From 4d5544505c2cf7e9031498accb4b5833508d5896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingy=20d=C3=B6t=20Net?= Date: Wed, 11 Jun 2025 20:16:52 -0400 Subject: [PATCH] Data update --- Lang/8080-Assembly/Loops-Infinite | 1 + Lang/8080-Assembly/Run-length-encoding | 1 + Lang/8086-Assembly/00-LANG.txt | 52 +- Lang/ALGOL-60/Additive-primes | 1 + Lang/ALGOL-60/Largest-proper-divisor-of-n | 1 + ...oops-Increment-loop-index-within-loop-body | 1 + Lang/ALGOL-60/Proper-divisors | 1 + .../Sequence-of-primes-by-trial-division | 1 + Lang/ALGOL-68/00-LANG.txt | 219 +-- Lang/ALGOL-68/Elliptic-curve-arithmetic | 1 + Lang/ALGOL-68/Permutation-test | 1 + ...---allocate-descendants-to-their-ancestors | 1 + Lang/ALGOL-68/Pythagoras-tree | 1 + Lang/ALGOL-68/Solve-a-Numbrix-puzzle | 1 + Lang/ALGOL-68/Solve-the-no-connection-puzzle | 1 + Lang/ALGOL-68/Text-processing-2 | 1 + .../Wasteful-equidigital-and-frugal-numbers | 1 + Lang/ALGOL-M/Additive-primes | 1 + Lang/ANSI-BASIC/Levenshtein-distance | 1 + Lang/ANSI-BASIC/M-bius-function | 1 + Lang/ANSI-BASIC/Magic-constant | 1 + Lang/ANSI-BASIC/Map-range | 1 + Lang/APL/Loops-Infinite | 1 + Lang/APL/Sort-a-list-of-object-identifiers | 1 + Lang/APL/Strip-comments-from-a-string | 1 + Lang/APL/Tic-tac-toe | 1 + Lang/ASIC/M-bius-function | 1 + Lang/Action-/00-LANG.txt | 2 +- Lang/Ada/Cistercian-numerals | 1 + Lang/Ada/Curzon-numbers | 1 + Lang/AppleScript/Bin-given-limits | 1 + Lang/AppleScript/Nth-root | 1 + .../Write-float-arrays-to-a-text-file | 1 + Lang/Applesoft-BASIC/Cistercian-numerals | 1 + Lang/Applesoft-BASIC/Formatted-numeric-output | 1 + Lang/Applesoft-BASIC/Levenshtein-distance | 1 + Lang/Applesoft-BASIC/Multi-dimensional-array | 1 + Lang/Applesoft-BASIC/Towers-of-Hanoi | 1 + Lang/Arturo/Arithmetic-derivative | 1 + Lang/Arturo/Dice-game-probabilities | 1 + Lang/Arturo/Element-wise-operations | 1 + Lang/Arturo/Entropy-Narcissist | 1 + Lang/Arturo/Munching-squares | 1 + Lang/Asymptote/Evaluate-binomial-coefficients | 1 + Lang/Atari-BASIC/Pi | 1 + Lang/AutoHotKey-V2/00-LANG.txt | 1 + Lang/AutoHotKey-V2/00-META.yaml | 2 + Lang/AutoHotKey-V2/Hello-world-Graphical | 1 + Lang/Autohotkey-V2/00-LANG.txt | 16 - Lang/Autohotkey-V2/00-META.yaml | 2 - Lang/Autohotkey-V2/Hello-world-Graphical | 1 - .../Partition-an-integer-x-into-n-primes | 1 + Lang/BASIC256/Evaluate-binomial-coefficients | 1 + Lang/BQN/Find-common-directory-path | 1 + .../Globally-replace-text-in-several-files | 1 + Lang/Ballerina/00-LANG.txt | 18 +- Lang/Ballerina/A+B | 1 + Lang/Ballerina/ABC-problem | 1 + Lang/Ballerina/AKS-test-for-primes | 1 + ...ficient-and-perfect-number-classifications | 1 + Lang/Ballerina/Abundant-odd-numbers | 1 + Lang/Ballerina/Accumulator-factory | 1 + Lang/Ballerina/Achilles-numbers | 1 + Lang/Ballerina/Ackermann-function | 1 + ...-a-variable-to-a-class-instance-at-runtime | 1 + Lang/Ballerina/Additive-primes | 1 + Lang/Ballerina/Address-of-a-variable | 1 + Lang/Ballerina/Almost-prime | 1 + Lang/Ballerina/Amb | 1 + .../Angle-difference-between-two-bearings | 1 + Lang/Ballerina/Anti-primes | 1 + Lang/Ballerina/Apply-a-callback-to-an-array | 1 + Lang/Ballerina/Approximate-equality | 1 + Lang/Ballerina/Arithmetic-Complex | 1 + Lang/Ballerina/Arithmetic-Integer | 1 + Lang/Ballerina/Arithmetic-Rational | 1 + Lang/Ballerina/Arithmetic-numbers | 1 + Lang/Ballerina/Array-concatenation | 1 + Lang/Ballerina/Array-length | 1 + Lang/Ballerina/Arrays | 1 + Lang/Ballerina/Ascending-primes | 1 + Lang/Ballerina/Associative-array-Creation | 1 + Lang/Ballerina/Associative-array-Iteration | 1 + Lang/Ballerina/Associative-array-Merging | 1 + Lang/Ballerina/Averages-Arithmetic-mean | 1 + Lang/Ballerina/Averages-Mean-angle | 1 + Lang/Ballerina/Averages-Mean-time-of-day | 1 + Lang/Ballerina/Averages-Median | 1 + Lang/Ballerina/Averages-Mode | 1 + Lang/Ballerina/Averages-Pythagorean-means | 1 + Lang/Ballerina/Averages-Root-mean-square | 1 + Lang/Ballerina/Averages-Simple-moving-average | 1 + Lang/Ballerina/Balanced-brackets | 1 + Lang/Ballerina/Boolean-values | 1 + Lang/Ballerina/Caesar-cipher | 1 + Lang/Ballerina/Calculating-the-value-of-e | 1 + .../Ballerina/Case-sensitivity-of-identifiers | 1 + Lang/Ballerina/Character-codes | 1 + Lang/Ballerina/Classes | 1 + Lang/Ballerina/Count-in-octal | 1 + Lang/Ballerina/Currency | 1 + Lang/Ballerina/Currying | 1 + Lang/Ballerina/Dynamic-variable-names | 1 + Lang/Ballerina/Empty-string | 1 + Lang/Ballerina/Extreme-floating-point-values | 1 + Lang/Ballerina/Farey-sequence | 1 + Lang/Ballerina/Find-limit-of-recursion | 1 + Lang/Ballerina/Fivenum | 1 + Lang/Ballerina/Floyds-triangle | 1 + Lang/Ballerina/Four-bit-adder | 1 + Lang/Ballerina/Function-definition | 1 + Lang/Ballerina/Gapful-numbers | 1 + Lang/Ballerina/Greatest-subsequential-sum | 1 + Lang/Ballerina/Hailstone-sequence | 1 + Lang/Ballerina/Hello-world-Newline-omission | 1 + Lang/Ballerina/Hello-world-Standard-error | 1 + Lang/Ballerina/Levenshtein-distance | 1 + .../Loop-over-multiple-arrays-simultaneously | 1 + Lang/Ballerina/Loops-Break | 1 + Lang/Ballerina/Loops-Continue | 1 + Lang/Ballerina/Loops-Do-while | 1 + Lang/Ballerina/Loops-Downward-for | 1 + Lang/Ballerina/Loops-For | 1 + .../Ballerina/Loops-For-with-a-specified-step | 1 + Lang/Ballerina/Loops-Foreach | 1 + ...oops-Increment-loop-index-within-loop-body | 1 + Lang/Ballerina/Loops-Infinite | 1 + Lang/Ballerina/Loops-N-plus-one-half | 1 + Lang/Ballerina/Loops-Nested | 1 + Lang/Ballerina/Loops-With-multiple-ranges | 1 + Lang/Ballerina/Loops-Wrong-ranges | 1 + Lang/Ballerina/Stack | 1 + Lang/Ballerina/Statistics-Basic | 1 + Lang/Ballerina/Towers-of-Hanoi | 1 + Lang/Ballerina/Truncatable-primes | 1 + Lang/Ballerina/Unicode-variable-names | 1 + Lang/C++/Currency | 1 + Lang/C++/Strassens-algorithm | 1 + Lang/C-sharp/ADFGVX-cipher | 1 + Lang/C-sharp/ASCII-art-diagram-converter | 1 + Lang/C-sharp/Arithmetic-derivative | 1 + Lang/C-sharp/Boyer-Moore-string-search | 1 + Lang/C-sharp/Calkin-Wilf-sequence | 1 + ...ithmetic-G-matrix-ng-continued-fraction-n- | 1 + ...Elliptic-Curve-Digital-Signature-Algorithm | 1 + Lang/C-sharp/Execute-a-Markov-algorithm | 1 + Lang/C-sharp/Extensible-prime-generator | 1 + .../File-extension-is-in-extensions-list | 1 + .../Find-if-a-point-is-within-a-triangle | 1 + Lang/C-sharp/Gotchas | 1 + .../Index-finite-lists-of-positive-integers | 1 + Lang/C-sharp/K-d-tree | 1 + Lang/C-sharp/Longest-string-challenge | 1 + Lang/C-sharp/P-Adic-numbers-basic | 1 + Lang/C-sharp/Reflection-Get-source | 1 + ...e:-smallest-number-with-exactly-n-divisors | 1 + Lang/C-sharp/Strassens-algorithm | 1 + Lang/C/Color-wheel | 1 + Lang/C/Magic-constant | 1 + Lang/C3/Binary-digits | 1 + .../Evaluate-binomial-coefficients | 1 + Lang/Crystal/Abbreviations-easy | 1 + Lang/Crystal/Anagrams-Deranged-anagrams | 1 + Lang/Crystal/Arithmetic-Complex | 1 + Lang/Crystal/Arithmetic-geometric-mean | 1 + Lang/Crystal/Averages-Mode | 1 + Lang/Crystal/Averages-Pythagorean-means | 1 + Lang/Crystal/Bin-given-limits | 1 + Lang/Crystal/Character-codes | 1 + Lang/Crystal/Cistercian-numerals | 1 + Lang/Crystal/Closures-Value-capture | 1 + Lang/Crystal/Comma-quibbling | 1 + .../Convert-seconds-to-compound-duration | 1 + ...ne-if-a-string-has-all-the-same-characters | 1 + .../Determine-if-a-string-is-collapsible | 1 + Lang/Crystal/Dijkstras-algorithm | 1 + Lang/Crystal/Dutch-national-flag-problem | 1 + Lang/Crystal/Execute-Brain- | 1 + Lang/Crystal/Hello-world-Standard-error | 1 + Lang/Crystal/Hex-words | 1 + Lang/Crystal/Increment-a-numerical-string | 1 + Lang/Crystal/Interactive-programming-repl- | 1 + Lang/Crystal/Loops-N-plus-one-half | 1 + Lang/Crystal/Magic-8-ball | 1 + Lang/Crystal/Non-decimal-radices-Convert | 1 + Lang/Crystal/Order-by-pair-comparisons | 1 + Lang/Crystal/Order-two-numerical-lists | 1 + Lang/Crystal/Phrase-reversals | 1 + Lang/Crystal/Power-set | 1 + Lang/Crystal/Run-length-encoding | 1 + .../Sort-an-array-of-composite-structures | 1 + Lang/Crystal/Sort-numbers-lexicographically | 1 + Lang/Crystal/Sort-three-variables | 1 + Lang/Crystal/Sorting-Algorithms-Circle-Sort | 1 + Lang/Crystal/Sorting-algorithms-Bubble-sort | 1 + ...racter-string-based-on-change-of-character | 1 + Lang/Crystal/Stack-traces | 1 + Lang/Crystal/String-prepend | 1 + Lang/Crystal/Take-notes-on-the-command-line | 1 + ...Find-Chess960-starting-position-identifier | 1 + Lang/Dart/24-game-Solve | 1 + Lang/Dart/K-d-tree | 1 + Lang/Dart/Penneys-game | 1 + .../Generate-Chess960-starting-position | 1 + Lang/ERRE/Leonardo-numbers | 1 + Lang/EasyLang/00-LANG.txt | 2 +- Lang/EasyLang/2048 | 1 + Lang/EasyLang/Abbreviations-automatic | 1 + Lang/EasyLang/Abbreviations-easy | 1 + Lang/EasyLang/Abbreviations-simple | 1 + Lang/EasyLang/Amb | 1 + Lang/EasyLang/Anagrams | 1 + Lang/EasyLang/Anagrams-Deranged-anagrams | 1 + Lang/EasyLang/Babylonian-spiral | 1 + Lang/EasyLang/Boyer-Moore-string-search | 1 + Lang/EasyLang/Element-wise-operations | 1 + Lang/EasyLang/Factorions | 1 + Lang/EasyLang/Mad-Libs | 1 + Lang/EasyLang/Permutation-test | 1 + ...rs-whose-neighboring-pairs-are-tetraprimes | 1 + ...---allocate-descendants-to-their-ancestors | 1 + Lang/EasyLang/Solve-a-Numbrix-puzzle | 1 + Lang/EasyLang/Solve-the-no-connection-puzzle | 1 + .../EasyLang/Sorting-algorithms-Patience-sort | 1 + Lang/EasyLang/Unprimeable-numbers | 1 + .../Wasteful-equidigital-and-frugal-numbers | 1 + Lang/Elena/00-LANG.txt | 2 +- Lang/Elena/Comma-quibbling | 1 + Lang/Elena/Concurrent-computing | 1 + Lang/Elena/HTTP | 1 + Lang/Elena/HTTPS | 1 + Lang/Emacs-Lisp/Color-wheel | 1 + .../Keyboard-input-Flush-the-keyboard-buffer | 1 + Lang/Emacs-Lisp/Keyboard-input-Keypress-check | 1 + .../Keyboard-input-Obtain-a-Y-or-N-response | 1 + ...racter-string-based-on-change-of-character | 1 + Lang/Emacs-Lisp/Strip-comments-from-a-string | 1 + Lang/Emacs-Lisp/Word-frequency | 1 + Lang/Erlang/Parse-an-IP-Address | 1 + Lang/Excel/Arrays | 1 + Lang/Excel/Conditional-structures | 1 + Lang/Excel/FizzBuzz | 1 + Lang/Excel/Function-definition | 1 + Lang/Excel/Loops-For | 1 + Lang/Excel/Repeat-a-string | 1 + Lang/Excel/Reverse-a-string | 1 + Lang/Excel/Tokenize-a-string | 1 + Lang/F-Sharp/Mad-Libs | 1 + Lang/Factor/Tic-tac-toe | 1 + Lang/Forth/Almost-prime | 1 + ...-digital-filter-direct-form-II-transposed- | 1 + Lang/Fortran/B-zier-curves-Intersections | 1 + Lang/Fortran/Eulers-constant-0.5772... | 1 + ...fect-square-in-base-n-with-n-unique-digits | 1 + Lang/Fortran/Harmonic-series | 1 + Lang/Fortran/Knuths-algorithm-S | 1 + Lang/Fortran/Thieles-interpolation-formula | 1 + Lang/Fortran/Vogels-approximation-method | 1 + Lang/Free-Pascal-Lazarus/DNS-query | 1 + Lang/Free-Pascal-Lazarus/Levenshtein-distance | 1 + Lang/Free-Pascal-Lazarus/Map-range | 1 + .../FreeBASIC/Bioinformatics-Global-alignment | 1 + Lang/FreeBASIC/Cistercian-numerals | 1 + Lang/FreeBASIC/Compiler-syntax-analyzer | 1 + Lang/FreeBASIC/Deconvolution-2D+ | 1 + ...stribution-of-0-digits-in-factorial-series | 1 + Lang/FreeBASIC/Elliptic-curve-arithmetic | 1 + Lang/FreeBASIC/Fermat-numbers | 1 + Lang/FreeBASIC/Graph-colouring | 1 + Lang/FreeBASIC/Juggler-sequence | 1 + Lang/FreeBASIC/Knuths-algorithm-S | 1 + Lang/FreeBASIC/Knuths-power-tree | 1 + Lang/FreeBASIC/Last-letter-first-letter | 1 + Lang/FreeBASIC/Natural-sorting | 1 + Lang/FreeBASIC/Rosetta-Code-Fix-code-tags | 1 + .../Rosetta-Code-Rank-languages-by-popularity | 1 + Lang/FreeBASIC/SQL-based-authentication | 1 + Lang/FreeBASIC/Simulate-input-Keyboard | 1 + Lang/FreeBASIC/Sorting-algorithms-Strand-sort | 1 + Lang/FreeBASIC/Text-processing-2 | 1 + .../Ukkonen-s-suffix-tree-construction | 1 + Lang/FreeBASIC/Word-ladder | 1 + Lang/GW-BASIC/Levenshtein-distance | 1 + Lang/GW-BASIC/Magic-constant | 1 + Lang/GW-BASIC/Map-range | 1 + Lang/Gambas/Evaluate-binomial-coefficients | 1 + Lang/Gambas/Magic-constant | 1 + Lang/Go/Boyer-Moore-string-search | 1 + Lang/Go/Goldbachs-comet | 1 + Lang/Go/P-Adic-square-roots | 1 + .../Pathological-floating-point-problems | 1 + ...oops-Increment-loop-index-within-loop-body | 1 + Lang/Java/Strassens-algorithm | 1 + Lang/JavaScript/15-puzzle-solver | 1 + Lang/JavaScript/ADFGVX-cipher | 1 + Lang/JavaScript/Average-loop-length | 1 + Lang/JavaScript/Bifid-cipher | 1 + Lang/JavaScript/Bitcoin-address-validation | 1 + Lang/JavaScript/Boyer-Moore-string-search | 1 + Lang/JavaScript/Burrows-Wheeler-transform | 1 + Lang/JavaScript/Camel-case-and-snake-case | 1 + Lang/JavaScript/Colorful-numbers | 1 + Lang/JavaScript/Commatizing-numbers | 1 + Lang/JavaScript/Compiler-code-generator | 1 + .../JavaScript/Create-a-file-on-magnetic-tape | 1 + Lang/JavaScript/Cyclotomic-polynomial | 1 + Lang/JavaScript/De-Bruijn-sequences | 1 + ...stribution-of-0-digits-in-factorial-series | 1 + ...Elliptic-Curve-Digital-Signature-Algorithm | 1 + Lang/JavaScript/Elliptic-curve-arithmetic | 1 + Lang/JavaScript/Gauss-Jordan-matrix-inversion | 1 + Lang/JavaScript/Graph-colouring | 1 + .../Greedy-algorithm-for-Egyptian-fractions | 1 + .../JavaScript/Isqrt-integer-square-root-of-X | 1 + Lang/JavaScript/Jacobi-symbol | 1 + Lang/JavaScript/K-d-tree | 1 + Lang/JavaScript/Knuths-algorithm-S | 1 + Lang/JavaScript/Knuths-power-tree | 1 + Lang/JavaScript/M-bius-function | 1 + Lang/JavaScript/MD5-Implementation | 1 + Lang/JavaScript/P-Adic-numbers-basic | 1 + Lang/JavaScript/P-Adic-square-roots | 1 + Lang/JavaScript/Perlin-noise | 1 + Lang/JavaScript/Playfair-cipher | 1 + Lang/JavaScript/SHA-1 | 1 + Lang/JavaScript/Set-puzzle | 1 + Lang/JavaScript/Solve-a-Hidato-puzzle | 1 + Lang/JavaScript/Solve-a-Numbrix-puzzle | 1 + Lang/JavaScript/Sorting-algorithms-Radix-sort | 1 + Lang/JavaScript/Spelling-of-ordinal-numbers | 1 + Lang/JavaScript/State-name-puzzle | 1 + Lang/JavaScript/Strassens-algorithm | 1 + Lang/JavaScript/Substitution-cipher | 1 + Lang/JavaScript/Tonelli-Shanks-algorithm | 1 + .../Ukkonen-s-suffix-tree-construction | 1 + Lang/JavaScript/Verhoeff-algorithm | 1 + Lang/JavaScript/Vigen-re-cipher-Cryptanalysis | 1 + Lang/JavaScript/Vogels-approximation-method | 1 + Lang/JavaScript/Wordiff | 1 + Lang/JavaScript/Zebra-puzzle | 1 + Lang/K/Compare-length-of-two-strings | 1 + Lang/K/Euler-method | 1 + Lang/K/M-bius-function | 1 + Lang/K/Substring | 1 + Lang/K/UTF-8-encode-and-decode | 1 + Lang/K/Write-float-arrays-to-a-text-file | 1 + Lang/Logo/Merge-and-aggregate-datasets | 1 + Lang/Lua/Check-input-device-is-a-terminal | 1 + Lang/Lua/Parse-an-IP-Address | 1 + .../Ramer-Douglas-Peucker-line-simplification | 1 + Lang/Lua/Update-a-configuration-file | 1 + Lang/M2000-Interpreter/00-LANG.txt | 60 +- Lang/M2000-Interpreter/ADFGVX-cipher | 1 + ...-digital-filter-direct-form-II-transposed- | 1 + .../Cartesian-product-of-two-or-more-lists | 1 + .../Compare-length-of-two-strings | 1 + .../File-extension-is-in-extensions-list | 1 + .../Greatest-subsequential-sum | 1 + Lang/M2000-Interpreter/Power-set | 1 + Lang/M2000-Interpreter/Simple-turtle-graphics | 1 + .../Sorting-algorithms-Strand-sort | 1 + .../Strip-a-set-of-characters-from-a-string | 1 + Lang/MACRO-11/Run-length-encoding | 1 + Lang/MAD/Look-and-say-sequence | 1 + Lang/MSX-Basic/Evaluate-binomial-coefficients | 1 + Lang/MUMPS/00-LANG.txt | 17 +- Lang/Maple/Pythagoras-tree | 1 + Lang/Mathematica/00-LANG.txt | 2 +- Lang/Mathematica/15-puzzle-solver | 1 + Lang/Mathematica/B-zier-curves-Intersections | 1 + Lang/Mathematica/Sisyphus-sequence | 1 + Lang/Mathematica/Sphenic-numbers | 1 + Lang/Mathematica/Wagstaff-primes | 1 + .../Evaluate-binomial-coefficients | 1 + Lang/Miranda/Loops-Infinite | 1 + Lang/Miranda/Run-length-encoding | 1 + Lang/Modula-2/M-bius-function | 1 + Lang/Modula-2/Magic-constant | 1 + Lang/Modula-2/Map-range | 1 + .../Ramer-Douglas-Peucker-line-simplification | 1 + Lang/Nascom-BASIC/Levenshtein-distance | 1 + Lang/Nu/CSV-data-manipulation | 1 + Lang/Nu/Department-numbers | 1 + ...ne-if-a-string-has-all-the-same-characters | 1 + Lang/Nu/File-extension-is-in-extensions-list | 1 + Lang/Nu/File-size-distribution | 1 + Lang/Nu/I-before-E-except-after-C | 1 + Lang/Nu/Word-frequency | 1 + Lang/OCaml/Anti-primes | 1 + Lang/OCaml/Attractive-numbers | 1 + Lang/OCaml/Cuban-primes | 1 + Lang/OOC/00-LANG.txt | 2 +- Lang/OPL/00-LANG.txt | 10 +- Lang/OPL/100-doors | 1 + Lang/OPL/Arithmetic-Integer | 1 + Lang/OPL/Arrays | 1 + Lang/OPL/Character-codes | 1 + Lang/OPL/Comments | 1 + Lang/OPL/Compare-length-of-two-strings | 1 + Lang/OPL/Copy-a-string | 1 + Lang/OPL/Draw-a-clock | 1 + Lang/OPL/Draw-a-pixel | 1 + Lang/OPL/Hello-world-Text | 1 + Lang/OPL/Program-termination | 1 + Lang/OPL/String-prepend | 1 + Lang/OPL/User-input-Text | 1 + Lang/Objeck/Copy-stdin-to-stdout | 1 + Lang/Objeck/Distributed-programming | 1 + Lang/Objeck/Floyds-triangle | 1 + .../Objeck/Generate-lower-case-ASCII-alphabet | 1 + Lang/Objeck/Hello-world-Standard-error | 1 + Lang/Objeck/Knuth-shuffle | 1 + Lang/Objeck/Mad-Libs | 1 + Lang/Objeck/Multiplication-tables | 1 + Lang/Objeck/Roman-numerals-Decode | 1 + .../Rosetta-Code-Find-unimplemented-tasks | 1 + .../Strip-a-set-of-characters-from-a-string | 1 + Lang/Odin/Euler-method | 1 + Lang/Odin/Execute-Brain- | 1 + Lang/Odin/Fractran | 1 + Lang/Odin/Hailstone-sequence | 1 + Lang/Odin/Hello-world-Graphical | 1 + Lang/Odin/Primality-by-trial-division | 1 + Lang/Odin/Runge-Kutta-method | 1 + .../Strip-a-set-of-characters-from-a-string | 1 + Lang/Odin/Unicode-variable-names | 1 + Lang/Odin/Write-entire-file | 1 + Lang/Ol/Runge-Kutta-method | 1 + .../Evaluate-binomial-coefficients | 1 + Lang/PARI-GP/Attractive-numbers | 1 + Lang/PARI-GP/Disarium-numbers | 1 + ...rs-whose-neighboring-pairs-are-tetraprimes | 1 + Lang/PHP/M-bius-function | 1 + Lang/PHP/Magic-constant | 1 + Lang/PHP/Map-range | 1 + Lang/PL-I-80/Additive-primes | 1 + Lang/Pascal/Date-manipulation | 1 + Lang/Pascal/FizzBuzz | 1 - Lang/Pascal/Levenshtein-distance | 1 - Lang/Pascal/Map-range | 1 - Lang/PascalABC.NET/Additive-primes | 1 + Lang/PascalABC.NET/Amicable-pairs | 1 + Lang/PascalABC.NET/Pancake-numbers | 1 + Lang/PascalABC.NET/Pangram-checker | 1 + Lang/PascalABC.NET/Paraffins | 1 + Lang/PascalABC.NET/Parallel-calculations | 1 + .../Parsing-RPN-calculator-algorithm | 1 + .../Partition-an-integer-x-into-n-primes | 1 + Lang/PascalABC.NET/Pascal-matrix-generation | 1 + Lang/PascalABC.NET/Pascals-triangle-Puzzle | 1 + .../Pathological-floating-point-problems | 1 + Lang/PascalABC.NET/Pells-equation | 1 + Lang/PascalABC.NET/Perfect-shuffle | 1 + Lang/PascalABC.NET/Perfect-totient-numbers | 1 + Lang/PascalABC.NET/Permutation-test | 1 + Lang/Perl/Execute-Computer-Zero | 1 + Lang/Prolog/Evaluate-binomial-coefficients | 1 + .../Im-a-software-engineer-get-me-out-of-here | 1 + ...rs-whose-neighboring-pairs-are-tetraprimes | 1 + Lang/Python/Square-form-factorization | 1 + .../Wasteful-equidigital-and-frugal-numbers | 1 + Lang/Q/Euler-method | 1 + Lang/QBasic/Evaluate-binomial-coefficients | 1 + Lang/QBasic/Map-range | 1 + Lang/Quackery/00-LANG.txt | 24 +- Lang/Quackery/Dice-game-probabilities | 1 + ...-of-elements-below-main-diagonal-of-matrix | 1 + Lang/Quackery/Two-bullet-roulette | 1 + Lang/R/Camel-case-and-snake-case | 1 + Lang/R/Determine-sentence-type | 1 + Lang/R/Disarium-numbers | 1 + Lang/R/Display-a-linear-combination | 1 + Lang/R/Draw-a-cuboid | 1 + Lang/R/Dutch-national-flag-problem | 1 + Lang/R/Factorions | 1 + ...c-numbers-in-both-binary-and-ternary-bases | 1 + Lang/R/Halt-and-catch-fire | 1 + Lang/R/Hex-words | 1 + Lang/R/Kernighans-large-earthquake-problem | 1 + Lang/R/Munchausen-numbers | 1 + Lang/R/Old-Russian-measure-of-length | 1 + Lang/R/Semordnilap | 1 + Lang/R/Sort-numbers-lexicographically | 1 + .../R/Strip-a-set-of-characters-from-a-string | 1 + Lang/REXX/00-LANG.txt | 18 +- Lang/REXX/Magic-constant | 1 + ...---allocate-descendants-to-their-ancestors | 1 + Lang/REXX/Ramanujan-primes-twins | 1 + Lang/REXX/Sequence-of-primorial-primes | 1 + Lang/REXX/Sieve-of-Pritchard | 1 + Lang/Raku/Simple-turtle-graphics | 1 + Lang/RapidQ/Levenshtein-distance | 1 + Lang/RapidQ/M-bius-function | 1 + Lang/RapidQ/Map-range | 1 + Lang/Refal/Loops-Infinite | 1 + Lang/Refal/Power-set | 1 + Lang/Refal/Run-length-encoding | 1 + Lang/Refal/Strip-comments-from-a-string | 1 + Lang/Rust/Ascending-primes | 1 + Lang/Rust/B-zier-curves-Intersections | 1 + Lang/Rust/Bifid-cipher | 1 + Lang/Rust/Bioinformatics-Global-alignment | 1 + Lang/Rust/Blum-integer | 1 + Lang/Rust/Boyer-Moore-string-search | 1 + Lang/Rust/Calendar---for-REAL-programmers | 1 + .../Compare-sorting-algorithms-performance | 1 + Lang/Rust/Compiler-AST-interpreter | 1 + Lang/Rust/Compiler-code-generator | 1 + Lang/Rust/Compiler-lexical-analyzer | 1 + Lang/Rust/Compiler-syntax-analyzer | 1 + Lang/Rust/Cyclotomic-polynomial | 1 + Lang/Rust/Descending-primes | 1 + Lang/Rust/Doubly-linked-list-Definition | 1 + Lang/Rust/Doubly-linked-list-Traversal | 1 + ...Elliptic-Curve-Digital-Signature-Algorithm | 1 + Lang/Rust/Faulhabers-formula | 1 + Lang/Rust/Graph-colouring | 1 + Lang/Rust/Hex-words | 1 + Lang/Rust/Kosaraju | 1 + Lang/Rust/Latin-Squares-in-reduced-form | 1 + Lang/Rust/Median-filter | 1 + Lang/Rust/Natural-sorting | 1 + Lang/Rust/Nonogram-solver | 1 + Lang/Rust/OpenWebNet-password | 1 + Lang/Rust/P-Adic-numbers-basic | 1 + Lang/Rust/P-Adic-square-roots | 1 + Lang/Rust/Playfair-cipher | 1 + Lang/Rust/Polynomial-regression | 1 + ...bers-Combined-recursive-generator-MRG32k3a | 1 + ...Pseudo-random-numbers-Middle-square-method | 1 + Lang/Rust/Pseudo-random-numbers-Splitmix64 | 1 + Lang/Rust/QR-decomposition | 1 + Lang/Rust/Rendezvous | 1 + Lang/Rust/Resistor-mesh | 1 + Lang/Rust/Shoelace-formula-for-polygonal-area | 1 + Lang/Rust/Solve-a-Holy-Knights-tour | 1 + Lang/Rust/Solve-a-Hopido-puzzle | 1 + Lang/Rust/Solve-a-Numbrix-puzzle | 1 + Lang/Rust/Sorting-algorithms-Bead-sort | 1 + Lang/Rust/Sorting-algorithms-Patience-sort | 1 + Lang/Rust/Sorting-algorithms-Strand-sort | 1 + Lang/Rust/Steffensens-method | 1 + Lang/Rust/Strassens-algorithm | 1 + Lang/Rust/Stream-merge | 1 + Lang/Rust/Sudan-function | 1 + Lang/Rust/Tonelli-Shanks-algorithm | 1 + Lang/Rust/Ukkonen-s-suffix-tree-construction | 1 + Lang/Rust/Verhoeff-algorithm | 1 + Lang/Rust/Xiaolin-Wus-line-algorithm | 1 + Lang/S-BASIC/Additive-primes | 1 + Lang/S-BASIC/Character-codes | 1 + ...oops-Increment-loop-index-within-loop-body | 1 + Lang/S-BASIC/Sum-of-a-series | 1 + Lang/SETL/Gray-code | 1 + Lang/SETL/Loops-Do-while | 1 + ...oops-Increment-loop-index-within-loop-body | 1 + Lang/SETL/Loops-Infinite | 1 + Lang/SETL/Radical-of-an-integer | 1 + Lang/SETL/Strip-comments-from-a-string | 1 + Lang/SQL/Factorial | 1 + Lang/Scala/Boyer-Moore-string-search | 1 + Lang/Scheme/Circular-primes | 1 + Lang/Scheme/Compare-length-of-two-strings | 1 + Lang/Scheme/Runge-Kutta-method | 1 + Lang/Scheme/Unicode-variable-names | 1 + Lang/Standard-ML/Box-the-compass | 1 + Lang/Tcl/Unicode-strings | 1 + Lang/Tiny-BASIC/Magic-constant | 1 + .../True-BASIC/Evaluate-binomial-coefficients | 1 + Lang/TypeScript/Additive-primes | 1 + Lang/TypeScript/Arithmetic-numbers | 1 + Lang/TypeScript/Map-range | 1 + Lang/TypeScript/Sum-of-a-series | 1 + Lang/UNIX-Shell/Color-of-a-screen-pixel | 1 + Lang/UNIX-Shell/Color-quantization | 1 + .../Create-a-two-dimensional-array-at-runtime | 1 + Lang/Uiua/Damm-algorithm | 1 + Lang/Uiua/Ethiopian-multiplication | 1 + Lang/Uiua/Matrix-transposition | 1 + Lang/Uiua/Munching-squares | 1 + Lang/Uiua/Pangram-checker | 1 + Lang/Uiua/Spiral-matrix | 1 + Lang/Uiua/Zig-zag-matrix | 1 + Lang/Uxntal/00-LANG.txt | 17 +- Lang/Uxntal/Array-length | 1 + Lang/Uxntal/Bioinformatics-base-count | 1 + Lang/Uxntal/Comments | 1 + Lang/Uxntal/Conditional-structures | 1 + Lang/Uxntal/Copy-a-string | 1 + Lang/Uxntal/Draw-a-pixel | 1 - Lang/Uxntal/Fibonacci-sequence | 1 + Lang/Uxntal/Flow-control-structures | 1 + Lang/Uxntal/Hello-world-Graphical | 1 + Lang/Uxntal/Hello-world-Standard-error | 1 + Lang/Uxntal/Hello-world-Text | 1 - Lang/Uxntal/Integer-sequence | 1 + Lang/Uxntal/Loops-Break | 1 + Lang/Uxntal/Loops-Continue | 1 + Lang/Uxntal/Loops-Do-while | 1 + Lang/Uxntal/Loops-For-with-a-specified-step | 1 + Lang/Uxntal/Loops-Foreach | 1 + Lang/Uxntal/Loops-N-plus-one-half | 1 + Lang/Uxntal/Loops-While | 1 + Lang/Uxntal/Stack-traces | 1 + Lang/Uxntal/String-length | 1 + Lang/V-(Vlang)/Quine | 1 + Lang/Wisp/Knuth-shuffle | 1 + .../Terminal-control-Clear-the-screen | 1 + Lang/XBasic/Levenshtein-distance | 1 + Lang/XPL0/Bin-given-limits | 1 + Lang/XPL0/Create-an-object-at-a-given-address | 1 + Lang/XPL0/Floyd-Warshall-algorithm | 1 + Lang/XPL0/Largest-int-from-concatenated-ints | 1 + Lang/XPL0/Last-letter-first-letter | 1 + Lang/XPL0/Levenshtein-distance | 1 + Lang/XPL0/Polynomial-regression | 1 + Lang/XPL0/Read-a-configuration-file | 1 + Lang/XPL0/Sort-three-variables | 1 + Lang/XPL0/Text-processing-1 | 1 + Lang/XPL0/Text-processing-2 | 1 + Lang/Yabasic/Evaluate-binomial-coefficients | 1 + Lang/ZED/00-LANG.txt | 3 + Lang/Zig/15-puzzle-solver | 1 + Lang/Zig/2048 | 1 + Lang/Zig/24-game | 1 + Lang/Zig/Anti-primes | 1 + Lang/Zig/Canonicalize-CIDR | 1 + Lang/Zig/Convex-hull | 1 + Lang/Zig/De-Bruijn-sequences | 1 + Lang/Zig/Dijkstras-algorithm | 1 + Lang/Zig/Execute-a-Markov-algorithm | 1 + Lang/Zig/Fibonacci-sequence | 1 + Lang/Zig/Find-the-missing-permutation | 1 + Lang/Zig/Floyd-Warshall-algorithm | 1 + Lang/Zig/Latin-Squares-in-reduced-form | 1 + Lang/Zig/Move-to-front-algorithm | 1 + Lang/Zig/Natural-sorting | 1 + Lang/Zig/P-Adic-numbers-basic | 1 + Lang/Zig/P-Adic-square-roots | 1 + Lang/Zig/Parsing-RPN-calculator-algorithm | 1 + Lang/Zig/Parsing-Shunting-yard-algorithm | 1 + Lang/Zig/Quickselect-algorithm | 1 + Lang/Zig/Quine | 1 + Lang/Zig/SHA-1 | 1 + Lang/Zig/Solve-a-Holy-Knights-tour | 1 + Lang/Zig/Sorting-algorithms-Patience-sort | 1 + Lang/Zig/Sorting-algorithms-Strand-sort | 1 + Lang/Zig/Strassens-algorithm | 1 + Lang/Zig/Sutherland-Hodgman-polygon-clipping | 1 + Lang/Zig/Thue-Morse | 1 + Lang/Zig/Tonelli-Shanks-algorithm | 1 + Lang/Zig/Y-combinator | 1 + Task/100-doors/BQN/100-doors-4.bqn | 3 + Task/100-doors/BQN/100-doors-5.bqn | 3 + Task/100-doors/EasyLang/100-doors.easy | 4 +- Task/100-doors/Elena/100-doors.elena | 4 +- Task/100-doors/Excel/100-doors-4.excel | 1 + Task/100-doors/OPL/100-doors.opl | 32 + Task/100-doors/Quackery/100-doors-1.quackery | 17 + Task/100-doors/Quackery/100-doors-2.quackery | 1 + Task/100-doors/Quackery/100-doors.quackery | 22 - Task/100-doors/Tcl/100-doors-1.tcl | 90 +- Task/100-doors/Tcl/100-doors-2.tcl | 11 +- Task/100-doors/Tcl/100-doors-3.tcl | 48 +- Task/100-doors/Tcl/100-doors-4.tcl | 46 + .../100-prisoners/EasyLang/100-prisoners.easy | 55 +- .../EasyLang/15-puzzle-game.easy | 75 +- .../C-sharp/15-puzzle-solver.cs | 1527 +---------------- .../JavaScript/15-puzzle-solver.js | 97 ++ .../Mathematica/15-puzzle-solver.math | 178 ++ .../15-puzzle-solver/Zig/15-puzzle-solver.zig | 187 ++ Task/2048/BQN/2048.bqn | 2 +- Task/2048/EasyLang/2048.easy | 161 ++ Task/2048/Zig/2048.zig | 228 +++ Task/24-game-Solve/Dart/24-game-solve.dart | 226 +++ Task/24-game/Elena/24-game.elena | 41 +- Task/24-game/Perl/24-game.pl | 17 +- Task/24-game/Rust/24-game.rs | 8 +- Task/24-game/Zig/24-game.zig | 153 ++ .../EasyLang/4-rings-or-4-squares-puzzle.easy | 6 +- .../Elena/99-bottles-of-beer.elena | 2 +- .../Factor/99-bottles-of-beer-1.factor | 6 + ...eer.factor => 99-bottles-of-beer-2.factor} | 0 .../Uxntal/99-bottles-of-beer.uxnatl | 108 +- Task/A+B/Ballerina/a+b.ballerina | 16 + Task/A+B/Elena/a+b-1.elena | 6 +- Task/A+B/Elena/a+b-2.elena | 2 +- Task/A+B/REXX/a+b-1.rexx | 4 - Task/A+B/REXX/a+b-2.rexx | 4 - Task/A+B/REXX/a+b-3.rexx | 6 - Task/A+B/REXX/a+b-4.rexx | 11 - Task/A+B/REXX/a+b-5.rexx | 8 - Task/A+B/REXX/a+b.rexx | 27 + .../Ballerina/abc-problem.ballerina | 32 + Task/ABC-problem/EasyLang/abc-problem.easy | 2 +- Task/ABC-problem/Elena/abc-problem.elena | 2 +- Task/ADFGVX-cipher/C-sharp/adfgvx-cipher.cs | 117 ++ .../ADFGVX-cipher/JavaScript/adfgvx-cipher.js | 134 ++ .../M2000-Interpreter/adfgvx-cipher.m2000 | 116 ++ .../Ballerina/aks-test-for-primes.ballerina | 58 + .../Elena/aks-test-for-primes.elena | 12 +- .../REXX/aks-test-for-primes-2.rexx | 134 +- .../REXX/aks-test-for-primes-3.rexx | 89 - .../C-sharp/ascii-art-diagram-converter-1.cs | 190 ++ .../C-sharp/ascii-art-diagram-converter-2.cs | 15 + .../EasyLang/abbreviations-automatic.easy | 30 + .../Crystal/abbreviations-easy.cr | 17 + .../EasyLang/abbreviations-easy.easy | 42 + .../EasyLang/abbreviations-simple.easy | 42 + .../abelian-sandpile-model-identity.easy | 28 +- .../EasyLang/abelian-sandpile-model.easy | 9 +- ...perfect-number-classifications-1.ballerina | 46 + ...perfect-number-classifications-2.ballerina | 36 + ...t-and-perfect-number-classifications.elena | 2 +- ...-and-perfect-number-classifications-1.rexx | 72 +- ...-and-perfect-number-classifications-2.rexx | 53 +- ...-and-perfect-number-classifications-3.rexx | 51 - ...-and-perfect-number-classifications-4.rexx | 27 - Task/Abundant-odd-numbers/00-TASK.txt | 10 +- .../Ballerina/abundant-odd-numbers.ballerina | 73 + .../EasyLang/abundant-odd-numbers.easy | 2 +- .../Ballerina/accumulator-factory.ballerina | 38 + .../Elena/accumulator-factory.elena | 2 +- .../Ballerina/achilles-numbers.ballerina | 92 + .../EasyLang/achilles-numbers.easy | 36 +- .../Ballerina/ackermann-function.ballerina | 14 + .../Elena/ackermann-function.elena | 14 +- ...e-to-a-class-instance-at-runtime.ballerina | 23 + ...iable-to-a-class-instance-at-runtime.elena | 4 +- .../ALGOL-60/additive-primes.alg | 60 + .../ALGOL-M/additive-primes.alg | 64 + .../Ballerina/additive-primes.ballerina | 67 + .../EasyLang/additive-primes.easy | 13 +- .../PL-I-80/additive-primes.pli | 52 + .../PascalABC.NET/additive-primes.pas | 4 + .../REXX/additive-primes-2.rexx | 55 +- .../Additive-primes/Raku/additive-primes.raku | 2 +- .../S-BASIC/additive-primes.basic | 55 + .../TypeScript/additive-primes.ts | 29 + .../Ballerina/address-of-a-variable.ballerina | 8 + .../Align-columns/EasyLang/align-columns.easy | 4 +- Task/Align-columns/Emacs-Lisp/align-columns.l | 341 ++-- .../aliquot-sequence-classifications.easy | 52 +- .../00-TASK.txt | 12 +- Task/Almost-prime/00-TASK.txt | 2 +- .../Ballerina/almost-prime.ballerina | 32 + Task/Almost-prime/Clojure/almost-prime.clj | 2 - Task/Almost-prime/EasyLang/almost-prime.easy | 14 +- Task/Almost-prime/Forth/almost-prime.fth | 38 + Task/Almost-prime/REXX/almost-prime-1.rexx | 35 - Task/Almost-prime/REXX/almost-prime-2.rexx | 66 - ...{almost-prime-3.rexx => almost-prime.rexx} | 4 +- Task/Amb/Ballerina/amb.ballerina | 35 + Task/Amb/EasyLang/amb.easy | 31 + Task/Amb/Elena/amb.elena | 6 +- Task/Amb/Langur/amb.langur | 2 +- .../EasyLang/amicable-pairs.easy | 10 +- .../Elena/amicable-pairs-1.elena | 2 +- .../Elena/amicable-pairs-2.elena | 2 +- .../Elena/amicable-pairs-3.elena | 14 +- .../PascalABC.NET/amicable-pairs.pas | 9 + .../Amicable-pairs/REXX/amicable-pairs-2.rexx | 52 +- .../Amicable-pairs/REXX/amicable-pairs-3.rexx | 30 - .../Amicable-pairs/REXX/amicable-pairs-4.rexx | 34 - .../Amicable-pairs/REXX/amicable-pairs-5.rexx | 34 - .../Amicable-pairs/REXX/amicable-pairs-6.rexx | 43 - .../Crystal/anagrams-deranged-anagrams.cr | 19 + .../EasyLang/anagrams-deranged-anagrams.easy | 74 + Task/Anagrams/EasyLang/anagrams.easy | 46 + Task/Anagrams/Elena/anagrams.elena | 10 +- ...-difference-between-two-bearings.ballerina | 34 + ...angle-difference-between-two-bearings.easy | 2 +- ...eometric-normalization-and-conversion.easy | 2 +- .../EasyLang/animate-a-pendulum.easy | 17 +- Task/Animation/EasyLang/animation.easy | 12 +- .../Elena/anonymous-recursion.elena | 8 +- .../Ballerina/anti-primes.ballerina | 42 + Task/Anti-primes/EasyLang/anti-primes.easy | 6 +- Task/Anti-primes/OCaml/anti-primes.ml | 18 + Task/Anti-primes/REXX/anti-primes-1.rexx | 70 +- Task/Anti-primes/REXX/anti-primes-2.rexx | 69 +- Task/Anti-primes/REXX/anti-primes-3.rexx | 44 - Task/Anti-primes/Zig/anti-primes.zig | 160 ++ .../apply-a-callback-to-an-array.ballerina | 9 + ...igital-filter-direct-form-ii-transposed-.f | 42 + ...al-filter-direct-form-ii-transposed-.m2000 | 49 + .../Ballerina/approximate-equality.ballerina | 22 + .../EasyLang/approximate-equality.easy | 4 +- .../EasyLang/archimedean-spiral.easy | 12 +- .../ALGOL-68/arithmetic-complex.alg | 26 +- .../Ballerina/arithmetic-complex.ballerina | 67 + .../Crystal/arithmetic-complex.cr | 15 + ...mplex.m2000 => arithmetic-complex-1.m2000} | 0 .../arithmetic-complex-2.m2000 | 35 + .../REXX/arithmetic-complex.rexx | 79 +- .../Ballerina/arithmetic-integer.ballerina | 24 + .../OPL/arithmetic-integer.opl | 14 + .../Wren/arithmetic-integer.wren | 14 +- .../Ballerina/arithmetic-rational.ballerina | 156 ++ .../REXX/arithmetic-rational.rexx | 4 +- Task/Arithmetic-derivative/00-TASK.txt | 18 +- .../Arturo/arithmetic-derivative.arturo | 20 + .../C-sharp/arithmetic-derivative.cs | 30 + .../EasyLang/arithmetic-derivative.easy | 12 +- .../EasyLang/arithmetic-evaluation.easy | 8 +- ...rithmetic-geometric-mean-calculate-pi.easy | 2 +- .../C++/arithmetic-geometric-mean.cpp | 42 +- .../Crystal/arithmetic-geometric-mean.cr | 8 + .../EasyLang/arithmetic-geometric-mean.easy | 2 +- .../Ballerina/arithmetic-numbers.ballerina | 98 ++ .../EasyLang/arithmetic-numbers.easy | 42 +- .../REXX/arithmetic-numbers.rexx | 20 +- .../TypeScript/arithmetic-numbers.ts | 32 + .../Ballerina/array-concatenation.ballerina | 7 + .../EasyLang/array-concatenation.easy | 4 +- .../REXX/array-concatenation-1.rexx | 3 - .../REXX/array-concatenation-2.rexx | 9 - .../REXX/array-concatenation-3.rexx | 22 - .../REXX/array-concatenation.rexx | 21 + .../Ballerina/array-length.ballerina | 6 + Task/Array-length/Uxntal/array-length.uxnatl | 18 + Task/Arrays/Ballerina/arrays.ballerina | 15 + Task/Arrays/EasyLang/arrays.easy | 10 +- Task/Arrays/Excel/arrays-1.excel | 15 + Task/Arrays/Excel/arrays-2.excel | 1 + Task/Arrays/Excel/arrays-3.excel | 16 + Task/Arrays/OPL/arrays.opl | 9 + Task/Arrays/REXX/arrays-1.rexx | 9 - Task/Arrays/REXX/arrays-2.rexx | 11 - Task/Arrays/REXX/arrays-3.rexx | 11 - Task/Arrays/REXX/arrays-4.rexx | 10 - Task/Arrays/REXX/arrays-5.rexx | 17 - Task/Arrays/REXX/arrays-6.rexx | 27 - Task/Arrays/REXX/arrays.rexx | 67 + Task/Arrays/Tcl/arrays-1.tcl | 13 +- Task/Arrays/Tcl/arrays-2.tcl | 9 +- Task/Arrays/Tcl/arrays-3.tcl | 2 + Task/Arrays/Tcl/arrays-4.tcl | 2 + Task/Arrays/Tcl/arrays-5.tcl | 4 + Task/Arrays/Tcl/arrays-6.tcl | 10 + .../Ballerina/ascending-primes.ballerina | 38 + .../EasyLang/ascending-primes.easy | 26 +- .../Rust/ascending-primes-1.rs | 36 + .../Rust/ascending-primes-2.rs | 30 + .../Rust/ascending-primes-3.rs | 43 + .../associative-array-creation.ballerina | 22 + .../EasyLang/associative-array-creation.easy | 27 +- .../associative-array-iteration.ballerina | 22 + .../associative-array-merging.ballerina | 15 + .../associative-array-merging-3.lisp | 28 + .../EasyLang/associative-array-merging.easy | 6 +- .../JavaScript/associative-array-merging.js | 35 +- .../EasyLang/attractive-numbers.easy | 12 +- .../OCaml/attractive-numbers.ml | 26 + .../PARI-GP/attractive-numbers-1.parigp | 1 + .../PARI-GP/attractive-numbers-2.parigp | 1 + .../EasyLang/average-loop-length.easy | 8 +- .../JavaScript/average-loop-length.js | 49 + .../averages-arithmetic-mean.ballerina | 22 + .../EasyLang/averages-arithmetic-mean.easy | 11 +- .../Ballerina/averages-mean-angle.ballerina | 27 + .../averages-mean-time-of-day.ballerina | 42 + .../Ballerina/averages-median.ballerina | 20 + .../EasyLang/averages-median.easy | 22 +- .../Ballerina/averages-mode.ballerina | 27 + Task/Averages-Mode/Crystal/averages-mode.cr | 6 + .../Averages-Mode/EasyLang/averages-mode.easy | 6 +- .../averages-pythagorean-means.ballerina | 21 + .../Crystal/averages-pythagorean-means.cr | 24 + .../EasyLang/averages-pythagorean-means.easy | 2 +- .../averages-root-mean-square.ballerina | 8 + .../averages-simple-moving-average.ballerina | 33 + .../averages-simple-moving-average.easy | 2 +- .../Fortran/b-zier-curves-intersections.f | 286 +++ .../b-zier-curves-intersections.math | 7 + .../Rust/b-zier-curves-intersections.rs | 198 +++ .../EasyLang/babylonian-spiral.easy | 70 + .../Ballerina/balanced-brackets.ballerina | 34 + .../Excel/balanced-brackets-3.excel | 1 + .../Excel/balanced-brackets-4.excel | 1 + Task/Balanced-ternary/00-TASK.txt | 4 +- .../Barnsley-fern/EasyLang/barnsley-fern.easy | 37 +- .../{bell-numbers.cs => bell-numbers-1.cs} | 0 Task/Bell-numbers/C-sharp/bell-numbers-2.cs | 25 + Task/Benfords-law/EasyLang/benfords-law.easy | 10 +- Task/Best-shuffle/EasyLang/best-shuffle.easy | 2 +- Task/Bifid-cipher/EasyLang/bifid-cipher.easy | 2 +- Task/Bifid-cipher/JavaScript/bifid-cipher.js | 199 +++ Task/Bifid-cipher/Rust/bifid-cipher.rs | 125 ++ .../AppleScript/bin-given-limits.applescript | 42 + .../Crystal/bin-given-limits.cr | 43 + .../EasyLang/bin-given-limits.easy | 7 +- .../XPL0/bin-given-limits.xpl0 | 60 + Task/Binary-digits/C3/binary-digits.c3 | 8 + .../Binary-digits/EasyLang/binary-digits.easy | 8 +- .../Binary-search/EasyLang/binary-search.easy | 11 +- .../bioinformatics-global-alignment.basic | 170 ++ .../Rust/bioinformatics-global-alignment.rs | 132 ++ .../bioinformatics-sequence-mutation.easy | 28 +- .../EasyLang/bioinformatics-base-count.easy | 14 +- .../Uxntal/bioinformatics-base-count.uxnatl | 80 + Task/Biorhythms/EasyLang/biorhythms.easy | 36 +- .../JavaScript/bitcoin-address-validation.js | 53 + .../bitmap-b-zier-curves-quadratic.easy | 19 +- .../bitmap-bresenhams-line-algorithm.easy | 7 +- .../Uxntal/bitwise-operations.uxnatl | 120 +- Task/Blum-integer/EasyLang/blum-integer.easy | 27 +- Task/Blum-integer/Rust/blum-integer.rs | 91 + .../Ballerina/boolean-values.ballerina | 12 + .../EasyLang/box-the-compass.easy | 2 +- .../Standard-ML/box-the-compass.ml | 29 + .../C-sharp/boyer-moore-string-search.cs | 280 +++ .../EasyLang/boyer-moore-string-search.easy | 67 + .../Go/boyer-moore-string-search.go | 65 + .../JavaScript/boyer-moore-string-search.js | 52 + .../Rust/boyer-moore-string-search.rs | 62 + .../Scala/boyer-moore-string-search.scala | 329 ++++ .../Wren/boyer-moore-string-search.wren | 15 +- .../EasyLang/brace-expansion.easy | 6 +- .../EasyLang/brazilian-numbers.easy | 23 +- .../EasyLang/brilliant-numbers.easy | 22 +- .../Brownian-tree/EasyLang/brownian-tree.easy | 10 +- Task/Bulls-and-cows/APL/bulls-and-cows-1.apl | 2 +- Task/Bulls-and-cows/J/bulls-and-cows-1.j | 8 +- Task/Bulls-and-cows/J/bulls-and-cows-2.j | 4 +- .../EasyLang/burrows-wheeler-transform.easy | 10 +- .../JavaScript/burrows-wheeler-transform.js | 76 + .../csv-data-manipulation.m2000 | 17 +- .../Nu/csv-data-manipulation-1.nu | 5 + .../Nu/csv-data-manipulation-2.nu | 1 + .../Ballerina/caesar-cipher.ballerina | 32 + .../calculating-the-value-of-e.ballerina | 17 + .../EasyLang/calculating-the-value-of-e.easy | 2 +- .../Rust/calendar---for-real-programmers.rs | 216 +++ Task/Calendar/00-TASK.txt | 2 + Task/Calendar/EasyLang/calendar.easy | 28 +- .../C-sharp/calkin-wilf-sequence.cs | 48 + .../EasyLang/calkin-wilf-sequence.easy | 5 +- .../EasyLang/call-a-function.easy | 2 +- .../JavaScript/camel-case-and-snake-case.js | 82 + .../R/camel-case-and-snake-case.r | 56 + .../ALGOL-68/canonicalize-cidr.alg | 32 +- .../Zig/canonicalize-cidr.zig | 70 + Task/Cantor-set/EasyLang/cantor-set.easy | 7 +- .../carmichael-3-strong-pseudoprimes.easy | 6 +- .../carmichael-3-strong-pseudoprimes-1.rexx | 42 - .../carmichael-3-strong-pseudoprimes-2.rexx | 59 - .../carmichael-3-strong-pseudoprimes.rexx | 26 + ...rtesian-product-of-two-or-more-lists-1.cpp | 66 + ...rtesian-product-of-two-or-more-lists-2.cpp | 36 + ...cartesian-product-of-two-or-more-lists.cpp | 56 - ...artesian-product-of-two-or-more-lists.easy | 22 +- ...rtesian-product-of-two-or-more-lists.m2000 | 52 + ...artesian-product-of-two-or-more-lists-1.rs | 49 +- ...artesian-product-of-two-or-more-lists-2.rs | 25 +- ...artesian-product-of-two-or-more-lists-3.rs | 28 + .../case-sensitivity-of-identifiers.ballerina | 8 + .../EasyLang/catalan-numbers.easy | 6 +- .../REXX/catalan-numbers-1.rexx | 74 +- .../REXX/catalan-numbers-2.rexx | 92 +- Task/Chaocipher/EasyLang/chaocipher.easy | 10 +- Task/Chaos-game/EasyLang/chaos-game.easy | 7 +- .../Ballerina/character-codes.ballerina | 15 + .../Crystal/character-codes.cr | 2 + .../M2000-Interpreter/character-codes.m2000 | 41 +- Task/Character-codes/OPL/character-codes.opl | 5 + .../S-BASIC/character-codes.basic | 14 + .../Uxntal/character-codes.uxnatl | 35 +- Task/Check-Machin-like-formulas/00-TASK.txt | 2 +- .../Lua/check-input-device-is-a-terminal.lua | 6 + .../Lua/check-that-file-exists-3.lua | 10 + Task/Chernicks-Carmichael-numbers/00-TASK.txt | 18 +- .../REXX/chernicks-carmichael-numbers.rexx | 4 +- .../EasyLang/chinese-remainder-theorem.easy | 16 +- .../EasyLang/chinese-zodiac.easy | 4 +- .../ALGOL-68/chowla-numbers.alg | 2 +- Task/Chowla-numbers/Ada/chowla-numbers.ada | 2 +- .../EasyLang/chowla-numbers.easy | 26 +- .../Chowla-numbers/REXX/chowla-numbers-1.rexx | 29 - ...wla-numbers-2.rexx => chowla-numbers.rexx} | 15 +- ...es-of-given-radius-through-two-points.easy | 2 +- .../EasyLang/circular-primes.easy | 21 +- .../REXX/circular-primes-1.rexx | 37 - ...lar-primes-2.rexx => circular-primes.rexx} | 23 +- .../Scheme/circular-primes.scm | 82 + .../Ada/cistercian-numerals-1.ada | 92 + .../Ada/cistercian-numerals-2.ada | 36 + .../Ada/cistercian-numerals-3.ada | 49 + .../Ada/cistercian-numerals-4.ada | 54 + .../Ada/cistercian-numerals-5.ada | 9 + .../Ada/cistercian-numerals-6.ada | 54 + .../Ada/cistercian-numerals-7.ada | 76 + .../Applesoft-BASIC/cistercian-numerals.basic | 6 + .../Crystal/cistercian-numerals.cr | 96 ++ .../EasyLang/cistercian-numerals.easy | 47 +- .../FreeBASIC/cistercian-numerals.basic | 95 + Task/Classes/Ballerina/classes.ballerina | 28 + Task/Classes/Scheme/classes.scm | 11 + .../EasyLang/closest-pair-problem.easy | 2 +- .../Crystal/closures-value-capture.cr | 6 + .../UNIX-Shell/color-of-a-screen-pixel.sh | 1 + .../UNIX-Shell/color-quantization.sh | 1 + Task/Color-wheel/C/color-wheel.c | 99 ++ Task/Color-wheel/EasyLang/color-wheel.easy | 9 +- Task/Color-wheel/Emacs-Lisp/color-wheel.l | 75 + .../EasyLang/colorful-numbers.easy | 18 +- .../JavaScript/colorful-numbers.js | 85 + .../EasyLang/colour-bars-display.easy | 5 +- ...rs-display.py => colour-bars-display-1.py} | 0 .../Python/colour-bars-display-2.py | 40 + .../Uxntal/colour-bars-display.uxnatl | 32 +- .../EasyLang/colour-pinstripe-display.easy | 5 +- .../Uxntal/colour-pinstripe-display.uxnatl | 52 +- .../combinations-with-repetitions.easy | 4 +- Task/Combinations/EasyLang/combinations.easy | 2 +- .../Crystal/comma-quibbling.cr | 19 + .../Elena/comma-quibbling-1.elena | 23 + .../Elena/comma-quibbling-2.elena | 31 + ...rch64 => command-line-arguments-1.aarch64} | 0 .../command-line-arguments-2.aarch64 | 26 + .../JavaScript/commatizing-numbers.js | 42 + Task/Comments/OPL/comments.opl | 2 + Task/Comments/Uxntal/comments.uxnatl | 31 + .../EasyLang/compare-a-list-of-strings.easy | 18 +- .../compare-a-list-of-strings.m2000 | 35 + .../compare-length-of-two-strings.easy | 2 +- .../K/compare-length-of-two-strings.k | 11 + .../compare-length-of-two-strings-1.m2000 | 47 + .../compare-length-of-two-strings-2.m2000 | 28 + .../OPL/compare-length-of-two-strings-1.opl | 15 + .../OPL/compare-length-of-two-strings-2.opl | 47 + .../Scheme/compare-length-of-two-strings.scm | 47 + ...ompare-sorting-algorithms-performance-1.rs | 121 ++ ...ompare-sorting-algorithms-performance-2.rs | 16 + ...ompare-sorting-algorithms-performance-3.rs | 121 ++ .../Rust/compiler-ast-interpreter.rs | 400 +++++ .../JavaScript/compiler-code-generator.js | 502 ++++++ .../Rust/compiler-code-generator.rs | 644 +++++++ .../Rust/compiler-lexical-analyzer.rs | 682 ++++++++ .../FreeBASIC/compiler-syntax-analyzer.basic | 370 ++++ .../compiler-syntax-analyzer.m2000 | 2 +- .../Rust/compiler-syntax-analyzer.rs | 659 +++++++ ...whose-factors-are-all-substrings-of-k.easy | 27 +- .../Elena/concurrent-computing.elena | 11 + .../Excel/conditional-structures-1.excel | 1 + .../Excel/conditional-structures-2.excel | 1 + .../Excel/conditional-structures-3.excel | 1 + .../Uxntal/conditional-structures.uxnatl | 32 + ...h-ascending-or-descending-differences.easy | 4 +- ...ascending-or-descending-differences-1.rexx | 64 - ...-ascending-or-descending-differences.rexx} | 39 +- ...constrained-random-points-on-a-circle.easy | 3 +- ...metic-g-matrix-ng-continued-fraction-n-.cs | 70 + .../C-sharp/continued-fraction.cs | 116 +- .../EasyLang/continued-fraction.easy | 26 +- .../REXX/continued-fraction-1.rexx | 87 +- .../REXX/continued-fraction-2.rexx | 96 +- .../REXX/continued-fraction-3.rexx | 101 +- .../convert-seconds-to-compound-duration.cr | 43 + .../convert-seconds-to-compound-duration.easy | 4 +- Task/Convex-hull/EasyLang/convex-hull.easy | 15 +- Task/Convex-hull/Zig/convex-hull.zig | 96 ++ .../EasyLang/conways-game-of-life.easy | 21 +- Task/Copy-a-string/OPL/copy-a-string.opl | 8 + .../Copy-a-string/Uxntal/copy-a-string.uxnatl | 25 + .../Objeck/copy-stdin-to-stdout.objeck | 9 + .../EasyLang/count-in-factors.easy | 7 +- .../REXX/count-in-factors-1.rexx | 37 - .../REXX/count-in-factors-2.rexx | 51 - ...n-factors-3.rexx => count-in-factors.rexx} | 26 +- .../Ballerina/count-in-octal.ballerina | 28 + Task/Cramers-rule/EasyLang/cramers-rule.easy | 24 +- .../create-a-file-on-magnetic-tape.js | 2 + ...te-a-two-dimensional-array-at-runtime.uiua | 7 + .../create-an-object-at-a-given-address.xpl0 | 15 + Task/Cuban-primes/EasyLang/cuban-primes.easy | 25 +- Task/Cuban-primes/OCaml/cuban-primes.ml | 51 + Task/Cuban-primes/REXX/cuban-primes-1.rexx | 27 - ...{cuban-primes-2.rexx => cuban-primes.rexx} | 5 +- .../cumulative-standard-deviation.easy | 7 +- Task/Currency/Ballerina/currency.ballerina | 15 + Task/Currency/C++/currency.cpp | 21 + Task/Currency/Wren/currency.wren | 1 - Task/Currying/Ballerina/currying.ballerina | 12 + Task/Curzon-numbers/Ada/curzon-numbers.ada | 57 + .../EasyLang/curzon-numbers.easy | 6 +- .../EasyLang/cut-a-rectangle.easy | 10 +- .../EasyLang/cyclops-numbers.easy | 10 +- .../Cyclops-numbers/REXX/cyclops-numbers.rexx | 52 +- .../JavaScript/cyclotomic-polynomial.js | 504 ++++++ .../Rust/cyclotomic-polynomial.rs | 552 ++++++ .../Free-Pascal-Lazarus/dns-query.pas | 35 + Task/Damm-algorithm/Uiua/damm-algorithm.uiua | 21 + Task/Date-format/JavaScript/date-format.js | 20 +- .../Pascal/date-manipulation.pas | 108 ++ .../EasyLang/de-bruijn-sequences.easy | 18 +- .../JavaScript/de-bruijn-sequences.js | 96 ++ .../Zig/de-bruijn-sequences.zig | 111 ++ .../EasyLang/deal-cards-for-freecell.easy | 12 +- .../FreeBASIC/deconvolution-2d+.basic | 183 ++ .../EasyLang/demings-funnel.easy | 33 +- .../EasyLang/department-numbers.easy | 2 +- .../Nu/department-numbers.nu | 24 + .../EasyLang/descending-primes.easy | 26 +- .../Rust/descending-primes-1.rs | 1 + .../Rust/descending-primes-2.rs | 1 + .../Rust/descending-primes-3.rs | 1 + .../Rust/descending-primes-4.rs | 1 + ...ro.rexx => detect-division-by-zero-1.rexx} | 0 .../REXX/detect-division-by-zero-2.rexx | 10 + .../REXX/detect-division-by-zero-3.rexx | 4 + ...if-a-string-has-all-the-same-characters.cr | 10 + ...-a-string-has-all-the-same-characters.easy | 6 +- ...-a-string-has-all-the-same-characters-1.nu | 20 + ...-a-string-has-all-the-same-characters-2.nu | 27 + ...if-a-string-has-all-unique-characters.easy | 6 +- .../determine-if-a-string-is-collapsible.cr | 16 + .../determine-if-a-string-is-squeezable.easy | 6 +- .../determine-if-two-triangles-overlap.easy | 14 +- .../R/determine-sentence-type.r | 14 + .../Arturo/dice-game-probabilities.arturo | 11 + .../EasyLang/dice-game-probabilities.easy | 4 +- .../Quackery/dice-game-probabilities.quackery | 14 + ...ital-root-multiplicative-digital-root.easy | 14 +- Task/Digital-root/REXX/digital-root-2.rexx | 49 +- Task/Digital-root/REXX/digital-root-3.rexx | 20 - Task/Digital-root/REXX/digital-root-4.rexx | 57 - .../Crystal/dijkstras-algorithm.cr | 43 + .../EasyLang/dijkstras-algorithm.easy | 8 +- .../Tcl/dijkstras-algorithm-2.tcl | 28 +- .../Zig/dijkstras-algorithm.zig | 158 ++ .../dinesmans-multiple-dwelling-problem.easy | 43 +- .../PARI-GP/disarium-numbers.parigp | 20 + Task/Disarium-numbers/R/disarium-numbers.r | 16 + .../EasyLang/discordian-date.easy | 10 +- .../R/display-a-linear-combination.r | 27 + .../Objeck/distributed-programming.objeck | 32 + ...on-of-0-digits-in-factorial-series-1.basic | 86 + ...on-of-0-digits-in-factorial-series-2.basic | 33 + ...ibution-of-0-digits-in-factorial-series.js | 40 + .../diversity-prediction-theorem.easy | 6 +- .../Rust/doubly-linked-list-definition-1.rs | 7 + .../Rust/doubly-linked-list-definition-2.rs | 40 + ...doubly-linked-list-element-definition-1.rs | 5 - ...doubly-linked-list-element-definition-2.rs | 12 - .../doubly-linked-list-element-definition.rs | 5 + .../doubly-linked-list-element-insertion-1.rs | 16 +- .../doubly-linked-list-element-insertion-2.rs | 93 +- .../Rust/doubly-linked-list-traversal.rs | 15 + Task/Dragon-curve/EasyLang/dragon-curve.easy | 11 +- Task/Draw-a-clock/EasyLang/draw-a-clock.easy | 48 +- Task/Draw-a-clock/OPL/draw-a-clock.opl | 4 + .../Draw-a-cuboid/EasyLang/draw-a-cuboid.easy | 36 +- Task/Draw-a-cuboid/R/draw-a-cuboid.r | 14 + Task/Draw-a-pixel/EasyLang/draw-a-pixel.easy | 5 +- Task/Draw-a-pixel/OPL/draw-a-pixel.opl | 8 + Task/Draw-a-pixel/Uxntal/draw-a-pixel.uxnatl | 22 - .../EasyLang/draw-a-rotating-cube.easy | 31 +- .../EasyLang/duffinian-numbers.easy | 10 +- .../Crystal/dutch-national-flag-problem.cr | 34 + .../R/dutch-national-flag-problem.r | 26 + .../dynamic-variable-names.ballerina | 16 + Task/Eban-numbers/EasyLang/eban-numbers.easy | 23 +- .../EasyLang/egyptian-division.easy | 2 +- .../Arturo/element-wise-operations.arturo | 41 + .../EasyLang/element-wise-operations.easy | 67 + ...erations.k => element-wise-operations-1.k} | 0 .../K/element-wise-operations-2.k | 6 + .../elementary-cellular-automaton.easy | 10 +- ...iptic-curve-digital-signature-algorithm.cs | 369 ++++ ...iptic-curve-digital-signature-algorithm.js | 356 ++++ ...iptic-curve-digital-signature-algorithm.rs | 507 ++++++ .../ALGOL-68/elliptic-curve-arithmetic.alg | 81 + .../FreeBASIC/elliptic-curve-arithmetic.basic | 98 ++ .../JavaScript/elliptic-curve-arithmetic.js | 90 + Task/Emirp-primes/REXX/emirp-primes-1.rexx | 163 +- Task/Emirp-primes/REXX/emirp-primes-2.rexx | 214 +-- Task/Emirp-primes/REXX/emirp-primes-3.rexx | 92 - .../Ballerina/empty-string.ballerina | 12 + .../Arturo/entropy-narcissist.arturo | 7 + .../equal-prime-and-composite-sums.easy | 19 +- .../Uiua/ethiopian-multiplication.uiua | 10 + .../REXX/euclid-mullin-sequence.rexx | 57 +- Task/Euler-method/EasyLang/euler-method.easy | 30 +- Task/Euler-method/K/euler-method.k | 15 + Task/Euler-method/Odin/euler-method.odin | 36 + Task/Euler-method/Q/euler-method.q | 10 + .../EasyLang/eulers-constant-0.5772....easy | 2 +- .../Fortran/eulers-constant-0.5772....f | 131 ++ .../REXX/eulers-constant-0.5772....rexx | 13 +- .../evaluate-binomial-coefficients.asymptote | 34 + .../evaluate-binomial-coefficients.basic | 29 + .../evaluate-binomial-coefficients.basic | 23 + .../evaluate-binomial-coefficients.gambas | 36 + .../evaluate-binomial-coefficients.basic | 22 + .../evaluate-binomial-coefficients.basic | 25 + .../evaluate-binomial-coefficients.basic | 38 + .../Prolog/evaluate-binomial-coefficients.pro | 10 + .../evaluate-binomial-coefficients.basic | 45 + .../evaluate-binomial-coefficients-1.basic | 35 + .../evaluate-binomial-coefficients-2.basic | 25 + .../evaluate-binomial-coefficients.basic | 33 + Task/Events/EasyLang/events.easy | 6 +- Task/Execute-Brain-/Crystal/execute-brain-.cr | 33 + .../EasyLang/execute-brain-.easy | 6 +- Task/Execute-Brain-/Odin/execute-brain-.odin | 126 ++ .../EasyLang/execute-computer-zero.easy | 2 +- .../Perl/execute-computer-zero.pl | 154 ++ Task/Execute-HQ9+/EasyLang/execute-hq9+.easy | 2 +- .../Execute-SNUSP/EasyLang/execute-snusp.easy | 10 +- .../C-sharp/execute-a-markov-algorithm.cs | 161 ++ .../Zig/execute-a-markov-algorithm.zig | 278 +++ .../C-sharp/extensible-prime-generator.cs | 88 + .../EasyLang/extensible-prime-generator.easy | 2 +- .../REXX/extensible-prime-generator-1.rexx | 50 - .../REXX/extensible-prime-generator-3.rexx | 9 - ...2.rexx => extensible-prime-generator.rexx} | 52 +- .../extreme-floating-point-values.ballerina | 34 + Task/Factorial/EasyLang/factorial.easy | 4 +- Task/Factorial/Java/factorial-4.java | 27 + .../M2000-Interpreter/factorial-2.m2000 | 25 +- Task/Factorial/Pascal/factorial-2.pas | 65 +- Task/Factorial/Pascal/factorial-3.pas | 107 +- Task/Factorial/REXX/factorial-1.rexx | 22 +- Task/Factorial/REXX/factorial-2.rexx | 91 +- Task/Factorial/REXX/factorial-3.rexx | 27 - Task/Factorial/REXX/factorial-4.rexx | 4 - Task/Factorial/REXX/factorial-5.rexx | 67 - Task/Factorial/SQL/factorial.sql | 6 + Task/Factorial/Tcl/factorial-1.tcl | 14 +- Task/Factorial/Tcl/factorial-2.tcl | 7 +- Task/Factorial/Tcl/factorial-3.tcl | 4 +- Task/Factorial/Tcl/factorial-4.tcl | 18 +- Task/Factorial/Tcl/factorial-5.tcl | 28 +- Task/Factorial/Tcl/factorial-6.tcl | 14 +- Task/Factorial/Tcl/factorial-7.tcl | 5 + Task/Factorial/Uxntal/factorial.uxnatl | 28 +- Task/Factorions/EasyLang/factorions.easy | 21 + Task/Factorions/R/factorions.r | 15 + .../REXX/factors-of-a-mersenne-number-1.rexx | 53 - ...rexx => factors-of-a-mersenne-number.rexx} | 16 +- .../EasyLang/factors-of-an-integer.easy | 13 +- .../REXX/factors-of-an-integer-1.rexx | 61 +- .../REXX/factors-of-an-integer-2.rexx | 54 +- .../REXX/factors-of-an-integer-3.rexx | 57 - .../fairshare-between-two-and-more.easy | 2 +- .../Ballerina/farey-sequence.ballerina | 83 + .../EasyLang/farey-sequence.easy | 6 +- .../EasyLang/fast-fourier-transform.easy | 2 +- .../Faulhabers-formula/C/faulhabers-formula.c | 254 ++- .../Rust/faulhabers-formula.rs | 178 ++ .../feigenbaum-constant-calculation.easy | 9 +- .../feigenbaum-constant-calculation-1.rexx | 33 - ...x => feigenbaum-constant-calculation.rexx} | 23 +- .../FreeBASIC/fermat-numbers.basic | 102 ++ .../Fermat-numbers/REXX/fermat-numbers-1.rexx | 33 - .../Fermat-numbers/REXX/fermat-numbers-2.rexx | 36 - ...mat-numbers-3.rexx => fermat-numbers.rexx} | 11 +- .../fibonacci-n-step-number-sequences.easy | 6 +- .../APL/fibonacci-sequence-1.apl | 2 +- .../APL/fibonacci-sequence-2.apl | 2 +- .../APL/fibonacci-sequence-3.apl | 2 +- .../APL/fibonacci-sequence-4.apl | 2 +- .../APL/fibonacci-sequence-5.apl | 1 + .../K/fibonacci-sequence-1.k | 2 +- .../K/fibonacci-sequence-2.k | 2 +- .../Uxntal/fibonacci-sequence.uxnatl | 31 + .../Zig/fibonacci-sequence.zig | 14 + .../EasyLang/fibonacci-word.easy | 6 +- .../file-extension-is-in-extensions-list.cs | 20 + ...file-extension-is-in-extensions-list.m2000 | 35 + .../file-extension-is-in-extensions-list.nu | 20 + .../Nu/file-size-distribution.nu | 24 + .../Tcl/file-size-distribution-1.tcl | 75 + ...ution.tcl => file-size-distribution-2.tcl} | 0 ...nd-chess960-starting-position-identifier.d | 83 + .../BQN/find-common-directory-path.bqn | 9 + .../find-if-a-point-is-within-a-triangle.cs | 90 + .../find-if-a-point-is-within-a-triangle.easy | 23 +- ...eft-truncatable-prime-in-a-given-base.rexx | 10 +- .../find-limit-of-recursion.ballerina | 10 + .../EasyLang/find-limit-of-recursion.easy | 6 +- ...bers-in-both-binary-and-ternary-bases.easy | 15 +- ...numbers-in-both-binary-and-ternary-bases.r | 82 + ...e-intersection-of-a-line-with-a-plane.easy | 29 +- .../find-the-intersection-of-two-lines.easy | 24 +- .../find-the-last-sunday-of-each-month.easy | 10 +- .../find-the-missing-permutation.easy | 36 +- .../Zig/find-the-missing-permutation.zig | 39 + ...square-in-base-n-with-n-unique-digits.easy | 10 +- ...ct-square-in-base-n-with-n-unique-digits.f | 100 ++ ...that-has-leading-decimal-digits-of-12.easy | 6 +- Task/Fivenum/Ballerina/fivenum.ballerina | 30 + Task/Fivenum/EasyLang/fivenum.easy | 10 +- Task/FizzBuzz/APL/fizzbuzz-1.apl | 4 +- Task/FizzBuzz/APL/fizzbuzz-2.apl | 2 +- Task/FizzBuzz/APL/fizzbuzz-3.apl | 2 +- Task/FizzBuzz/APL/fizzbuzz-4.apl | 3 +- Task/FizzBuzz/APL/fizzbuzz-5.apl | 42 +- Task/FizzBuzz/APL/fizzbuzz-6.apl | 4 +- Task/FizzBuzz/APL/fizzbuzz-7.apl | 40 + .../Erlang/{fizzbuzz.erl => fizzbuzz-1.erl} | 0 Task/FizzBuzz/Erlang/fizzbuzz-2.erl | 27 + Task/FizzBuzz/Excel/fizzbuzz.excel | 11 + Task/FizzBuzz/Factor/fizzbuzz-1.factor | 9 +- Task/FizzBuzz/Factor/fizzbuzz-2.factor | 24 +- Task/FizzBuzz/Factor/fizzbuzz-3.factor | 37 +- Task/FizzBuzz/Factor/fizzbuzz-4.factor | 24 + Task/FizzBuzz/J/fizzbuzz-1.j | 3 +- Task/FizzBuzz/J/fizzbuzz-10.j | 2 + Task/FizzBuzz/J/fizzbuzz-11.j | 36 + Task/FizzBuzz/J/fizzbuzz-2.j | 2 +- Task/FizzBuzz/J/fizzbuzz-3.j | 6 +- Task/FizzBuzz/J/fizzbuzz-4.j | 7 +- Task/FizzBuzz/J/fizzbuzz-5.j | 7 +- Task/FizzBuzz/J/fizzbuzz-6.j | 7 +- Task/FizzBuzz/J/fizzbuzz-7.j | 42 +- Task/FizzBuzz/J/fizzbuzz-8.j | 6 + Task/FizzBuzz/J/fizzbuzz-9.j | 1 + Task/FizzBuzz/K/fizzbuzz-1.k | 2 +- Task/FizzBuzz/K/fizzbuzz-2.k | 3 +- Task/FizzBuzz/K/fizzbuzz-3.k | 9 +- Task/FizzBuzz/K/fizzbuzz-4.k | 9 +- Task/FizzBuzz/Pascal/fizzbuzz.pas | 14 - Task/FizzBuzz/Python/fizzbuzz-10.py | 40 +- Task/FizzBuzz/Python/fizzbuzz-11.py | 34 +- Task/FizzBuzz/Python/fizzbuzz-12.py | 13 +- Task/FizzBuzz/Python/fizzbuzz-13.py | 13 +- Task/FizzBuzz/Python/fizzbuzz-14.py | 1 + Task/FizzBuzz/Python/fizzbuzz-8.py | 18 +- Task/FizzBuzz/Python/fizzbuzz-9.py | 14 +- Task/FizzBuzz/Smalltalk/fizzbuzz-4.st | 22 +- Task/FizzBuzz/Smalltalk/fizzbuzz-5.st | 15 +- Task/FizzBuzz/Smalltalk/fizzbuzz-6.st | 10 +- Task/FizzBuzz/Smalltalk/fizzbuzz-7.st | 5 + .../Uxntal/flow-control-structures.uxnatl | 24 + .../EasyLang/floyd-warshall-algorithm.easy | 6 +- .../XPL0/floyd-warshall-algorithm.xpl0 | 49 + .../Zig/floyd-warshall-algorithm.zig | 99 ++ .../Ballerina/floyds-triangle.ballerina | 20 + .../EasyLang/floyds-triangle.easy | 8 +- .../Objeck/floyds-triangle.objeck | 20 + .../YAMLScript/floyds-triangle.ys | 2 +- Task/Forest-fire/EasyLang/forest-fire.easy | 79 +- Task/Forest-fire/J/forest-fire-3.j | 16 + Task/Forest-fire/J/forest-fire-4.j | 10 + ...put.alg => formatted-numeric-output-1.alg} | 0 .../ALGOL-68/formatted-numeric-output-2.alg | 59 + .../formatted-numeric-output.basic | 27 + .../JavaScript/formatted-numeric-output.js | 21 +- .../EasyLang/fortunate-numbers.easy | 22 +- .../REXX/fortunate-numbers-1.rexx | 54 - ...-numbers-2.rexx => fortunate-numbers.rexx} | 8 +- .../Ballerina/four-bit-adder.ballerina | 31 + .../EasyLang/four-bit-adder.easy | 8 +- Task/Fractal-tree/EasyLang/fractal-tree.easy | 24 +- Task/Fractran/EasyLang/fractran.easy | 10 +- Task/Fractran/Julia/fractran.jl | 75 +- Task/Fractran/Odin/fractran.odin | 77 + Task/Fractran/REXX/fractran.rexx | 4 +- .../Ballerina/function-definition.ballerina | 9 + .../Excel/function-definition.excel | 4 + .../EasyLang/galton-box-animation.easy | 25 +- .../EasyLang/gamma-function.easy | 4 +- Task/Gamma-function/REXX/gamma-function.rexx | 19 +- .../Ballerina/gapful-numbers.ballerina | 26 + .../EasyLang/gapful-numbers.easy | 6 +- .../gauss-jordan-matrix-inversion.easy | 24 +- .../gauss-jordan-matrix-inversion.js | 99 ++ .../EasyLang/gaussian-elimination.easy | 2 +- .../D/generate-chess960-starting-position-1.d | 72 +- .../D/generate-chess960-starting-position-2.d | 32 +- .../D/generate-chess960-starting-position-3.d | 20 +- .../D/generate-chess960-starting-position-4.d | 11 + .../D/generate-chess960-starting-position-5.d | 13 + .../generate-chess960-starting-position.pas | 41 + .../generate-chess960-starting-position.easy | 2 +- .../generate-chess960-starting-position-3.rs | 36 + .../generate-lower-case-ascii-alphabet.objeck | 7 + ...> generate-lower-case-ascii-alphabet-1.rs} | 0 .../generate-lower-case-ascii-alphabet-2.rs | 1 + ...ential.tcl => generator-exponential-1.tcl} | 0 .../Tcl/generator-exponential-2.tcl | 13 + .../Tcl/generator-exponential-3.tcl | 54 + .../Ursalang/generator-exponential.ursa | 1 - ...globally-replace-text-in-several-files.bqn | 9 + .../EasyLang/goldbachs-comet.easy | 18 +- Task/Goldbachs-comet/Go/goldbachs-comet.go | 63 + .../Goldbachs-comet/REXX/goldbachs-comet.rexx | 19 +- .../EasyLang/golden-ratio-convergence.easy | 2 +- Task/Gotchas/C-sharp/gotchas.cs | 18 + .../FreeBASIC/graph-colouring.basic | 149 ++ .../JavaScript/graph-colouring.js | 222 +++ Task/Graph-colouring/Rust/graph-colouring.rs | 134 ++ Task/Gray-code/SETL/gray-code.setl | 29 + .../M2000-Interpreter/grayscale-image.m2000 | 397 ++--- .../greatest-subsequential-sum.ballerina | 42 + .../EasyLang/greatest-subsequential-sum.easy | 6 +- .../greatest-subsequential-sum-1.m2000 | 26 + .../greatest-subsequential-sum-2.m2000 | 36 + ...greedy-algorithm-for-egyptian-fractions.js | 222 +++ .../EasyLang/greyscale-bars-display.easy | 5 +- Task/HTTP/Elena/http.elena | 13 + Task/HTTPS/Elena/https.elena | 14 + .../Ballerina/hailstone-sequence.ballerina | 34 + .../EasyLang/hailstone-sequence.easy | 14 +- .../Odin/hailstone-sequence.odin | 65 + .../R/halt-and-catch-fire-1.r | 1 + .../R/halt-and-catch-fire-2.r | 1 + .../REXX/hamming-numbers-1.rexx | 20 - .../REXX/hamming-numbers-2.rexx | 26 - .../REXX/hamming-numbers-3.rexx | 26 - .../REXX/hamming-numbers-4.rexx | 73 - .../Hamming-numbers/REXX/hamming-numbers.rexx | 40 + .../EasyLang/harmonic-series.easy | 2 +- .../Harmonic-series/Fortran/harmonic-series.f | 83 + .../hello-world-graphical.ahk | 0 .../EasyLang/hello-world-graphical.easy | 4 +- .../Odin/hello-world-graphical.odin | 27 + .../Uxntal/hello-world-graphical.uxnatl | 240 +++ .../hello-world-newline-omission.ballerina | 5 + .../hello-world-newline-omission.uxnatl | 26 +- ...4 => hello-world-standard-error-1.aarch64} | 0 .../hello-world-standard-error-2.aarch64 | 16 + .../hello-world-standard-error.arm | 2 +- .../hello-world-standard-error.ballerina | 5 + .../Crystal/hello-world-standard-error.cr | 1 + .../Objeck/hello-world-standard-error.objeck | 5 + .../Uxntal/hello-world-standard-error.uxnatl | 17 + ...ext.aarch64 => hello-world-text-1.aarch64} | 0 .../hello-world-text-2.aarch64 | 16 + .../hello-world-text-3.aarch64 | 21 + .../Hello-world-Text/OPL/hello-world-text.opl | 4 + .../Uxntal/hello-world-text.uxnatl | 22 - .../EasyLang/heronian-triangles.easy | 30 +- Task/Hex-words/Crystal/hex-words.cr | 10 + Task/Hex-words/EasyLang/hex-words.easy | 22 +- Task/Hex-words/R/hex-words.r | 43 + Task/Hex-words/Rust/hex-words.rs | 83 + .../Pascal/higher-order-functions-3.pas | 936 ++++------ .../REXX/higher-order-functions-2.rexx | 12 - ...ons-1.rexx => higher-order-functions.rexx} | 12 +- .../Hilbert-curve/EasyLang/hilbert-curve.easy | 13 +- .../hofstadter-conway-$10-000-sequence.easy | 6 +- .../hofstadter-figure-figure-sequences.easy | 4 +- .../EasyLang/hofstadter-q-sequence.easy | 12 +- Task/Home-primes/REXX/home-primes-1.rexx | 46 - Task/Home-primes/REXX/home-primes-2.rexx | 40 - Task/Home-primes/REXX/home-primes.rexx | 48 + ...ners-rule-for-polynomial-evaluation-2.rexx | 5 +- .../EasyLang/humble-numbers.easy | 28 +- .../Humble-numbers/REXX/humble-numbers-1.rexx | 44 - .../Humble-numbers/REXX/humble-numbers-2.rexx | 86 - Task/Humble-numbers/REXX/humble-numbers.rexx | 48 + .../Nu/i-before-e-except-after-c-1.nu | 32 + .../Nu/i-before-e-except-after-c-2.nu | 48 + Task/IBAN/EasyLang/iban.easy | 2 +- .../EasyLang/identity-matrix.easy | 2 +- ...y-matrix.excel => identity-matrix-1.excel} | 0 .../Excel/identity-matrix-2.excel | 1 + ...-a-software-engineer-get-me-out-of-here.py | 175 ++ Task/Image-noise/EasyLang/image-noise.easy | 23 +- .../Bracmat/include-a-file.bracmat | 2 +- ...aps-between-consecutive-niven-numbers.easy | 2 +- .../Crystal/increment-a-numerical-string.cr | 5 + .../Tcl/increment-a-numerical-string-1.tcl | 10 + .../Tcl/increment-a-numerical-string-2.tcl | 6 + .../Tcl/increment-a-numerical-string-3.tcl | 5 + .../Tcl/increment-a-numerical-string-4.tcl | 4 + .../Tcl/increment-a-numerical-string-5.tcl | 2 + .../Tcl/increment-a-numerical-string-6.tcl | 1 + .../Tcl/increment-a-numerical-string.tcl | 2 - ...index-finite-lists-of-positive-integers.cs | 107 ++ .../{input-loop.js => input-loop-1.js} | 0 Task/Input-loop/JavaScript/input-loop-2.js | 21 + .../Uxntal/integer-sequence.uxnatl | 23 + .../Crystal/interactive-programming-repl-.cr | 11 + ...nverted-syntax.rb => inverted-syntax-1.rb} | 0 .../Inverted-syntax/Ruby/inverted-syntax-2.rb | 4 + .../EasyLang/isograms-and-heterograms.easy | 38 +- .../isqrt-integer-square-root-of-x.js | 36 + .../REXX/isqrt-integer-square-root-of-x.rexx | 169 +- .../Jacobi-symbol/EasyLang/jacobi-symbol.easy | 18 +- .../Jacobi-symbol/JavaScript/jacobi-symbol.js | 52 + .../EasyLang/jaro-winkler-distance.easy | 32 +- .../M2000-Interpreter/jensens-device-1.m2000 | 4 +- .../M2000-Interpreter/jensens-device-2.m2000 | 4 +- .../M2000-Interpreter/jensens-device-3.m2000 | 4 +- .../EasyLang/jordan-p-lya-numbers.easy | 14 +- Task/JortSort/EasyLang/jortsort.easy | 10 +- .../FreeBASIC/juggler-sequence.basic | 87 + Task/Julia-set/EasyLang/julia-set.easy | 27 +- Task/K-d-tree/C-sharp/k-d-tree.cs | 472 +++++ Task/K-d-tree/Dart/k-d-tree.dart | 220 +++ Task/K-d-tree/JavaScript/k-d-tree.js | 235 +++ .../kernighans-large-earthquake-problem.alg | 3 +- .../R/kernighans-large-earthquake-problem.r | 2 + ...keyboard-input-flush-the-keyboard-buffer.l | 1 + .../keyboard-input-keypress-check.easy | 5 +- .../keyboard-input-keypress-check.l | 21 + ...yboard-input-obtain-a-y-or-n-response.easy | 6 +- .../keyboard-input-obtain-a-y-or-n-response.l | 5 + ...board-input-obtain-a-y-or-n-response-1.tcl | 42 +- ...board-input-obtain-a-y-or-n-response-2.tcl | 24 +- ...board-input-obtain-a-y-or-n-response-3.tcl | 11 + .../EasyLang/knapsack-problem-0-1.easy | 6 +- .../EasyLang/knapsack-problem-bounded.easy | 18 +- .../Nim/knapsack-problem-continuous.nim | 2 +- .../EasyLang/knapsack-problem-unbounded.easy | 2 +- Task/Knights-tour/EasyLang/knights-tour.easy | 76 +- .../Knuth-shuffle/EasyLang/knuth-shuffle.easy | 2 +- .../Knuth-shuffle/Objeck/knuth-shuffle.objeck | 21 + Task/Knuth-shuffle/Wisp/knuth-shuffle.wisp | 30 + .../Fortran/knuths-algorithm-s.f | 121 ++ .../FreeBASIC/knuths-algorithm-s.basic | 98 ++ .../JavaScript/knuths-algorithm-s.js | 36 + .../FreeBASIC/knuths-power-tree.basic | 247 +++ .../JavaScript/knuths-power-tree.js | 103 ++ Task/Koch-curve/EasyLang/koch-curve.easy | 19 +- Task/Kosaraju/EasyLang/kosaraju.easy | 4 +- Task/Kosaraju/Rust/kosaraju.rs | 91 + .../kronecker-product-based-fractals.easy | 7 +- Task/Langtons-ant/EasyLang/langtons-ant.easy | 13 +- .../largest-int-from-concatenated-ints.xpl0 | 34 + ...argest-number-divisible-by-its-digits.easy | 12 +- .../ALGOL-60/largest-proper-divisor-of-n.alg | 33 + .../EasyLang/last-friday-of-each-month.easy | 10 +- .../EasyLang/last-letter-first-letter.easy | 6 +- .../FreeBASIC/last-letter-first-letter.basic | 55 + .../XPL0/last-letter-first-letter.xpl0 | 68 + .../Rust/latin-squares-in-reduced-form.rs | 144 ++ .../Zig/latin-squares-in-reduced-form.zig | 207 +++ .../legendre-prime-counting-function-1.rexx | 13 +- .../legendre-prime-counting-function-2.rexx | 13 +- .../legendre-prime-counting-function-3.rexx | 7 +- .../ERRE/leonardo-numbers.erre | 24 + .../EasyLang/leonardo-numbers.easy | 2 +- ...ter-frequency.nu => letter-frequency-1.nu} | 0 .../Letter-frequency/Nu/letter-frequency-2.nu | 1 + .../levenshtein-distance-alignment.easy | 26 +- .../ANSI-BASIC/levenshtein-distance.basic | 29 + .../levenshtein-distance.basic | 18 + .../Ballerina/levenshtein-distance.ballerina | 31 + .../levenshtein-distance.pas | 40 + .../GW-BASIC/levenshtein-distance.basic | 28 + .../Nascom-BASIC/levenshtein-distance.basic | 33 + .../Pascal/levenshtein-distance.pas | 38 - .../RapidQ/levenshtein-distance.rapidq | 36 + .../XBasic/levenshtein-distance.basic | 40 + .../XPL0/levenshtein-distance.xpl0 | 40 + .../EasyLang/list-rooted-trees.easy | 24 +- .../REXX/literals-floating-point-1.rexx | 6 - .../REXX/literals-floating-point-2.rexx | 3 - .../REXX/literals-floating-point.rexx | 52 + .../JavaScript/literals-integer.js | 6 +- .../REXX/literals-integer.rexx | 80 +- .../EasyLang/logical-operations.easy | 2 +- Task/Long-primes/EasyLang/long-primes.easy | 14 +- Task/Long-primes/REXX/long-primes-1.rexx | 22 - Task/Long-primes/REXX/long-primes-2.rexx | 28 - Task/Long-primes/REXX/long-primes-3.rexx | 38 - Task/Long-primes/REXX/long-primes.rexx | 56 + .../C-sharp/longest-string-challenge.cs | 36 + .../EasyLang/look-and-say-sequence.easy | 2 +- .../MAD/look-and-say-sequence.mad | 36 + .../Python/look-and-say-sequence-5.py | 9 + .../SETL/look-and-say-sequence.setl | 14 +- ...r-multiple-arrays-simultaneously.ballerina | 10 + Task/Loops-Break/ALGOL-68/loops-break.alg | 14 +- .../Ballerina/loops-break.ballerina | 12 + Task/Loops-Break/Uxntal/loops-break.uxnatl | 62 + .../Ballerina/loops-continue.ballerina | 12 + .../Uxntal/loops-continue.uxnatl | 31 + .../Ballerina/loops-do-while-1.ballerina | 10 + .../Ballerina/loops-do-while-2.ballerina | 11 + Task/Loops-Do-while/SETL/loops-do-while.setl | 7 + .../Uxntal/loops-do-while.uxnatl | 22 + .../Ballerina/loops-downward-for.ballerina | 8 + .../loops-for-with-a-specified-step.ballerina | 9 + .../loops-for-with-a-specified-step.uxnatl | 20 + Task/Loops-For/Ballerina/loops-for.ballerina | 8 + Task/Loops-For/Excel/loops-for.excel | 9 + .../M2000-Interpreter/loops-for-1.m2000 | 4 + .../M2000-Interpreter/loops-for-2.m2000 | 17 + .../M2000-Interpreter/loops-for.m2000 | 14 - .../Ballerina/loops-foreach.ballerina | 8 + .../Loops-Foreach/Uxntal/loops-foreach.uxnatl | 44 + ...-increment-loop-index-within-loop-body.alg | 43 + ...ment-loop-index-within-loop-body.ballerina | 39 + ...increment-loop-index-within-loop-body.icon | 40 + ...ncrement-loop-index-within-loop-body.basic | 41 + ...increment-loop-index-within-loop-body.setl | 29 + .../8080-Assembly/loops-infinite.8080 | 7 + Task/Loops-Infinite/APL/loops-infinite.apl | 1 + .../Ballerina/loops-infinite.ballerina | 7 + Task/Loops-Infinite/J/loops-infinite-1.j | 2 +- Task/Loops-Infinite/J/loops-infinite-2.j | 2 +- Task/Loops-Infinite/J/loops-infinite-3.j | 1 + Task/Loops-Infinite/K/loops-infinite-1.k | 1 + Task/Loops-Infinite/K/loops-infinite-2.k | 1 + Task/Loops-Infinite/K/loops-infinite.k | 1 - .../Miranda/loops-infinite.miranda | 2 + .../Loops-Infinite/Refal/loops-infinite.refal | 1 + Task/Loops-Infinite/SETL/loops-infinite.setl | 5 + .../Uxntal/loops-infinite.uxnatl | 8 +- .../Ballerina/loops-n-plus-one-half.ballerina | 8 + .../Crystal/loops-n-plus-one-half.cr | 6 + .../Uxntal/loops-n-plus-one-half.uxnatl | 34 + .../Ballerina/loops-nested.ballerina | 23 + Task/Loops-Nested/Icon/loops-nested-1.icon | 15 +- Task/Loops-Nested/Icon/loops-nested-2.icon | 5 +- .../Ballerina/loops-while.ballerina | 12 +- Task/Loops-While/Uxntal/loops-while.uxnatl | 21 + .../loops-with-multiple-ranges.ballerina | 82 + .../Ballerina/loops-wrong-ranges.ballerina | 29 + .../REXX/lucas-lehmer-test.rexx | 120 +- ...mer-test.raku => lucas-lehmer-test-1.raku} | 0 .../Raku/lucas-lehmer-test-2.raku | 16 + .../Ludic-numbers/EasyLang/ludic-numbers.easy | 4 +- Task/Ludic-numbers/REXX/ludic-numbers.rexx | 89 +- ...=> luhn-test-of-credit-card-numbers-1.lua} | 6 +- .../luhn-test-of-credit-card-numbers-2.lua | 8 + .../luhn-test-of-credit-card-numbers-3.lua | 3 + .../ANSI-BASIC/m-bius-function.basic | 28 + .../M-bius-function/ASIC/m-bius-function.asic | 37 + .../EasyLang/m-bius-function.easy | 14 +- .../JavaScript/m-bius-function-1.js | 32 + .../JavaScript/m-bius-function-2.js | 7 + Task/M-bius-function/K/m-bius-function.k | 8 + .../Modula-2/m-bius-function.mod2 | 41 + Task/M-bius-function/PHP/m-bius-function.php | 29 + .../REXX/m-bius-function-1.rexx | 49 - .../REXX/m-bius-function-2.rexx | 41 - .../M-bius-function/REXX/m-bius-function.rexx | 30 + .../RapidQ/m-bius-function.rapidq | 36 + .../EasyLang/md5-implementation.easy | 16 +- .../JavaScript/md5-implementation.js | 209 +++ Task/MD5/EasyLang/md5.easy | 20 +- Task/Mad-Libs/ALGOL-68/mad-libs.alg | 210 ++- Task/Mad-Libs/EasyLang/mad-libs.easy | 58 + Task/Mad-Libs/F-Sharp/mad-libs.fs | 63 + Task/Mad-Libs/Objeck/mad-libs.objeck | 34 + Task/Magic-8-ball/Crystal/magic-8-ball.cr | 13 + .../ANSI-BASIC/magic-constant.basic | 25 + Task/Magic-constant/C/magic-constant.c | 32 + .../GW-BASIC/magic-constant.basic | 24 + .../Gambas/magic-constant.gambas | 35 + .../Modula-2/magic-constant.mod2 | 46 + Task/Magic-constant/PHP/magic-constant.php | 27 + Task/Magic-constant/REXX/magic-constant.rexx | 62 + .../Tiny-BASIC/magic-constant.basic | 21 + .../magic-squares-of-doubly-even-order.easy | 25 +- .../EasyLang/magic-squares-of-odd-order.easy | 4 +- .../magic-squares-of-singly-even-order.easy | 17 +- .../EasyLang/magnanimous-numbers.easy | 22 +- .../REXX/magnanimous-numbers.rexx | 73 +- .../EasyLang/mandelbrot-set.easy | 61 +- Task/Mandelbrot-set/Julia/mandelbrot-set-7.jl | 45 +- .../Mandelbrot-set/Python/mandelbrot-set-8.py | 50 +- Task/Map-range/ANSI-BASIC/map-range.basic | 10 + .../Free-Pascal-Lazarus/map-range-1.pas | 13 + .../Free-Pascal-Lazarus/map-range-2.pas | 58 + Task/Map-range/GW-BASIC/map-range.basic | 13 + Task/Map-range/Liberty-BASIC/map-range.basic | 16 +- Task/Map-range/Modula-2/map-range.mod2 | 22 + Task/Map-range/PHP/map-range.php | 15 + Task/Map-range/Pascal/map-range-1.pas | 13 - Task/Map-range/Pascal/map-range-2.pas | 56 - Task/Map-range/QBasic/map-range.basic | 10 + Task/Map-range/RapidQ/map-range.rapidq | 11 + Task/Map-range/TypeScript/map-range.ts | 14 + Task/Mastermind/EasyLang/mastermind.easy | 177 +- .../EasyLang/matrix-chain-multiplication.easy | 4 +- .../VBScript/matrix-multiplication.vb | 26 +- .../EasyLang/matrix-transposition.easy | 2 +- .../Uiua/matrix-transposition.uiua | 2 + .../EasyLang/mayan-numerals.easy | 18 +- .../EasyLang/maze-generation.easy | 19 +- Task/Maze-solving/EasyLang/maze-solving.easy | 32 +- Task/Median-filter/Rust/median-filter.rs | 510 ++++++ .../EasyLang/meissel-mertens-constant.easy | 13 +- .../REXX/meissel-mertens-constant.rexx | 12 +- .../merge-and-aggregate-datasets.easy | 14 +- ...c => merge-and-aggregate-datasets-1.basic} | 0 .../merge-and-aggregate-datasets-2.basic | 248 +++ .../Logo/merge-and-aggregate-datasets-1.logo | 87 + .../Logo/merge-and-aggregate-datasets-2.logo | 5 + .../EasyLang/mertens-function.easy | 10 +- .../REXX/mertens-function.rexx | 175 +- .../REXX/miller-rabin-primality-test.rexx | 4 +- .../EasyLang/mind-boggling-card-trick.easy | 26 +- .../EasyLang/minesweeper-game.easy | 108 +- .../modified-random-distribution.easy | 2 +- .../J/monads-maybe-monad-1.j | 2 +- .../EasyLang/monte-carlo-methods.easy | 6 +- Task/Morse-code/EasyLang/morse-code.easy | 2 +- .../{morse-code.java => morse-code-1.java} | 0 Task/Morse-code/Java/morse-code-2.java | 99 ++ .../Motzkin-numbers/REXX/motzkin-numbers.rexx | 73 +- .../EasyLang/mouse-position.easy | 5 +- .../Uxntal/mouse-position.uxnatl | 39 +- .../EasyLang/move-to-front-algorithm.easy | 2 +- .../Zig/move-to-front-algorithm.zig | 78 + .../REXX/multi-base-primes.rexx | 110 +- .../multi-dimensional-array-1.basic | 5 + .../multi-dimensional-array-2.basic | 1 + .../multi-dimensional-array-3.basic | 1 + .../multi-dimensional-array-4.basic | 5 + .../multi-dimensional-array-5.basic | 1 + .../multi-dimensional-array-6.basic | 1 + .../multi-dimensional-array-7.basic | 1 + .../multi-dimensional-array-8.basic | 1 + .../multi-dimensional-array-9.basic | 1 + ...rray.cpp => multi-dimensional-array-1.cpp} | 6 +- .../C++/multi-dimensional-array-2.cpp | 80 + .../EasyLang/multiplication-tables.easy | 10 +- .../Objeck/multiplication-tables.objeck | 25 + Task/Multisplit/EasyLang/multisplit.easy | 2 +- .../J/munchausen-numbers-3.j | 7 + .../Munchausen-numbers/R/munchausen-numbers.r | 10 + .../Arturo/munching-squares.arturo | 9 + .../EasyLang/munching-squares.easy | 9 +- .../Uiua/munching-squares.uiua | 1 + Task/Musical-scale/Java/musical-scale.java | 58 +- .../Musical-scale/JavaScript/musical-scale.js | 68 +- Task/N-queens-problem/C/n-queens-problem-1.c | 13 +- .../N-queens-problem/Jq/n-queens-problem-6.jq | 38 + .../N-queens-problem/Jq/n-queens-problem-7.jq | 13 + .../Python/n-queens-problem-10.py | 13 + .../Python/n-queens-problem-5.py | 1 - .../Python/n-queens-problem-6.py | 33 +- .../Python/n-queens-problem-7.py | 16 +- .../Python/n-queens-problem-8.py | 165 +- .../Python/n-queens-problem-9.py | 180 +- .../REXX/n-smooth-numbers.rexx | 96 +- Task/Natural-sorting/00-TASK.txt | 2 +- .../FreeBASIC/natural-sorting.basic | 156 ++ .../JavaScript/natural-sorting-1.js | 7 + ...atural-sorting.js => natural-sorting-2.js} | 0 Task/Natural-sorting/Rust/natural-sorting.rs | 260 +++ Task/Natural-sorting/Zig/natural-sorting.zig | 571 ++++++ .../EasyLang/negative-base-numbers.easy | 10 +- .../next-highest-int-from-digits.easy | 10 +- .../Crystal/non-decimal-radices-convert.cr | 2 + .../REXX/non-decimal-radices-convert.rexx | 52 +- Task/Nonoblock/EasyLang/nonoblock.easy | 10 +- Task/Nonogram-solver/Rust/nonogram-solver.rs | 241 +++ .../Nth-root/AppleScript/nth-root.applescript | 23 + Task/Nth-root/EasyLang/nth-root.easy | 8 +- Task/Nth-root/REXX/nth-root.rexx | 29 +- .../EasyLang/number-reversal-game.easy | 12 +- ...h-are-not-the-sum-of-distinct-squares.easy | 2 +- .../numbers-with-equal-rises-and-falls.easy | 14 +- ...tegration-gauss-legendre-quadrature-2.rexx | 138 +- ...tegration-gauss-legendre-quadrature-3.rexx | 51 - ...egration.jl => numerical-integration-1.jl} | 0 .../Julia/numerical-integration-2.jl | 24 + .../REXX/numerical-integration.rexx | 152 +- .../EasyLang/odd-word-problem.easy | 10 +- .../R/old-russian-measure-of-length.r | 28 + .../one-dimensional-cellular-automata.easy | 4 +- .../EasyLang/openwebnet-password.easy | 10 +- .../Rust/openwebnet-password.rs | 113 ++ .../Crystal/order-by-pair-comparisons.cr | 17 + .../EasyLang/order-by-pair-comparisons.easy | 2 +- .../Crystal/order-two-numerical-lists.cr | 2 + .../EasyLang/ormiston-triples.easy | 16 +- Task/P-Adic-numbers-basic/00-TASK.txt | 1 - .../C-sharp/p-adic-numbers-basic.cs | 402 +++++ .../JavaScript/p-adic-numbers-basic.js | 310 ++++ .../Rust/p-adic-numbers-basic.rs | 391 +++++ .../Zig/p-adic-numbers-basic.zig | 357 ++++ .../Go/p-adic-square-roots.go | 388 +++++ .../JavaScript/p-adic-square-roots.js | 360 ++++ .../Rust/p-adic-square-roots.rs | 381 ++++ .../Zig/p-adic-square-roots.zig | 495 ++++++ .../padovan-n-step-number-sequences.easy | 10 +- .../PascalABC.NET/pancake-numbers.pas | 37 + .../PascalABC.NET/pangram-checker.pas | 8 + .../Pangram-checker/Uiua/pangram-checker.uiua | 8 + Task/Paraffins/PascalABC.NET/paraffins.pas | 50 + .../PascalABC.NET/parallel-calculations.pas | 24 + Task/Parametric-polymorphism/00-TASK.txt | 2 +- .../C3/parametric-polymorphism-1.c3 | 2 +- .../C3/parametric-polymorphism-2.c3 | 2 +- .../Erlang/parse-an-ip-address.erl | 53 + .../Lua/parse-an-ip-address-1.lua | 158 ++ .../Lua/parse-an-ip-address-2.lua | 6 + .../parsing-rpn-calculator-algorithm.pas | 15 + .../Zig/parsing-rpn-calculator-algorithm.zig | 57 + .../Zig/parsing-shunting-yard-algorithm.zig | 343 ++++ .../EasyLang/particle-fountain.easy | 18 +- ...partition-an-integer-x-into-n-primes.basic | 33 + .../partition-an-integer-x-into-n-primes.easy | 20 +- .../partition-an-integer-x-into-n-primes.pas | 22 + .../partition-an-integer-x-into-n-primes.rexx | 131 +- .../partition-an-integer-x-into-n-primes.raku | 17 +- .../pascal-matrix-generation.pas | 16 + .../PascalABC.NET/pascals-triangle-puzzle.pas | 20 + .../EasyLang/pascals-triangle.easy | 8 +- .../pathological-floating-point-problems.easy | 10 +- .../pathological-floating-point-problems-1.hs | 11 + .../pathological-floating-point-problems-2.hs | 16 + .../pathological-floating-point-problems-3.hs | 30 + .../pathological-floating-point-problems.pas | 45 + Task/Peano-curve/EasyLang/peano-curve.easy | 11 +- .../PascalABC.NET/pells-equation.pas | 31 + Task/Penneys-game/Dart/penneys-game.dart | 89 + Task/Pentagram/EasyLang/pentagram.easy | 21 +- .../percolation-mean-run-density.easy | 6 +- .../REXX/perfect-numbers-1.rexx | 46 +- .../REXX/perfect-numbers-2.rexx | 25 +- .../REXX/perfect-numbers-3.rexx | 36 +- .../REXX/perfect-numbers-4.rexx | 35 +- .../REXX/perfect-numbers-5.rexx | 39 +- .../REXX/perfect-numbers-6.rexx | 40 +- .../REXX/perfect-numbers-7.rexx | 66 +- .../REXX/perfect-numbers-8.rexx | 47 + .../EasyLang/perfect-shuffle.easy | 8 +- .../PascalABC.NET/perfect-shuffle.pas | 19 + .../PascalABC.NET/perfect-totient-numbers.pas | 23 + .../EasyLang/periodic-table.easy | 10 +- .../EasyLang/peripheral-drift-illusion.easy | 19 +- Task/Perlin-noise/EasyLang/perlin-noise.easy | 12 +- Task/Perlin-noise/JavaScript/perlin-noise.js | 80 + .../ALGOL-68/permutation-test.alg | 36 + .../EasyLang/permutation-test.easy | 17 + .../permutation-test-2.m2000 | 22 +- .../PascalABC.NET/permutation-test.pas | 20 + .../EasyLang/permutations-derangements.easy | 16 +- .../permutations-rank-of-a-permutation.easy | 14 +- .../EasyLang/permutations-by-swapping.easy | 2 +- Task/Permutations/C/permutations-1.c | 109 +- Task/Permutations/C/permutations-2.c | 84 +- Task/Permutations/C/permutations-4.c | 100 -- Task/Permutations/EasyLang/permutations.easy | 2 +- Task/Permutations/K/permutations-4.k | 2 +- .../REXX/pernicious-numbers.rexx | 71 +- .../Crystal/phrase-reversals.cr | 5 + Task/Pi/Atari-BASIC/pi.basic | 51 + .../Zig/pick-random-element.zig | 16 +- .../REXX/pierpont-primes-1.rexx | 76 + .../REXX/pierpont-primes-2.rexx | 72 + .../Pierpont-primes/REXX/pierpont-primes.rexx | 36 - .../EasyLang/pig-the-dice-game.easy | 95 +- .../EasyLang/pinstripe-display.easy | 5 +- .../Pisano-period/EasyLang/pisano-period.easy | 58 +- Task/Pisano-period/REXX/pisano-period.rexx | 103 +- .../Plasma-effect/EasyLang/plasma-effect.easy | 8 +- .../JavaScript/playfair-cipher.js | 269 +++ Task/Playfair-cipher/Rust/playfair-cipher.rs | 225 +++ .../Playing-cards/EasyLang/playing-cards.easy | 14 +- .../EasyLang/plot-coordinate-pairs.easy | 38 +- .../REXX/polynomial-long-division-2.rexx | 5 +- .../EasyLang/polynomial-regression.easy | 4 +- .../Rust/polynomial-regression.rs | 41 + .../XPL0/polynomial-regression.xpl0 | 60 + Task/Polyspiral/EasyLang/polyspiral.easy | 21 +- .../EasyLang/population-count.easy | 4 +- Task/Power-set/Crystal/power-set.cr | 14 + .../M2000-Interpreter/power-set.m2000 | 72 + Task/Power-set/Refal/power-set.refal | 15 + .../REXX/primality-by-wilsons-theorem.rexx | 123 +- .../Odin/primality-by-trial-division.odin | 29 + .../primality-by-trial-division.pas | 2 +- .../REXX/primality-by-trial-division-1.rexx | 21 - .../REXX/primality-by-trial-division-2.rexx | 22 - .../REXX/primality-by-trial-division-3.rexx | 49 - .../REXX/primality-by-trial-division.rexx | 90 + ...onspiracy.rexx => prime-conspiracy-1.rexx} | 0 .../REXX/prime-conspiracy-2.rexx | 67 + .../REXX/prime-decomposition-1.rexx | 82 - .../REXX/prime-decomposition-2.rexx | 81 - .../REXX/prime-decomposition-3.rexx | 69 - .../REXX/prime-decomposition-4.rexx | 103 -- .../REXX/prime-decomposition.rexx | 41 + ...ose-neighboring-pairs-are-tetraprimes.easy | 64 + ...e-neighboring-pairs-are-tetraprimes.parigp | 35 + ...whose-neighboring-pairs-are-tetraprimes.py | 195 +++ .../00-TASK.txt | 4 + ...llocate-descendants-to-their-ancestors.alg | 108 ++ ...locate-descendants-to-their-ancestors.easy | 67 + ...locate-descendants-to-their-ancestors.rexx | 126 ++ .../REXX/primorial-numbers.rexx | 31 +- .../EasyLang/probabilistic-choice.easy | 2 +- .../EasyLang/problem-of-apollonius.easy | 29 +- Task/Program-name/Zig/program-name.zig | 13 +- .../OPL/program-termination.opl | 3 + .../ALGOL-60/proper-divisors.alg | 77 + .../REXX/proper-divisors-2.rexx | 102 +- .../REXX/proper-divisors-3.rexx | 46 - .../REXX/proper-divisors-4.rexx | 53 - ...s-combined-recursive-generator-mrg32k3a.rs | 89 + ...udo-random-numbers-middle-square-method.rs | 54 + .../Rust/pseudo-random-numbers-splitmix64.rs | 57 + .../ALGOL-68/pythagoras-tree.alg | 95 + .../EasyLang/pythagoras-tree.easy | 8 +- .../Maple/pythagoras-tree.maple | 23 + .../EasyLang/pythagorean-triples.easy | 2 +- .../QR-decomposition/Rust/qr-decomposition.rs | 591 +++++++ .../Quaternion-type/REXX/quaternion-type.rexx | 83 +- .../EasyLang/queue-definition.easy | 2 +- .../EasyLang/quickselect-algorithm.easy | 7 +- .../Zig/quickselect-algorithm.zig | 69 + Task/Quine/Rust/quine-1.rs | 6 +- Task/Quine/Rust/quine-2.rs | 61 +- Task/Quine/Rust/quine-3.rs | 49 +- Task/Quine/Rust/quine-4.rs | 61 +- Task/Quine/Rust/quine-5.rs | 42 + Task/Quine/V-(Vlang)/quine.v | 3 + Task/Quine/Zig/quine.zig | 6 + .../EasyLang/radical-of-an-integer.easy | 14 +- .../REXX/radical-of-an-integer-2.rexx | 29 +- .../SETL/radical-of-an-integer.setl | 43 + .../EasyLang/ramanujan-primes-twins.easy | 2 +- .../REXX/ramanujan-primes-twins.rexx | 43 + .../REXX/ramanujans-constant.rexx | 66 +- ...r-douglas-peucker-line-simplification.easy | 4 +- ...er-douglas-peucker-line-simplification.lua | 92 + ...r-douglas-peucker-line-simplification.mod2 | 100 ++ .../EasyLang/random-latin-squares.easy | 26 +- .../C/random-number-generator-device--5.c | 82 - .../random-number-generator-device--1.rexx | 5 - .../random-number-generator-device--2.rexx | 14 - .../REXX/random-number-generator-device-.rexx | 38 + .../random-number-generator-included--3.rexx | 2 + .../EasyLang/random-numbers.easy | 2 +- Task/Random-numbers/REXX/random-numbers.rexx | 130 +- .../ALGOL-68/random-sentence-from-book-1.alg | 7 +- .../EasyLang/range-consolidation.easy | 14 +- Task/Rare-numbers/Rust/rare-numbers.rs | 37 +- Task/Rate-counter/EasyLang/rate-counter.easy | 26 +- .../XPL0/read-a-configuration-file.xpl0 | 56 + .../OoRexx/read-entire-file-1.rexx | 11 +- .../OoRexx/read-entire-file-2.rexx | 6 +- .../OoRexx/read-entire-file-3.rexx | 16 +- .../OoRexx/read-entire-file-4.rexx | 9 + .../REXX/real-constants-and-functions-3.rexx | 28 +- .../REXX/real-constants-and-functions-4.rexx | 22 +- .../REXX/real-constants-and-functions-5.rexx | 27 - .../REXX/real-constants-and-functions-6.rexx | 26 - .../REXX/real-constants-and-functions-7.rexx | 14 - .../REXX/real-constants-and-functions-8.rexx | 27 - .../REXX/real-constants-and-functions-9.rexx | 19 - .../EasyLang/reduced-row-echelon-form.easy | 18 +- .../C-sharp/reflection-get-source.cs | 1 + Task/Rendezvous/Rust/rendezvous.rs | 207 +++ .../Excel/repeat-a-string.excel | 1 + Task/Resistor-mesh/Rust/resistor-mesh.rs | 133 ++ .../EasyLang/return-multiple-values.easy | 2 +- ...-a-string.lisp => reverse-a-string-1.lisp} | 0 .../Common-Lisp/reverse-a-string-2.lisp | 15 + .../Excel/reverse-a-string.excel | 1 + .../Objeck/roman-numerals-decode.objeck | 38 + .../EasyLang/roots-of-a-function.easy | 21 +- .../EasyLang/roots-of-unity.easy | 6 +- ...setta-code-find-unimplemented-tasks.objeck | 109 ++ .../rosetta-code-fix-code-tags.basic | 66 + ...ta-code-rank-languages-by-popularity.basic | 88 + ...tta-code-rank-languages-by-popularity-2.py | 8 +- Task/Rot-13/PL-I-80/rot-13.pli | 43 +- .../8080-Assembly/run-length-encoding.8080 | 92 + .../Crystal/run-length-encoding.cr | 19 + .../MACRO-11/run-length-encoding.macro11 | 106 ++ .../Miranda/run-length-encoding.miranda | 18 + .../Refal/run-length-encoding.refal | 44 + Task/Runge-Kutta-method/00-TASK.txt | 10 +- .../EasyLang/runge-kutta-method.easy | 2 +- .../Odin/runge-kutta-method.odin | 37 + .../Ol/runge-kutta-method.ol | 57 + .../Scheme/runge-kutta-method.scm | 54 + .../EasyLang/ruth-aaron-numbers.easy | 2 +- Task/SHA-1/JavaScript/sha-1.js | 164 ++ Task/SHA-1/Zig/sha-1.zig | 126 ++ .../FreeBASIC/sql-based-authentication.basic | 91 + .../safe-primes-and-unsafe-primes.easy | 20 +- .../REXX/safe-primes-and-unsafe-primes.rexx | 120 +- .../EasyLang/self-describing-numbers.easy | 16 +- Task/Self-numbers/EasyLang/self-numbers.easy | 10 +- Task/Semiprime/REXX/semiprime-2.rexx | 69 +- Task/Semiprime/REXX/semiprime-3.rexx | 41 - Task/Semiprime/REXX/semiprime-4.rexx | 57 - Task/Semordnilap/R/semordnilap.r | 17 + .../sequence-of-primes-by-trial-division.alg | 46 + .../sequence-of-primes-by-trial-division.easy | 21 +- .../sequence-of-primes-by-trial-division.pas | 2 +- ...equence-of-primes-by-trial-division-1.rexx | 18 - ...equence-of-primes-by-trial-division-2.rexx | 27 - .../sequence-of-primes-by-trial-division.rexx | 78 + .../REXX/sequence-of-primorial-primes.rexx | 50 + ...smallest-number-with-exactly-n-divisors.cs | 102 ++ Task/Set-puzzle/EasyLang/set-puzzle.easy | 24 +- Task/Set-puzzle/JavaScript/set-puzzle.js | 86 + .../EasyLang/set-right-adjacent-bits.easy | 2 +- ...seven-sided-dice-from-five-sided-dice.easy | 8 +- Task/Sexy-primes/EasyLang/sexy-primes.easy | 6 +- Task/Sexy-primes/REXX/sexy-primes.rexx | 153 +- .../shoelace-formula-for-polygonal-area.easy | 8 +- .../shoelace-formula-for-polygonal-area.rs | 25 + .../EasyLang/show-ascii-table.easy | 2 +- .../EasyLang/sierpinski-arrowhead-curve.easy | 9 +- .../EasyLang/sierpinski-carpet.easy | 11 +- .../EasyLang/sierpinski-pentagon.easy | 10 +- .../EasyLang/sierpinski-square-curve.easy | 11 +- .../sierpinski-triangle-graphical.easy | 5 +- .../Uxntal/sierpinski-triangle.uxnatl | 36 +- .../PascalABC.NET/sieve-of-eratosthenes.pas | 2 +- .../REXX/sieve-of-eratosthenes-1.rexx | 41 +- .../REXX/sieve-of-eratosthenes-2.rexx | 90 +- .../REXX/sieve-of-eratosthenes-3.rexx | 16 - .../REXX/sieve-of-eratosthenes-4.rexx | 29 - .../EasyLang/sieve-of-pritchard.easy | 18 +- .../REXX/sieve-of-pritchard.rexx | 95 + .../M2000-Interpreter/simple-database.m2000 | 2 +- .../EasyLang/simple-turtle-graphics.easy | 17 +- .../simple-turtle-graphics.m2000 | 69 + .../Raku/simple-turtle-graphics.raku | 54 + .../FreeBASIC/simulate-input-keyboard.basic | 40 + .../ALGOL-68/sisyphus-sequence.alg | 14 +- .../EasyLang/sisyphus-sequence.easy | 16 +- .../Mathematica/sisyphus-sequence.math | 33 + Task/Sleep/JavaScript/sleep-1.js | 11 + Task/Sleep/JavaScript/sleep-2.js | 14 + Task/Sleep/JavaScript/sleep-3.js | 8 + Task/Sleep/JavaScript/sleep.js | 9 - Task/Sleep/REXX/sleep-3.rexx | 8 +- .../smarandache-prime-digital-sequence.rexx | 95 +- Task/Snake/EasyLang/snake.easy | 87 +- .../EasyLang/solve-a-hidato-puzzle.easy | 22 +- .../JavaScript/solve-a-hidato-puzzle.js | 113 ++ .../EasyLang/solve-a-holy-knights-tour.easy | 14 +- .../Rust/solve-a-holy-knights-tour.rs | 188 ++ .../Zig/solve-a-holy-knights-tour.zig | 208 +++ .../EasyLang/solve-a-hopido-puzzle.easy | 14 +- .../Rust/solve-a-hopido-puzzle.rs | 258 +++ .../ALGOL-68/solve-a-numbrix-puzzle.alg | 132 ++ .../EasyLang/solve-a-numbrix-puzzle.easy | 76 + .../JavaScript/solve-a-numbrix-puzzle.js | 110 ++ .../Rust/solve-a-numbrix-puzzle.rs | 205 +++ .../Zkl/solve-a-numbrix-puzzle-1.zkl | 20 +- .../Zkl/solve-a-numbrix-puzzle-2.zkl | 17 +- .../solve-the-no-connection-puzzle.alg | 90 + .../solve-the-no-connection-puzzle.easy | 23 + .../APL/sort-a-list-of-object-identifiers.apl | 1 + .../sort-a-list-of-object-identifiers.easy | 22 +- .../sort-an-array-of-composite-structures.cr | 11 + ...ort-an-array-of-composite-structures.m2000 | 2 +- ...rt-an-array-of-composite-structures-2.rexx | 12 +- ...rt-an-array-of-composite-structures-3.rexx | 124 -- ...rt-an-array-of-composite-structures-4.rexx | 173 -- .../EasyLang/sort-an-integer-array.easy | 10 +- .../sort-an-outline-at-every-level.easy | 12 +- .../Crystal/sort-numbers-lexicographically.cr | 2 + .../R/sort-numbers-lexicographically.r | 6 + .../Crystal/sort-three-variables.cr | 14 + .../EasyLang/sort-three-variables.easy | 28 +- .../XPL0/sort-three-variables.xpl0 | 31 + .../Crystal/sorting-algorithms-circle-sort.cr | 35 + .../Rust/sorting-algorithms-bead-sort.rs | 37 + .../EasyLang/sorting-algorithms-bogosort.easy | 17 +- .../Crystal/sorting-algorithms-bubble-sort.cr | 17 + .../sorting-algorithms-bubble-sort.easy | 6 +- .../sorting-algorithms-cocktail-sort.easy | 2 +- .../sorting-algorithms-comb-sort.easy | 2 +- .../sorting-algorithms-counting-sort.easy | 6 +- .../sorting-algorithms-gnome-sort.easy | 2 +- .../EasyLang/sorting-algorithms-heapsort.easy | 10 +- .../REXX/sorting-algorithms-heapsort-1.rexx | 94 +- .../REXX/sorting-algorithms-heapsort-2.rexx | 124 +- .../REXX/sorting-algorithms-heapsort-3.rexx | 56 - .../sorting-algorithms-insertion-sort.easy | 2 +- .../sorting-algorithms-merge-sort.easy | 10 +- .../REXX/sorting-algorithms-merge-sort-3.rexx | 8 +- .../ZED/sorting-algorithms-merge-sort.zed | 90 +- .../sorting-algorithms-pancake-sort.easy | 4 +- .../sorting-algorithms-patience-sort.easy | 29 + .../Rust/sorting-algorithms-patience-sort.rs | 95 + .../Zig/sorting-algorithms-patience-sort.zig | 138 ++ .../sorting-algorithms-permutation-sort.easy | 31 +- .../sorting-algorithms-quicksort.easy | 26 +- .../K/sorting-algorithms-quicksort-8.k | 1 + .../REXX/sorting-algorithms-quicksort-1.rexx | 194 +-- .../REXX/sorting-algorithms-quicksort-2.rexx | 111 +- .../REXX/sorting-algorithms-quicksort-3.rexx | 36 +- .../REXX/sorting-algorithms-quicksort-4.rexx | 68 +- .../REXX/sorting-algorithms-quicksort-5.rexx | 198 ++- .../REXX/sorting-algorithms-quicksort-6.rexx | 73 - .../sorting-algorithms-radix-sort.easy | 12 +- .../sorting-algorithms-radix-sort.js | 60 + ....rs => sorting-algorithms-radix-sort-1.rs} | 6 +- .../Rust/sorting-algorithms-radix-sort-2.rs | 24 + .../Rust/sorting-algorithms-radix-sort-3.rs | 40 + .../sorting-algorithms-selection-sort.easy | 10 +- .../sorting-algorithms-shell-sort.easy | 2 +- .../sorting-algorithms-sleep-sort-1.js | 10 +- .../sorting-algorithms-sleep-sort-2.js | 2 +- .../sorting-algorithms-stooge-sort.easy | 10 +- .../sorting-algorithms-strand-sort.easy | 6 +- .../sorting-algorithms-strand-sort.basic | 100 ++ .../sorting-algorithms-strand-sort.m2000 | 68 + .../Rust/sorting-algorithms-strand-sort.rs | 153 ++ .../Zig/sorting-algorithms-strand-sort.zig | 190 ++ .../JavaScript/spelling-of-ordinal-numbers.js | 163 ++ .../Mathematica/sphenic-numbers.math | 3 + .../EasyLang/spinning-rod-animation-text.easy | 5 +- .../Spiral-matrix/EasyLang/spiral-matrix.easy | 8 +- Task/Spiral-matrix/Uiua/spiral-matrix.uiua | 5 + ...r-string-based-on-change-of-character-1.c} | 0 ...er-string-based-on-change-of-character-2.c | 32 + ...ter-string-based-on-change-of-character.cr | 6 + ...cter-string-based-on-change-of-character.l | 29 + ...-string-based-on-change-of-character.m2000 | 24 + ...r-string-based-on-change-of-character-1.rs | 64 +- ...r-string-based-on-change-of-character-2.rs | 22 +- ...r-string-based-on-change-of-character-3.rs | 14 + ...r-string-based-on-change-of-character-4.rs | 2 + ...r-string-based-on-change-of-character-5.rs | 9 + ...r-string-based-on-change-of-character-6.rs | 9 + ...r-string-based-on-change-of-character-7.rs | 5 + .../Python/square-form-factorization.py | 110 ++ .../REXX/square-form-factorization.rexx | 148 +- .../EasyLang/square-free-integers.easy | 2 +- .../PL-I-80/square-free-integers.pli | 6 +- .../REXX/square-free-integers.rexx | 113 +- .../EasyLang/stable-marriage-problem.easy | 10 +- Task/Stack-traces/Crystal/stack-traces.cr | 15 + Task/Stack-traces/Uxntal/stack-traces.uxnatl | 51 + Task/Stack/68000-Assembly/stack-1.68000 | 5 +- Task/Stack/Ballerina/stack-1.ballerina | 15 + Task/Stack/Ballerina/stack-2.ballerina | 53 + Task/Stack/C/stack-1.c | 56 +- Task/Stack/EasyLang/stack.easy | 6 +- .../EasyLang/stair-climbing-puzzle.easy | 2 +- .../EasyLang/start-from-a-main-routine.easy | 2 +- .../JavaScript/state-name-puzzle.js | 76 + .../Ballerina/statistics-basic.ballerina | 44 + .../EasyLang/statistics-basic.easy | 20 +- .../EasyLang/steffensens-method.easy | 8 +- .../Rust/steffensens-method.rs | 69 + .../EasyLang/stem-and-leaf-plot.easy | 17 +- .../Uiua/stem-and-leaf-plot.uiua | 2 +- .../EasyLang/stern-brocot-sequence.easy | 2 +- Task/Strassens-algorithm/00-TASK.txt | 2 + .../C++/strassens-algorithm.cpp | 248 +++ .../C-sharp/strassens-algorithm.cs | 323 ++++ .../Java/strassens-algorithm.java | 281 +++ .../JavaScript/strassens-algorithm-1.js | 318 ++++ .../JavaScript/strassens-algorithm-2.js | 316 ++++ .../Rust/strassens-algorithm.rs | 269 +++ .../Zig/strassens-algorithm.zig | 477 +++++ Task/Stream-merge/Rust/stream-merge.rs | 81 + .../JavaScript/string-concatenation.js | 2 +- .../Uxntal/string-concatenation.uxnatl | 31 +- Task/String-length/Crystal/string-length-1.cr | 2 +- Task/String-length/Crystal/string-length-2.cr | 2 +- Task/String-length/Crystal/string-length-3.cr | 1 + .../String-length/Uxntal/string-length.uxnatl | 31 + Task/String-prepend/Crystal/string-prepend.cr | 3 + Task/String-prepend/OPL/string-prepend.opl | 7 + ...p-a-set-of-characters-from-a-string-4.java | 13 + ...ip-a-set-of-characters-from-a-string.m2000 | 1 + ...p-a-set-of-characters-from-a-string.objeck | 17 + ...rip-a-set-of-characters-from-a-string.odin | 16 + .../strip-a-set-of-characters-from-a-string.r | 16 + ...rip-a-set-of-characters-from-a-string-1.rs | 6 +- ...rip-a-set-of-characters-from-a-string-2.rs | 11 +- ...rip-a-set-of-characters-from-a-string-3.rs | 5 +- ...rip-a-set-of-characters-from-a-string-4.rs | 13 + .../APL/strip-comments-from-a-string.apl | 1 + .../Emacs-Lisp/strip-comments-from-a-string.l | 5 + .../Refal/strip-comments-from-a-string.refal | 23 + .../SETL/strip-comments-from-a-string.setl | 13 + ...s-and-extended-characters-from-a-string.rs | 2 +- ...hitespace-from-a-string-top-and-tail-1.cpp | 47 + ...itespace-from-a-string-top-and-tail-2.cpp} | 8 +- .../EasyLang/strong-and-weak-primes.easy | 8 +- .../REXX/strong-and-weak-primes.rexx | 103 +- Task/Subleq/EasyLang/subleq.easy | 6 +- .../EasyLang/substitution-cipher.easy | 6 +- .../JavaScript/substitution-cipher.js | 30 + Task/Substring/K/substring.k | 32 + .../EasyLang/subtractive-generator.easy | 6 +- .../successive-prime-differences.easy | 30 +- .../REXX/successive-prime-differences.rexx | 97 +- Task/Sudan-function/Rust/sudan-function.rs | 15 + Task/Sudoku/EasyLang/sudoku.easy | 6 +- ...teger.nu => sum-digits-of-an-integer-1.nu} | 0 .../Nu/sum-digits-of-an-integer-2.nu | 13 + .../ALGOL-60/sum-of-a-series-1.alg | 10 + .../ALGOL-60/sum-of-a-series-2.alg | 24 + .../ALGOL-60/sum-of-a-series.alg | 18 - .../EasyLang/sum-of-a-series.easy | 2 +- .../S-BASIC/sum-of-a-series.basic | 11 + .../TypeScript/sum-of-a-series.ts | 5 + ...lements-below-main-diagonal-of-matrix.easy | 7 +- ...nts-below-main-diagonal-of-matrix.quackery | 10 + Task/Sum-to-100/EasyLang/sum-to-100.easy | 4 +- Task/Superellipse/EasyLang/superellipse.easy | 10 +- .../sutherland-hodgman-polygon-clipping.zig | 151 ++ .../EasyLang/sylvesters-sequence.easy | 2 +- .../Crystal/take-notes-on-the-command-line.cr | 9 + .../{tau-number.rexx => tau-number-1.rexx} | 0 Task/Tau-number/REXX/tau-number-2.rexx | 34 + .../terminal-control-clear-the-screen.x86-64 | 17 + .../EasyLang/test-integerness.easy | 6 +- .../Lua/text-processing-1.lua | 11 +- .../XPL0/text-processing-1.xpl0 | 49 + .../ALGOL-68/text-processing-2.alg | 164 ++ .../FreeBASIC/text-processing-2.basic | 128 ++ .../Lua/text-processing-2.lua | 5 +- .../XPL0/text-processing-2.xpl0 | 42 + .../text-processing-max-licenses-in-use.lua | 21 +- .../The-Name-Game/EasyLang/the-name-game.easy | 2 +- .../EasyLang/the-sieve-of-sundaram.easy | 2 +- .../REXX/the-sieve-of-sundaram.rexx | 93 +- .../Fortran/thieles-interpolation-formula.f | 87 + Task/Thue-Morse/Zig/thue-morse.zig | 16 + Task/Tic-tac-toe/APL/tic-tac-toe-1.apl | 7 + Task/Tic-tac-toe/APL/tic-tac-toe-2.apl | 1 + Task/Tic-tac-toe/EasyLang/tic-tac-toe.easy | 96 +- Task/Tic-tac-toe/Factor/tic-tac-toe-1.factor | 22 + Task/Tic-tac-toe/Factor/tic-tac-toe-2.factor | 27 + Task/Tic-tac-toe/J/tic-tac-toe-1.j | 16 +- Task/Tic-tac-toe/J/tic-tac-toe-2.j | 9 +- Task/Tic-tac-toe/J/tic-tac-toe-3.j | 2 +- Task/Tic-tac-toe/J/tic-tac-toe-4.j | 14 + Task/Tic-tac-toe/JavaScript/tic-tac-toe-3.js | 96 ++ Task/Time-a-function/Lua/time-a-function.lua | 20 +- .../REXX/time-a-function-2.rexx | 508 +++++- .../REXX/time-a-function-3.rexx | 27 - .../REXX/time-a-function-4.rexx | 485 ------ ... => tokenize-a-string-with-escaping-1.lua} | 12 +- .../Lua/tokenize-a-string-with-escaping-2.lua | 11 + .../Lua/tokenize-a-string-with-escaping-3.lua | 4 + .../Excel/tokenize-a-string-1.excel | 1 + .../Excel/tokenize-a-string-2.excel | 1 + .../Zig/tokenize-a-string.zig | 2 +- .../JavaScript/tonelli-shanks-algorithm.js | 113 ++ .../Rust/tonelli-shanks-algorithm.rs | 120 ++ .../Zig/tonelli-shanks-algorithm.zig | 128 ++ .../EasyLang/top-rank-per-group.easy | 4 +- .../EasyLang/total-circles-area.easy | 2 +- .../EasyLang/totient-function.easy | 2 +- .../REXX/totient-function-1.rexx | 24 - .../REXX/totient-function-2.rexx | 25 - .../REXX/totient-function-3.rexx | 137 -- .../REXX/totient-function.rexx | 99 ++ .../Applesoft-BASIC/towers-of-hanoi.basic | 27 + .../Ballerina/towers-of-hanoi.ballerina | 26 + .../EasyLang/towers-of-hanoi.easy | 4 +- .../Excel/towers-of-hanoi-3.excel | 11 + .../Uxntal/towers-of-hanoi.uxnatl | 30 +- .../EasyLang/tree-traversal.easy | 28 +- .../EasyLang/trigonometric-functions.easy | 2 +- .../REXX/trigonometric-functions-1.rexx | 81 - ...ns-2.rexx => trigonometric-functions.rexx} | 4 +- .../Ballerina/truncatable-primes.ballerina | 90 + ...-primes.rexx => truncatable-primes-1.rexx} | 0 .../REXX/truncatable-primes-2.rexx | 50 + Task/Twin-primes/REXX/twin-primes-1.rexx | 26 - Task/Twin-primes/REXX/twin-primes-2.rexx | 33 - Task/Twin-primes/REXX/twin-primes.rexx | 33 + .../EasyLang/two-bullet-roulette.easy | 30 +- .../Quackery/two-bullet-roulette.quackery | 35 + Task/UPC/EasyLang/upc.easy | 4 +- .../K/utf-8-encode-and-decode.k | 4 + ...ukkonen-s-suffix-tree-construction-1.basic | 151 ++ ...ukkonen-s-suffix-tree-construction-2.basic | 295 ++++ .../ukkonen-s-suffix-tree-construction.js | 196 +++ .../ukkonen-s-suffix-tree-construction.rs | 250 +++ .../EasyLang/ulam-spiral-for-primes-.easy | 42 +- .../REXX/ulam-spiral-for-primes--1.rexx | 48 - .../REXX/ulam-spiral-for-primes--2.rexx | 48 - .../REXX/ulam-spiral-for-primes-.rexx | 98 ++ Task/Unicode-strings/Tcl/unicode-strings.tcl | 52 + .../unicode-variable-names.ballerina | 7 + .../Odin/unicode-variable-names.odin | 11 + .../Scheme/unicode-variable-names.scm | 4 + .../EasyLang/universal-turing-machine.easy | 24 +- .../EasyLang/unprimeable-numbers.easy | 36 + .../REXX/unprimeable-numbers.rexx | 158 +- .../REXX/untouchable-numbers.rexx | 149 +- .../Lua/update-a-configuration-file.lua | 71 + .../JavaScript/user-input-text-3.js | 16 + Task/User-input-Text/Lua/user-input-text.lua | 2 +- Task/User-input-Text/OPL/user-input-text.opl | 30 + ...ional-securities-identification-number.lua | 31 +- .../EasyLang/vampire-number.easy | 12 +- Task/Vampire-number/Raku/vampire-number.raku | 17 +- Task/Variables/EasyLang/variables.easy | 2 +- .../Vector-products/REXX/vector-products.rexx | 54 +- Task/Vector/REXX/vector.rexx | 72 +- .../JavaScript/verhoeff-algorithm.js | 80 + .../Rust/verhoeff-algorithm.rs | 98 ++ ...tribution-uniformity-chi-squared-test.rexx | 138 +- .../verify-distribution-uniformity-naive.easy | 8 +- .../verify-distribution-uniformity-naive.rexx | 108 +- .../vigen-re-cipher-cryptanalysis.js | 190 ++ .../EasyLang/vogels-approximation-method.easy | 2 +- .../Fortran/vogels-approximation-method.f | 96 ++ .../JavaScript/vogels-approximation-method.js | 290 ++++ .../EasyLang/voronoi-diagram.easy | 10 +- .../EasyLang/wagstaff-primes.easy | 8 +- .../Mathematica/wagstaff-primes.math | 40 + ...asteful-equidigital-and-frugal-numbers.alg | 64 + ...steful-equidigital-and-frugal-numbers.easy | 56 + ...wasteful-equidigital-and-frugal-numbers.py | 272 +++ .../Weird-numbers/EasyLang/weird-numbers.easy | 26 +- .../Weird-numbers/YAMLScript/weird-numbers.ys | 2 +- ...ch-primes.rexx => wieferich-primes-1.rexx} | 0 .../REXX/wieferich-primes-2.rexx | 40 + .../REXX/wilson-primes-of-order-n-1.rexx | 58 + .../REXX/wilson-primes-of-order-n-2.rexx | 61 + .../REXX/wilson-primes-of-order-n.rexx | 47 - Task/Wireworld/EasyLang/wireworld.easy | 43 +- .../Emacs-Lisp/word-frequency.l | 28 + Task/Word-frequency/Nu/word-frequency.nu | 8 + Task/Word-frequency/Perl/word-frequency.pl | 2 +- Task/Word-ladder/EasyLang/word-ladder.easy | 2 +- Task/Word-ladder/FreeBASIC/word-ladder.basic | 147 ++ Task/Wordiff/JavaScript/wordiff.js | 200 +++ .../Odin/write-entire-file.odin | 11 + .../write-float-arrays-to-a-text-file.alg | 73 +- ...te-float-arrays-to-a-text-file.applescript | 60 + .../K/write-float-arrays-to-a-text-file.k | 16 + .../Rust/xiaolin-wus-line-algorithm.rs | 120 ++ Task/Y-combinator/Elm/y-combinator.elm | 69 +- Task/Y-combinator/F-Sharp/y-combinator-1.fs | 12 +- Task/Y-combinator/F-Sharp/y-combinator-2.fs | 42 +- Task/Y-combinator/F-Sharp/y-combinator-3.fs | 43 +- Task/Y-combinator/F-Sharp/y-combinator-4.fs | 42 +- Task/Y-combinator/F-Sharp/y-combinator-5.fs | 4 + Task/Y-combinator/J/y-combinator-1.j | 2 +- Task/Y-combinator/J/y-combinator-3.j | 4 +- Task/Y-combinator/J/y-combinator-6.j | 4 +- Task/Y-combinator/Zig/y-combinator.zig | 71 + .../EasyLang/yellowstone-sequence.easy | 16 +- .../REXX/yellowstone-sequence-1.rexx | 20 - .../REXX/yellowstone-sequence-2.rexx | 21 - .../REXX/yellowstone-sequence.rexx | 56 + Task/Yin-and-yang/EasyLang/yin-and-yang.easy | 29 +- Task/Zebra-puzzle/J/zebra-puzzle-1.j | 30 +- Task/Zebra-puzzle/JavaScript/zebra-puzzle.js | 163 ++ .../zeckendorf-number-representation.easy | 6 +- .../EasyLang/zig-zag-matrix.easy | 2 +- Task/Zig-zag-matrix/Uiua/zig-zag-matrix.uiua | 7 + .../EasyLang/zumkeller-numbers.easy | 30 +- 2347 files changed, 62432 insertions(+), 16731 deletions(-) create mode 120000 Lang/8080-Assembly/Loops-Infinite create mode 120000 Lang/8080-Assembly/Run-length-encoding create mode 120000 Lang/ALGOL-60/Additive-primes create mode 120000 Lang/ALGOL-60/Largest-proper-divisor-of-n create mode 120000 Lang/ALGOL-60/Loops-Increment-loop-index-within-loop-body create mode 120000 Lang/ALGOL-60/Proper-divisors create mode 120000 Lang/ALGOL-60/Sequence-of-primes-by-trial-division create mode 120000 Lang/ALGOL-68/Elliptic-curve-arithmetic create mode 120000 Lang/ALGOL-68/Permutation-test create mode 120000 Lang/ALGOL-68/Primes---allocate-descendants-to-their-ancestors create mode 120000 Lang/ALGOL-68/Pythagoras-tree create mode 120000 Lang/ALGOL-68/Solve-a-Numbrix-puzzle create mode 120000 Lang/ALGOL-68/Solve-the-no-connection-puzzle create mode 120000 Lang/ALGOL-68/Text-processing-2 create mode 120000 Lang/ALGOL-68/Wasteful-equidigital-and-frugal-numbers create mode 120000 Lang/ALGOL-M/Additive-primes create mode 120000 Lang/ANSI-BASIC/Levenshtein-distance create mode 120000 Lang/ANSI-BASIC/M-bius-function create mode 120000 Lang/ANSI-BASIC/Magic-constant create mode 120000 Lang/ANSI-BASIC/Map-range create mode 120000 Lang/APL/Loops-Infinite create mode 120000 Lang/APL/Sort-a-list-of-object-identifiers create mode 120000 Lang/APL/Strip-comments-from-a-string create mode 120000 Lang/APL/Tic-tac-toe create mode 120000 Lang/ASIC/M-bius-function create mode 120000 Lang/Ada/Cistercian-numerals create mode 120000 Lang/Ada/Curzon-numbers create mode 120000 Lang/AppleScript/Bin-given-limits create mode 120000 Lang/AppleScript/Nth-root create mode 120000 Lang/AppleScript/Write-float-arrays-to-a-text-file create mode 120000 Lang/Applesoft-BASIC/Cistercian-numerals create mode 120000 Lang/Applesoft-BASIC/Formatted-numeric-output create mode 120000 Lang/Applesoft-BASIC/Levenshtein-distance create mode 120000 Lang/Applesoft-BASIC/Multi-dimensional-array create mode 120000 Lang/Applesoft-BASIC/Towers-of-Hanoi create mode 120000 Lang/Arturo/Arithmetic-derivative create mode 120000 Lang/Arturo/Dice-game-probabilities create mode 120000 Lang/Arturo/Element-wise-operations create mode 120000 Lang/Arturo/Entropy-Narcissist create mode 120000 Lang/Arturo/Munching-squares create mode 120000 Lang/Asymptote/Evaluate-binomial-coefficients create mode 120000 Lang/Atari-BASIC/Pi create mode 100644 Lang/AutoHotKey-V2/00-LANG.txt create mode 100644 Lang/AutoHotKey-V2/00-META.yaml create mode 120000 Lang/AutoHotKey-V2/Hello-world-Graphical delete mode 100644 Lang/Autohotkey-V2/00-LANG.txt delete mode 100644 Lang/Autohotkey-V2/00-META.yaml delete mode 120000 Lang/Autohotkey-V2/Hello-world-Graphical create mode 120000 Lang/BASIC/Partition-an-integer-x-into-n-primes create mode 120000 Lang/BASIC256/Evaluate-binomial-coefficients create mode 120000 Lang/BQN/Find-common-directory-path create mode 120000 Lang/BQN/Globally-replace-text-in-several-files create mode 120000 Lang/Ballerina/A+B create mode 120000 Lang/Ballerina/ABC-problem create mode 120000 Lang/Ballerina/AKS-test-for-primes create mode 120000 Lang/Ballerina/Abundant-deficient-and-perfect-number-classifications create mode 120000 Lang/Ballerina/Abundant-odd-numbers create mode 120000 Lang/Ballerina/Accumulator-factory create mode 120000 Lang/Ballerina/Achilles-numbers create mode 120000 Lang/Ballerina/Ackermann-function create mode 120000 Lang/Ballerina/Add-a-variable-to-a-class-instance-at-runtime create mode 120000 Lang/Ballerina/Additive-primes create mode 120000 Lang/Ballerina/Address-of-a-variable create mode 120000 Lang/Ballerina/Almost-prime create mode 120000 Lang/Ballerina/Amb create mode 120000 Lang/Ballerina/Angle-difference-between-two-bearings create mode 120000 Lang/Ballerina/Anti-primes create mode 120000 Lang/Ballerina/Apply-a-callback-to-an-array create mode 120000 Lang/Ballerina/Approximate-equality create mode 120000 Lang/Ballerina/Arithmetic-Complex create mode 120000 Lang/Ballerina/Arithmetic-Integer create mode 120000 Lang/Ballerina/Arithmetic-Rational create mode 120000 Lang/Ballerina/Arithmetic-numbers create mode 120000 Lang/Ballerina/Array-concatenation create mode 120000 Lang/Ballerina/Array-length create mode 120000 Lang/Ballerina/Arrays create mode 120000 Lang/Ballerina/Ascending-primes create mode 120000 Lang/Ballerina/Associative-array-Creation create mode 120000 Lang/Ballerina/Associative-array-Iteration create mode 120000 Lang/Ballerina/Associative-array-Merging create mode 120000 Lang/Ballerina/Averages-Arithmetic-mean create mode 120000 Lang/Ballerina/Averages-Mean-angle create mode 120000 Lang/Ballerina/Averages-Mean-time-of-day create mode 120000 Lang/Ballerina/Averages-Median create mode 120000 Lang/Ballerina/Averages-Mode create mode 120000 Lang/Ballerina/Averages-Pythagorean-means create mode 120000 Lang/Ballerina/Averages-Root-mean-square create mode 120000 Lang/Ballerina/Averages-Simple-moving-average create mode 120000 Lang/Ballerina/Balanced-brackets create mode 120000 Lang/Ballerina/Boolean-values create mode 120000 Lang/Ballerina/Caesar-cipher create mode 120000 Lang/Ballerina/Calculating-the-value-of-e create mode 120000 Lang/Ballerina/Case-sensitivity-of-identifiers create mode 120000 Lang/Ballerina/Character-codes create mode 120000 Lang/Ballerina/Classes create mode 120000 Lang/Ballerina/Count-in-octal create mode 120000 Lang/Ballerina/Currency create mode 120000 Lang/Ballerina/Currying create mode 120000 Lang/Ballerina/Dynamic-variable-names create mode 120000 Lang/Ballerina/Empty-string create mode 120000 Lang/Ballerina/Extreme-floating-point-values create mode 120000 Lang/Ballerina/Farey-sequence create mode 120000 Lang/Ballerina/Find-limit-of-recursion create mode 120000 Lang/Ballerina/Fivenum create mode 120000 Lang/Ballerina/Floyds-triangle create mode 120000 Lang/Ballerina/Four-bit-adder create mode 120000 Lang/Ballerina/Function-definition create mode 120000 Lang/Ballerina/Gapful-numbers create mode 120000 Lang/Ballerina/Greatest-subsequential-sum create mode 120000 Lang/Ballerina/Hailstone-sequence create mode 120000 Lang/Ballerina/Hello-world-Newline-omission create mode 120000 Lang/Ballerina/Hello-world-Standard-error create mode 120000 Lang/Ballerina/Levenshtein-distance create mode 120000 Lang/Ballerina/Loop-over-multiple-arrays-simultaneously create mode 120000 Lang/Ballerina/Loops-Break create mode 120000 Lang/Ballerina/Loops-Continue create mode 120000 Lang/Ballerina/Loops-Do-while create mode 120000 Lang/Ballerina/Loops-Downward-for create mode 120000 Lang/Ballerina/Loops-For create mode 120000 Lang/Ballerina/Loops-For-with-a-specified-step create mode 120000 Lang/Ballerina/Loops-Foreach create mode 120000 Lang/Ballerina/Loops-Increment-loop-index-within-loop-body create mode 120000 Lang/Ballerina/Loops-Infinite create mode 120000 Lang/Ballerina/Loops-N-plus-one-half create mode 120000 Lang/Ballerina/Loops-Nested create mode 120000 Lang/Ballerina/Loops-With-multiple-ranges create mode 120000 Lang/Ballerina/Loops-Wrong-ranges create mode 120000 Lang/Ballerina/Stack create mode 120000 Lang/Ballerina/Statistics-Basic create mode 120000 Lang/Ballerina/Towers-of-Hanoi create mode 120000 Lang/Ballerina/Truncatable-primes create mode 120000 Lang/Ballerina/Unicode-variable-names create mode 120000 Lang/C++/Currency create mode 120000 Lang/C++/Strassens-algorithm create mode 120000 Lang/C-sharp/ADFGVX-cipher create mode 120000 Lang/C-sharp/ASCII-art-diagram-converter create mode 120000 Lang/C-sharp/Arithmetic-derivative create mode 120000 Lang/C-sharp/Boyer-Moore-string-search create mode 120000 Lang/C-sharp/Calkin-Wilf-sequence create mode 120000 Lang/C-sharp/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n- create mode 120000 Lang/C-sharp/Elliptic-Curve-Digital-Signature-Algorithm create mode 120000 Lang/C-sharp/Execute-a-Markov-algorithm create mode 120000 Lang/C-sharp/Extensible-prime-generator create mode 120000 Lang/C-sharp/File-extension-is-in-extensions-list create mode 120000 Lang/C-sharp/Find-if-a-point-is-within-a-triangle create mode 120000 Lang/C-sharp/Gotchas create mode 120000 Lang/C-sharp/Index-finite-lists-of-positive-integers create mode 120000 Lang/C-sharp/K-d-tree create mode 120000 Lang/C-sharp/Longest-string-challenge create mode 120000 Lang/C-sharp/P-Adic-numbers-basic create mode 120000 Lang/C-sharp/Reflection-Get-source create mode 120000 Lang/C-sharp/Sequence:-smallest-number-with-exactly-n-divisors create mode 120000 Lang/C-sharp/Strassens-algorithm create mode 120000 Lang/C/Color-wheel create mode 120000 Lang/C/Magic-constant create mode 120000 Lang/C3/Binary-digits create mode 120000 Lang/Chipmunk-Basic/Evaluate-binomial-coefficients create mode 120000 Lang/Crystal/Abbreviations-easy create mode 120000 Lang/Crystal/Anagrams-Deranged-anagrams create mode 120000 Lang/Crystal/Arithmetic-Complex create mode 120000 Lang/Crystal/Arithmetic-geometric-mean create mode 120000 Lang/Crystal/Averages-Mode create mode 120000 Lang/Crystal/Averages-Pythagorean-means create mode 120000 Lang/Crystal/Bin-given-limits create mode 120000 Lang/Crystal/Character-codes create mode 120000 Lang/Crystal/Cistercian-numerals create mode 120000 Lang/Crystal/Closures-Value-capture create mode 120000 Lang/Crystal/Comma-quibbling create mode 120000 Lang/Crystal/Convert-seconds-to-compound-duration create mode 120000 Lang/Crystal/Determine-if-a-string-has-all-the-same-characters create mode 120000 Lang/Crystal/Determine-if-a-string-is-collapsible create mode 120000 Lang/Crystal/Dijkstras-algorithm create mode 120000 Lang/Crystal/Dutch-national-flag-problem create mode 120000 Lang/Crystal/Execute-Brain- create mode 120000 Lang/Crystal/Hello-world-Standard-error create mode 120000 Lang/Crystal/Hex-words create mode 120000 Lang/Crystal/Increment-a-numerical-string create mode 120000 Lang/Crystal/Interactive-programming-repl- create mode 120000 Lang/Crystal/Loops-N-plus-one-half create mode 120000 Lang/Crystal/Magic-8-ball create mode 120000 Lang/Crystal/Non-decimal-radices-Convert create mode 120000 Lang/Crystal/Order-by-pair-comparisons create mode 120000 Lang/Crystal/Order-two-numerical-lists create mode 120000 Lang/Crystal/Phrase-reversals create mode 120000 Lang/Crystal/Power-set create mode 120000 Lang/Crystal/Run-length-encoding create mode 120000 Lang/Crystal/Sort-an-array-of-composite-structures create mode 120000 Lang/Crystal/Sort-numbers-lexicographically create mode 120000 Lang/Crystal/Sort-three-variables create mode 120000 Lang/Crystal/Sorting-Algorithms-Circle-Sort create mode 120000 Lang/Crystal/Sorting-algorithms-Bubble-sort create mode 120000 Lang/Crystal/Split-a-character-string-based-on-change-of-character create mode 120000 Lang/Crystal/Stack-traces create mode 120000 Lang/Crystal/String-prepend create mode 120000 Lang/Crystal/Take-notes-on-the-command-line create mode 120000 Lang/D/Find-Chess960-starting-position-identifier create mode 120000 Lang/Dart/24-game-Solve create mode 120000 Lang/Dart/K-d-tree create mode 120000 Lang/Dart/Penneys-game create mode 120000 Lang/Delphi/Generate-Chess960-starting-position create mode 120000 Lang/ERRE/Leonardo-numbers create mode 120000 Lang/EasyLang/2048 create mode 120000 Lang/EasyLang/Abbreviations-automatic create mode 120000 Lang/EasyLang/Abbreviations-easy create mode 120000 Lang/EasyLang/Abbreviations-simple create mode 120000 Lang/EasyLang/Amb create mode 120000 Lang/EasyLang/Anagrams create mode 120000 Lang/EasyLang/Anagrams-Deranged-anagrams create mode 120000 Lang/EasyLang/Babylonian-spiral create mode 120000 Lang/EasyLang/Boyer-Moore-string-search create mode 120000 Lang/EasyLang/Element-wise-operations create mode 120000 Lang/EasyLang/Factorions create mode 120000 Lang/EasyLang/Mad-Libs create mode 120000 Lang/EasyLang/Permutation-test create mode 120000 Lang/EasyLang/Prime-numbers-whose-neighboring-pairs-are-tetraprimes create mode 120000 Lang/EasyLang/Primes---allocate-descendants-to-their-ancestors create mode 120000 Lang/EasyLang/Solve-a-Numbrix-puzzle create mode 120000 Lang/EasyLang/Solve-the-no-connection-puzzle create mode 120000 Lang/EasyLang/Sorting-algorithms-Patience-sort create mode 120000 Lang/EasyLang/Unprimeable-numbers create mode 120000 Lang/EasyLang/Wasteful-equidigital-and-frugal-numbers create mode 120000 Lang/Elena/Comma-quibbling create mode 120000 Lang/Elena/Concurrent-computing create mode 120000 Lang/Elena/HTTP create mode 120000 Lang/Elena/HTTPS create mode 120000 Lang/Emacs-Lisp/Color-wheel create mode 120000 Lang/Emacs-Lisp/Keyboard-input-Flush-the-keyboard-buffer create mode 120000 Lang/Emacs-Lisp/Keyboard-input-Keypress-check create mode 120000 Lang/Emacs-Lisp/Keyboard-input-Obtain-a-Y-or-N-response create mode 120000 Lang/Emacs-Lisp/Split-a-character-string-based-on-change-of-character create mode 120000 Lang/Emacs-Lisp/Strip-comments-from-a-string create mode 120000 Lang/Emacs-Lisp/Word-frequency create mode 120000 Lang/Erlang/Parse-an-IP-Address create mode 120000 Lang/Excel/Arrays create mode 120000 Lang/Excel/Conditional-structures create mode 120000 Lang/Excel/FizzBuzz create mode 120000 Lang/Excel/Function-definition create mode 120000 Lang/Excel/Loops-For create mode 120000 Lang/Excel/Repeat-a-string create mode 120000 Lang/Excel/Reverse-a-string create mode 120000 Lang/Excel/Tokenize-a-string create mode 120000 Lang/F-Sharp/Mad-Libs create mode 120000 Lang/Factor/Tic-tac-toe create mode 120000 Lang/Forth/Almost-prime create mode 120000 Lang/Fortran/Apply-a-digital-filter-direct-form-II-transposed- create mode 120000 Lang/Fortran/B-zier-curves-Intersections create mode 120000 Lang/Fortran/Eulers-constant-0.5772... create mode 120000 Lang/Fortran/First-perfect-square-in-base-n-with-n-unique-digits create mode 120000 Lang/Fortran/Harmonic-series create mode 120000 Lang/Fortran/Knuths-algorithm-S create mode 120000 Lang/Fortran/Thieles-interpolation-formula create mode 120000 Lang/Fortran/Vogels-approximation-method create mode 120000 Lang/Free-Pascal-Lazarus/DNS-query create mode 120000 Lang/Free-Pascal-Lazarus/Levenshtein-distance create mode 120000 Lang/Free-Pascal-Lazarus/Map-range create mode 120000 Lang/FreeBASIC/Bioinformatics-Global-alignment create mode 120000 Lang/FreeBASIC/Cistercian-numerals create mode 120000 Lang/FreeBASIC/Compiler-syntax-analyzer create mode 120000 Lang/FreeBASIC/Deconvolution-2D+ create mode 120000 Lang/FreeBASIC/Distribution-of-0-digits-in-factorial-series create mode 120000 Lang/FreeBASIC/Elliptic-curve-arithmetic create mode 120000 Lang/FreeBASIC/Fermat-numbers create mode 120000 Lang/FreeBASIC/Graph-colouring create mode 120000 Lang/FreeBASIC/Juggler-sequence create mode 120000 Lang/FreeBASIC/Knuths-algorithm-S create mode 120000 Lang/FreeBASIC/Knuths-power-tree create mode 120000 Lang/FreeBASIC/Last-letter-first-letter create mode 120000 Lang/FreeBASIC/Natural-sorting create mode 120000 Lang/FreeBASIC/Rosetta-Code-Fix-code-tags create mode 120000 Lang/FreeBASIC/Rosetta-Code-Rank-languages-by-popularity create mode 120000 Lang/FreeBASIC/SQL-based-authentication create mode 120000 Lang/FreeBASIC/Simulate-input-Keyboard create mode 120000 Lang/FreeBASIC/Sorting-algorithms-Strand-sort create mode 120000 Lang/FreeBASIC/Text-processing-2 create mode 120000 Lang/FreeBASIC/Ukkonen-s-suffix-tree-construction create mode 120000 Lang/FreeBASIC/Word-ladder create mode 120000 Lang/GW-BASIC/Levenshtein-distance create mode 120000 Lang/GW-BASIC/Magic-constant create mode 120000 Lang/GW-BASIC/Map-range create mode 120000 Lang/Gambas/Evaluate-binomial-coefficients create mode 120000 Lang/Gambas/Magic-constant create mode 120000 Lang/Go/Boyer-Moore-string-search create mode 120000 Lang/Go/Goldbachs-comet create mode 120000 Lang/Go/P-Adic-square-roots create mode 120000 Lang/Haskell/Pathological-floating-point-problems create mode 120000 Lang/Icon/Loops-Increment-loop-index-within-loop-body create mode 120000 Lang/Java/Strassens-algorithm create mode 120000 Lang/JavaScript/15-puzzle-solver create mode 120000 Lang/JavaScript/ADFGVX-cipher create mode 120000 Lang/JavaScript/Average-loop-length create mode 120000 Lang/JavaScript/Bifid-cipher create mode 120000 Lang/JavaScript/Bitcoin-address-validation create mode 120000 Lang/JavaScript/Boyer-Moore-string-search create mode 120000 Lang/JavaScript/Burrows-Wheeler-transform create mode 120000 Lang/JavaScript/Camel-case-and-snake-case create mode 120000 Lang/JavaScript/Colorful-numbers create mode 120000 Lang/JavaScript/Commatizing-numbers create mode 120000 Lang/JavaScript/Compiler-code-generator create mode 120000 Lang/JavaScript/Create-a-file-on-magnetic-tape create mode 120000 Lang/JavaScript/Cyclotomic-polynomial create mode 120000 Lang/JavaScript/De-Bruijn-sequences create mode 120000 Lang/JavaScript/Distribution-of-0-digits-in-factorial-series create mode 120000 Lang/JavaScript/Elliptic-Curve-Digital-Signature-Algorithm create mode 120000 Lang/JavaScript/Elliptic-curve-arithmetic create mode 120000 Lang/JavaScript/Gauss-Jordan-matrix-inversion create mode 120000 Lang/JavaScript/Graph-colouring create mode 120000 Lang/JavaScript/Greedy-algorithm-for-Egyptian-fractions create mode 120000 Lang/JavaScript/Isqrt-integer-square-root-of-X create mode 120000 Lang/JavaScript/Jacobi-symbol create mode 120000 Lang/JavaScript/K-d-tree create mode 120000 Lang/JavaScript/Knuths-algorithm-S create mode 120000 Lang/JavaScript/Knuths-power-tree create mode 120000 Lang/JavaScript/M-bius-function create mode 120000 Lang/JavaScript/MD5-Implementation create mode 120000 Lang/JavaScript/P-Adic-numbers-basic create mode 120000 Lang/JavaScript/P-Adic-square-roots create mode 120000 Lang/JavaScript/Perlin-noise create mode 120000 Lang/JavaScript/Playfair-cipher create mode 120000 Lang/JavaScript/SHA-1 create mode 120000 Lang/JavaScript/Set-puzzle create mode 120000 Lang/JavaScript/Solve-a-Hidato-puzzle create mode 120000 Lang/JavaScript/Solve-a-Numbrix-puzzle create mode 120000 Lang/JavaScript/Sorting-algorithms-Radix-sort create mode 120000 Lang/JavaScript/Spelling-of-ordinal-numbers create mode 120000 Lang/JavaScript/State-name-puzzle create mode 120000 Lang/JavaScript/Strassens-algorithm create mode 120000 Lang/JavaScript/Substitution-cipher create mode 120000 Lang/JavaScript/Tonelli-Shanks-algorithm create mode 120000 Lang/JavaScript/Ukkonen-s-suffix-tree-construction create mode 120000 Lang/JavaScript/Verhoeff-algorithm create mode 120000 Lang/JavaScript/Vigen-re-cipher-Cryptanalysis create mode 120000 Lang/JavaScript/Vogels-approximation-method create mode 120000 Lang/JavaScript/Wordiff create mode 120000 Lang/JavaScript/Zebra-puzzle create mode 120000 Lang/K/Compare-length-of-two-strings create mode 120000 Lang/K/Euler-method create mode 120000 Lang/K/M-bius-function create mode 120000 Lang/K/Substring create mode 120000 Lang/K/UTF-8-encode-and-decode create mode 120000 Lang/K/Write-float-arrays-to-a-text-file create mode 120000 Lang/Logo/Merge-and-aggregate-datasets create mode 120000 Lang/Lua/Check-input-device-is-a-terminal create mode 120000 Lang/Lua/Parse-an-IP-Address create mode 120000 Lang/Lua/Ramer-Douglas-Peucker-line-simplification create mode 120000 Lang/Lua/Update-a-configuration-file create mode 120000 Lang/M2000-Interpreter/ADFGVX-cipher create mode 120000 Lang/M2000-Interpreter/Apply-a-digital-filter-direct-form-II-transposed- create mode 120000 Lang/M2000-Interpreter/Cartesian-product-of-two-or-more-lists create mode 120000 Lang/M2000-Interpreter/Compare-length-of-two-strings create mode 120000 Lang/M2000-Interpreter/File-extension-is-in-extensions-list create mode 120000 Lang/M2000-Interpreter/Greatest-subsequential-sum create mode 120000 Lang/M2000-Interpreter/Power-set create mode 120000 Lang/M2000-Interpreter/Simple-turtle-graphics create mode 120000 Lang/M2000-Interpreter/Sorting-algorithms-Strand-sort create mode 120000 Lang/M2000-Interpreter/Strip-a-set-of-characters-from-a-string create mode 120000 Lang/MACRO-11/Run-length-encoding create mode 120000 Lang/MAD/Look-and-say-sequence create mode 120000 Lang/MSX-Basic/Evaluate-binomial-coefficients create mode 120000 Lang/Maple/Pythagoras-tree create mode 120000 Lang/Mathematica/15-puzzle-solver create mode 120000 Lang/Mathematica/B-zier-curves-Intersections create mode 120000 Lang/Mathematica/Sisyphus-sequence create mode 120000 Lang/Mathematica/Sphenic-numbers create mode 120000 Lang/Mathematica/Wagstaff-primes create mode 120000 Lang/Minimal-BASIC/Evaluate-binomial-coefficients create mode 120000 Lang/Miranda/Loops-Infinite create mode 120000 Lang/Miranda/Run-length-encoding create mode 120000 Lang/Modula-2/M-bius-function create mode 120000 Lang/Modula-2/Magic-constant create mode 120000 Lang/Modula-2/Map-range create mode 120000 Lang/Modula-2/Ramer-Douglas-Peucker-line-simplification create mode 120000 Lang/Nascom-BASIC/Levenshtein-distance create mode 120000 Lang/Nu/CSV-data-manipulation create mode 120000 Lang/Nu/Department-numbers create mode 120000 Lang/Nu/Determine-if-a-string-has-all-the-same-characters create mode 120000 Lang/Nu/File-extension-is-in-extensions-list create mode 120000 Lang/Nu/File-size-distribution create mode 120000 Lang/Nu/I-before-E-except-after-C create mode 120000 Lang/Nu/Word-frequency create mode 120000 Lang/OCaml/Anti-primes create mode 120000 Lang/OCaml/Attractive-numbers create mode 120000 Lang/OCaml/Cuban-primes create mode 120000 Lang/OPL/100-doors create mode 120000 Lang/OPL/Arithmetic-Integer create mode 120000 Lang/OPL/Arrays create mode 120000 Lang/OPL/Character-codes create mode 120000 Lang/OPL/Comments create mode 120000 Lang/OPL/Compare-length-of-two-strings create mode 120000 Lang/OPL/Copy-a-string create mode 120000 Lang/OPL/Draw-a-clock create mode 120000 Lang/OPL/Draw-a-pixel create mode 120000 Lang/OPL/Hello-world-Text create mode 120000 Lang/OPL/Program-termination create mode 120000 Lang/OPL/String-prepend create mode 120000 Lang/OPL/User-input-Text create mode 120000 Lang/Objeck/Copy-stdin-to-stdout create mode 120000 Lang/Objeck/Distributed-programming create mode 120000 Lang/Objeck/Floyds-triangle create mode 120000 Lang/Objeck/Generate-lower-case-ASCII-alphabet create mode 120000 Lang/Objeck/Hello-world-Standard-error create mode 120000 Lang/Objeck/Knuth-shuffle create mode 120000 Lang/Objeck/Mad-Libs create mode 120000 Lang/Objeck/Multiplication-tables create mode 120000 Lang/Objeck/Roman-numerals-Decode create mode 120000 Lang/Objeck/Rosetta-Code-Find-unimplemented-tasks create mode 120000 Lang/Objeck/Strip-a-set-of-characters-from-a-string create mode 120000 Lang/Odin/Euler-method create mode 120000 Lang/Odin/Execute-Brain- create mode 120000 Lang/Odin/Fractran create mode 120000 Lang/Odin/Hailstone-sequence create mode 120000 Lang/Odin/Hello-world-Graphical create mode 120000 Lang/Odin/Primality-by-trial-division create mode 120000 Lang/Odin/Runge-Kutta-method create mode 120000 Lang/Odin/Strip-a-set-of-characters-from-a-string create mode 120000 Lang/Odin/Unicode-variable-names create mode 120000 Lang/Odin/Write-entire-file create mode 120000 Lang/Ol/Runge-Kutta-method create mode 120000 Lang/OxygenBasic/Evaluate-binomial-coefficients create mode 120000 Lang/PARI-GP/Attractive-numbers create mode 120000 Lang/PARI-GP/Disarium-numbers create mode 120000 Lang/PARI-GP/Prime-numbers-whose-neighboring-pairs-are-tetraprimes create mode 120000 Lang/PHP/M-bius-function create mode 120000 Lang/PHP/Magic-constant create mode 120000 Lang/PHP/Map-range create mode 120000 Lang/PL-I-80/Additive-primes create mode 120000 Lang/Pascal/Date-manipulation delete mode 120000 Lang/Pascal/FizzBuzz delete mode 120000 Lang/Pascal/Levenshtein-distance delete mode 120000 Lang/Pascal/Map-range create mode 120000 Lang/PascalABC.NET/Additive-primes create mode 120000 Lang/PascalABC.NET/Amicable-pairs create mode 120000 Lang/PascalABC.NET/Pancake-numbers create mode 120000 Lang/PascalABC.NET/Pangram-checker create mode 120000 Lang/PascalABC.NET/Paraffins create mode 120000 Lang/PascalABC.NET/Parallel-calculations create mode 120000 Lang/PascalABC.NET/Parsing-RPN-calculator-algorithm create mode 120000 Lang/PascalABC.NET/Partition-an-integer-x-into-n-primes create mode 120000 Lang/PascalABC.NET/Pascal-matrix-generation create mode 120000 Lang/PascalABC.NET/Pascals-triangle-Puzzle create mode 120000 Lang/PascalABC.NET/Pathological-floating-point-problems create mode 120000 Lang/PascalABC.NET/Pells-equation create mode 120000 Lang/PascalABC.NET/Perfect-shuffle create mode 120000 Lang/PascalABC.NET/Perfect-totient-numbers create mode 120000 Lang/PascalABC.NET/Permutation-test create mode 120000 Lang/Perl/Execute-Computer-Zero create mode 120000 Lang/Prolog/Evaluate-binomial-coefficients create mode 120000 Lang/Python/Im-a-software-engineer-get-me-out-of-here create mode 120000 Lang/Python/Prime-numbers-whose-neighboring-pairs-are-tetraprimes create mode 120000 Lang/Python/Square-form-factorization create mode 120000 Lang/Python/Wasteful-equidigital-and-frugal-numbers create mode 120000 Lang/Q/Euler-method create mode 120000 Lang/QBasic/Evaluate-binomial-coefficients create mode 120000 Lang/QBasic/Map-range create mode 120000 Lang/Quackery/Dice-game-probabilities create mode 120000 Lang/Quackery/Sum-of-elements-below-main-diagonal-of-matrix create mode 120000 Lang/Quackery/Two-bullet-roulette create mode 120000 Lang/R/Camel-case-and-snake-case create mode 120000 Lang/R/Determine-sentence-type create mode 120000 Lang/R/Disarium-numbers create mode 120000 Lang/R/Display-a-linear-combination create mode 120000 Lang/R/Draw-a-cuboid create mode 120000 Lang/R/Dutch-national-flag-problem create mode 120000 Lang/R/Factorions create mode 120000 Lang/R/Find-palindromic-numbers-in-both-binary-and-ternary-bases create mode 120000 Lang/R/Halt-and-catch-fire create mode 120000 Lang/R/Hex-words create mode 120000 Lang/R/Kernighans-large-earthquake-problem create mode 120000 Lang/R/Munchausen-numbers create mode 120000 Lang/R/Old-Russian-measure-of-length create mode 120000 Lang/R/Semordnilap create mode 120000 Lang/R/Sort-numbers-lexicographically create mode 120000 Lang/R/Strip-a-set-of-characters-from-a-string create mode 120000 Lang/REXX/Magic-constant create mode 120000 Lang/REXX/Primes---allocate-descendants-to-their-ancestors create mode 120000 Lang/REXX/Ramanujan-primes-twins create mode 120000 Lang/REXX/Sequence-of-primorial-primes create mode 120000 Lang/REXX/Sieve-of-Pritchard create mode 120000 Lang/Raku/Simple-turtle-graphics create mode 120000 Lang/RapidQ/Levenshtein-distance create mode 120000 Lang/RapidQ/M-bius-function create mode 120000 Lang/RapidQ/Map-range create mode 120000 Lang/Refal/Loops-Infinite create mode 120000 Lang/Refal/Power-set create mode 120000 Lang/Refal/Run-length-encoding create mode 120000 Lang/Refal/Strip-comments-from-a-string create mode 120000 Lang/Rust/Ascending-primes create mode 120000 Lang/Rust/B-zier-curves-Intersections create mode 120000 Lang/Rust/Bifid-cipher create mode 120000 Lang/Rust/Bioinformatics-Global-alignment create mode 120000 Lang/Rust/Blum-integer create mode 120000 Lang/Rust/Boyer-Moore-string-search create mode 120000 Lang/Rust/Calendar---for-REAL-programmers create mode 120000 Lang/Rust/Compare-sorting-algorithms-performance create mode 120000 Lang/Rust/Compiler-AST-interpreter create mode 120000 Lang/Rust/Compiler-code-generator create mode 120000 Lang/Rust/Compiler-lexical-analyzer create mode 120000 Lang/Rust/Compiler-syntax-analyzer create mode 120000 Lang/Rust/Cyclotomic-polynomial create mode 120000 Lang/Rust/Descending-primes create mode 120000 Lang/Rust/Doubly-linked-list-Definition create mode 120000 Lang/Rust/Doubly-linked-list-Traversal create mode 120000 Lang/Rust/Elliptic-Curve-Digital-Signature-Algorithm create mode 120000 Lang/Rust/Faulhabers-formula create mode 120000 Lang/Rust/Graph-colouring create mode 120000 Lang/Rust/Hex-words create mode 120000 Lang/Rust/Kosaraju create mode 120000 Lang/Rust/Latin-Squares-in-reduced-form create mode 120000 Lang/Rust/Median-filter create mode 120000 Lang/Rust/Natural-sorting create mode 120000 Lang/Rust/Nonogram-solver create mode 120000 Lang/Rust/OpenWebNet-password create mode 120000 Lang/Rust/P-Adic-numbers-basic create mode 120000 Lang/Rust/P-Adic-square-roots create mode 120000 Lang/Rust/Playfair-cipher create mode 120000 Lang/Rust/Polynomial-regression create mode 120000 Lang/Rust/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a create mode 120000 Lang/Rust/Pseudo-random-numbers-Middle-square-method create mode 120000 Lang/Rust/Pseudo-random-numbers-Splitmix64 create mode 120000 Lang/Rust/QR-decomposition create mode 120000 Lang/Rust/Rendezvous create mode 120000 Lang/Rust/Resistor-mesh create mode 120000 Lang/Rust/Shoelace-formula-for-polygonal-area create mode 120000 Lang/Rust/Solve-a-Holy-Knights-tour create mode 120000 Lang/Rust/Solve-a-Hopido-puzzle create mode 120000 Lang/Rust/Solve-a-Numbrix-puzzle create mode 120000 Lang/Rust/Sorting-algorithms-Bead-sort create mode 120000 Lang/Rust/Sorting-algorithms-Patience-sort create mode 120000 Lang/Rust/Sorting-algorithms-Strand-sort create mode 120000 Lang/Rust/Steffensens-method create mode 120000 Lang/Rust/Strassens-algorithm create mode 120000 Lang/Rust/Stream-merge create mode 120000 Lang/Rust/Sudan-function create mode 120000 Lang/Rust/Tonelli-Shanks-algorithm create mode 120000 Lang/Rust/Ukkonen-s-suffix-tree-construction create mode 120000 Lang/Rust/Verhoeff-algorithm create mode 120000 Lang/Rust/Xiaolin-Wus-line-algorithm create mode 120000 Lang/S-BASIC/Additive-primes create mode 120000 Lang/S-BASIC/Character-codes create mode 120000 Lang/S-BASIC/Loops-Increment-loop-index-within-loop-body create mode 120000 Lang/S-BASIC/Sum-of-a-series create mode 120000 Lang/SETL/Gray-code create mode 120000 Lang/SETL/Loops-Do-while create mode 120000 Lang/SETL/Loops-Increment-loop-index-within-loop-body create mode 120000 Lang/SETL/Loops-Infinite create mode 120000 Lang/SETL/Radical-of-an-integer create mode 120000 Lang/SETL/Strip-comments-from-a-string create mode 120000 Lang/SQL/Factorial create mode 120000 Lang/Scala/Boyer-Moore-string-search create mode 120000 Lang/Scheme/Circular-primes create mode 120000 Lang/Scheme/Compare-length-of-two-strings create mode 120000 Lang/Scheme/Runge-Kutta-method create mode 120000 Lang/Scheme/Unicode-variable-names create mode 120000 Lang/Standard-ML/Box-the-compass create mode 120000 Lang/Tcl/Unicode-strings create mode 120000 Lang/Tiny-BASIC/Magic-constant create mode 120000 Lang/True-BASIC/Evaluate-binomial-coefficients create mode 120000 Lang/TypeScript/Additive-primes create mode 120000 Lang/TypeScript/Arithmetic-numbers create mode 120000 Lang/TypeScript/Map-range create mode 120000 Lang/TypeScript/Sum-of-a-series create mode 120000 Lang/UNIX-Shell/Color-of-a-screen-pixel create mode 120000 Lang/UNIX-Shell/Color-quantization create mode 120000 Lang/Uiua/Create-a-two-dimensional-array-at-runtime create mode 120000 Lang/Uiua/Damm-algorithm create mode 120000 Lang/Uiua/Ethiopian-multiplication create mode 120000 Lang/Uiua/Matrix-transposition create mode 120000 Lang/Uiua/Munching-squares create mode 120000 Lang/Uiua/Pangram-checker create mode 120000 Lang/Uiua/Spiral-matrix create mode 120000 Lang/Uiua/Zig-zag-matrix create mode 120000 Lang/Uxntal/Array-length create mode 120000 Lang/Uxntal/Bioinformatics-base-count create mode 120000 Lang/Uxntal/Comments create mode 120000 Lang/Uxntal/Conditional-structures create mode 120000 Lang/Uxntal/Copy-a-string delete mode 120000 Lang/Uxntal/Draw-a-pixel create mode 120000 Lang/Uxntal/Fibonacci-sequence create mode 120000 Lang/Uxntal/Flow-control-structures create mode 120000 Lang/Uxntal/Hello-world-Graphical create mode 120000 Lang/Uxntal/Hello-world-Standard-error delete mode 120000 Lang/Uxntal/Hello-world-Text create mode 120000 Lang/Uxntal/Integer-sequence create mode 120000 Lang/Uxntal/Loops-Break create mode 120000 Lang/Uxntal/Loops-Continue create mode 120000 Lang/Uxntal/Loops-Do-while create mode 120000 Lang/Uxntal/Loops-For-with-a-specified-step create mode 120000 Lang/Uxntal/Loops-Foreach create mode 120000 Lang/Uxntal/Loops-N-plus-one-half create mode 120000 Lang/Uxntal/Loops-While create mode 120000 Lang/Uxntal/Stack-traces create mode 120000 Lang/Uxntal/String-length create mode 120000 Lang/V-(Vlang)/Quine create mode 120000 Lang/Wisp/Knuth-shuffle create mode 120000 Lang/X86-64-Assembly/Terminal-control-Clear-the-screen create mode 120000 Lang/XBasic/Levenshtein-distance create mode 120000 Lang/XPL0/Bin-given-limits create mode 120000 Lang/XPL0/Create-an-object-at-a-given-address create mode 120000 Lang/XPL0/Floyd-Warshall-algorithm create mode 120000 Lang/XPL0/Largest-int-from-concatenated-ints create mode 120000 Lang/XPL0/Last-letter-first-letter create mode 120000 Lang/XPL0/Levenshtein-distance create mode 120000 Lang/XPL0/Polynomial-regression create mode 120000 Lang/XPL0/Read-a-configuration-file create mode 120000 Lang/XPL0/Sort-three-variables create mode 120000 Lang/XPL0/Text-processing-1 create mode 120000 Lang/XPL0/Text-processing-2 create mode 120000 Lang/Yabasic/Evaluate-binomial-coefficients create mode 120000 Lang/Zig/15-puzzle-solver create mode 120000 Lang/Zig/2048 create mode 120000 Lang/Zig/24-game create mode 120000 Lang/Zig/Anti-primes create mode 120000 Lang/Zig/Canonicalize-CIDR create mode 120000 Lang/Zig/Convex-hull create mode 120000 Lang/Zig/De-Bruijn-sequences create mode 120000 Lang/Zig/Dijkstras-algorithm create mode 120000 Lang/Zig/Execute-a-Markov-algorithm create mode 120000 Lang/Zig/Fibonacci-sequence create mode 120000 Lang/Zig/Find-the-missing-permutation create mode 120000 Lang/Zig/Floyd-Warshall-algorithm create mode 120000 Lang/Zig/Latin-Squares-in-reduced-form create mode 120000 Lang/Zig/Move-to-front-algorithm create mode 120000 Lang/Zig/Natural-sorting create mode 120000 Lang/Zig/P-Adic-numbers-basic create mode 120000 Lang/Zig/P-Adic-square-roots create mode 120000 Lang/Zig/Parsing-RPN-calculator-algorithm create mode 120000 Lang/Zig/Parsing-Shunting-yard-algorithm create mode 120000 Lang/Zig/Quickselect-algorithm create mode 120000 Lang/Zig/Quine create mode 120000 Lang/Zig/SHA-1 create mode 120000 Lang/Zig/Solve-a-Holy-Knights-tour create mode 120000 Lang/Zig/Sorting-algorithms-Patience-sort create mode 120000 Lang/Zig/Sorting-algorithms-Strand-sort create mode 120000 Lang/Zig/Strassens-algorithm create mode 120000 Lang/Zig/Sutherland-Hodgman-polygon-clipping create mode 120000 Lang/Zig/Thue-Morse create mode 120000 Lang/Zig/Tonelli-Shanks-algorithm create mode 120000 Lang/Zig/Y-combinator create mode 100644 Task/100-doors/BQN/100-doors-4.bqn create mode 100644 Task/100-doors/BQN/100-doors-5.bqn create mode 100644 Task/100-doors/Excel/100-doors-4.excel create mode 100644 Task/100-doors/OPL/100-doors.opl create mode 100644 Task/100-doors/Quackery/100-doors-1.quackery create mode 100644 Task/100-doors/Quackery/100-doors-2.quackery delete mode 100644 Task/100-doors/Quackery/100-doors.quackery create mode 100644 Task/100-doors/Tcl/100-doors-4.tcl create mode 100644 Task/15-puzzle-solver/JavaScript/15-puzzle-solver.js create mode 100644 Task/15-puzzle-solver/Mathematica/15-puzzle-solver.math create mode 100644 Task/15-puzzle-solver/Zig/15-puzzle-solver.zig create mode 100644 Task/2048/EasyLang/2048.easy create mode 100644 Task/2048/Zig/2048.zig create mode 100644 Task/24-game-Solve/Dart/24-game-solve.dart create mode 100644 Task/24-game/Zig/24-game.zig create mode 100644 Task/99-bottles-of-beer/Factor/99-bottles-of-beer-1.factor rename Task/99-bottles-of-beer/Factor/{99-bottles-of-beer.factor => 99-bottles-of-beer-2.factor} (100%) create mode 100644 Task/A+B/Ballerina/a+b.ballerina delete mode 100644 Task/A+B/REXX/a+b-1.rexx delete mode 100644 Task/A+B/REXX/a+b-2.rexx delete mode 100644 Task/A+B/REXX/a+b-3.rexx delete mode 100644 Task/A+B/REXX/a+b-4.rexx delete mode 100644 Task/A+B/REXX/a+b-5.rexx create mode 100644 Task/A+B/REXX/a+b.rexx create mode 100644 Task/ABC-problem/Ballerina/abc-problem.ballerina create mode 100644 Task/ADFGVX-cipher/C-sharp/adfgvx-cipher.cs create mode 100644 Task/ADFGVX-cipher/JavaScript/adfgvx-cipher.js create mode 100644 Task/ADFGVX-cipher/M2000-Interpreter/adfgvx-cipher.m2000 create mode 100644 Task/AKS-test-for-primes/Ballerina/aks-test-for-primes.ballerina delete mode 100644 Task/AKS-test-for-primes/REXX/aks-test-for-primes-3.rexx create mode 100644 Task/ASCII-art-diagram-converter/C-sharp/ascii-art-diagram-converter-1.cs create mode 100644 Task/ASCII-art-diagram-converter/C-sharp/ascii-art-diagram-converter-2.cs create mode 100644 Task/Abbreviations-automatic/EasyLang/abbreviations-automatic.easy create mode 100644 Task/Abbreviations-easy/Crystal/abbreviations-easy.cr create mode 100644 Task/Abbreviations-easy/EasyLang/abbreviations-easy.easy create mode 100644 Task/Abbreviations-simple/EasyLang/abbreviations-simple.easy create mode 100644 Task/Abundant-deficient-and-perfect-number-classifications/Ballerina/abundant-deficient-and-perfect-number-classifications-1.ballerina create mode 100644 Task/Abundant-deficient-and-perfect-number-classifications/Ballerina/abundant-deficient-and-perfect-number-classifications-2.ballerina delete mode 100644 Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-3.rexx delete mode 100644 Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-4.rexx create mode 100644 Task/Abundant-odd-numbers/Ballerina/abundant-odd-numbers.ballerina create mode 100644 Task/Accumulator-factory/Ballerina/accumulator-factory.ballerina create mode 100644 Task/Achilles-numbers/Ballerina/achilles-numbers.ballerina create mode 100644 Task/Ackermann-function/Ballerina/ackermann-function.ballerina create mode 100644 Task/Add-a-variable-to-a-class-instance-at-runtime/Ballerina/add-a-variable-to-a-class-instance-at-runtime.ballerina create mode 100644 Task/Additive-primes/ALGOL-60/additive-primes.alg create mode 100644 Task/Additive-primes/ALGOL-M/additive-primes.alg create mode 100644 Task/Additive-primes/Ballerina/additive-primes.ballerina create mode 100644 Task/Additive-primes/PL-I-80/additive-primes.pli create mode 100644 Task/Additive-primes/PascalABC.NET/additive-primes.pas create mode 100644 Task/Additive-primes/S-BASIC/additive-primes.basic create mode 100644 Task/Additive-primes/TypeScript/additive-primes.ts create mode 100644 Task/Address-of-a-variable/Ballerina/address-of-a-variable.ballerina create mode 100644 Task/Almost-prime/Ballerina/almost-prime.ballerina create mode 100644 Task/Almost-prime/Forth/almost-prime.fth delete mode 100644 Task/Almost-prime/REXX/almost-prime-1.rexx delete mode 100644 Task/Almost-prime/REXX/almost-prime-2.rexx rename Task/Almost-prime/REXX/{almost-prime-3.rexx => almost-prime.rexx} (92%) create mode 100644 Task/Amb/Ballerina/amb.ballerina create mode 100644 Task/Amb/EasyLang/amb.easy create mode 100644 Task/Amicable-pairs/PascalABC.NET/amicable-pairs.pas delete mode 100644 Task/Amicable-pairs/REXX/amicable-pairs-3.rexx delete mode 100644 Task/Amicable-pairs/REXX/amicable-pairs-4.rexx delete mode 100644 Task/Amicable-pairs/REXX/amicable-pairs-5.rexx delete mode 100644 Task/Amicable-pairs/REXX/amicable-pairs-6.rexx create mode 100644 Task/Anagrams-Deranged-anagrams/Crystal/anagrams-deranged-anagrams.cr create mode 100644 Task/Anagrams-Deranged-anagrams/EasyLang/anagrams-deranged-anagrams.easy create mode 100644 Task/Anagrams/EasyLang/anagrams.easy create mode 100644 Task/Angle-difference-between-two-bearings/Ballerina/angle-difference-between-two-bearings.ballerina create mode 100644 Task/Anti-primes/Ballerina/anti-primes.ballerina create mode 100644 Task/Anti-primes/OCaml/anti-primes.ml delete mode 100644 Task/Anti-primes/REXX/anti-primes-3.rexx create mode 100644 Task/Anti-primes/Zig/anti-primes.zig create mode 100644 Task/Apply-a-callback-to-an-array/Ballerina/apply-a-callback-to-an-array.ballerina create mode 100644 Task/Apply-a-digital-filter-direct-form-II-transposed-/Fortran/apply-a-digital-filter-direct-form-ii-transposed-.f create mode 100644 Task/Apply-a-digital-filter-direct-form-II-transposed-/M2000-Interpreter/apply-a-digital-filter-direct-form-ii-transposed-.m2000 create mode 100644 Task/Approximate-equality/Ballerina/approximate-equality.ballerina create mode 100644 Task/Arithmetic-Complex/Ballerina/arithmetic-complex.ballerina create mode 100644 Task/Arithmetic-Complex/Crystal/arithmetic-complex.cr rename Task/Arithmetic-Complex/M2000-Interpreter/{arithmetic-complex.m2000 => arithmetic-complex-1.m2000} (100%) create mode 100644 Task/Arithmetic-Complex/M2000-Interpreter/arithmetic-complex-2.m2000 create mode 100644 Task/Arithmetic-Integer/Ballerina/arithmetic-integer.ballerina create mode 100644 Task/Arithmetic-Integer/OPL/arithmetic-integer.opl create mode 100644 Task/Arithmetic-Rational/Ballerina/arithmetic-rational.ballerina create mode 100644 Task/Arithmetic-derivative/Arturo/arithmetic-derivative.arturo create mode 100644 Task/Arithmetic-derivative/C-sharp/arithmetic-derivative.cs create mode 100644 Task/Arithmetic-geometric-mean/Crystal/arithmetic-geometric-mean.cr create mode 100644 Task/Arithmetic-numbers/Ballerina/arithmetic-numbers.ballerina create mode 100644 Task/Arithmetic-numbers/TypeScript/arithmetic-numbers.ts create mode 100644 Task/Array-concatenation/Ballerina/array-concatenation.ballerina delete mode 100644 Task/Array-concatenation/REXX/array-concatenation-1.rexx delete mode 100644 Task/Array-concatenation/REXX/array-concatenation-2.rexx delete mode 100644 Task/Array-concatenation/REXX/array-concatenation-3.rexx create mode 100644 Task/Array-concatenation/REXX/array-concatenation.rexx create mode 100644 Task/Array-length/Ballerina/array-length.ballerina create mode 100644 Task/Array-length/Uxntal/array-length.uxnatl create mode 100644 Task/Arrays/Ballerina/arrays.ballerina create mode 100644 Task/Arrays/Excel/arrays-1.excel create mode 100644 Task/Arrays/Excel/arrays-2.excel create mode 100644 Task/Arrays/Excel/arrays-3.excel create mode 100644 Task/Arrays/OPL/arrays.opl delete mode 100644 Task/Arrays/REXX/arrays-1.rexx delete mode 100644 Task/Arrays/REXX/arrays-2.rexx delete mode 100644 Task/Arrays/REXX/arrays-3.rexx delete mode 100644 Task/Arrays/REXX/arrays-4.rexx delete mode 100644 Task/Arrays/REXX/arrays-5.rexx delete mode 100644 Task/Arrays/REXX/arrays-6.rexx create mode 100644 Task/Arrays/REXX/arrays.rexx create mode 100644 Task/Arrays/Tcl/arrays-3.tcl create mode 100644 Task/Arrays/Tcl/arrays-4.tcl create mode 100644 Task/Arrays/Tcl/arrays-5.tcl create mode 100644 Task/Arrays/Tcl/arrays-6.tcl create mode 100644 Task/Ascending-primes/Ballerina/ascending-primes.ballerina create mode 100644 Task/Ascending-primes/Rust/ascending-primes-1.rs create mode 100644 Task/Ascending-primes/Rust/ascending-primes-2.rs create mode 100644 Task/Ascending-primes/Rust/ascending-primes-3.rs create mode 100644 Task/Associative-array-Creation/Ballerina/associative-array-creation.ballerina create mode 100644 Task/Associative-array-Iteration/Ballerina/associative-array-iteration.ballerina create mode 100644 Task/Associative-array-Merging/Ballerina/associative-array-merging.ballerina create mode 100644 Task/Associative-array-Merging/Common-Lisp/associative-array-merging-3.lisp create mode 100644 Task/Attractive-numbers/OCaml/attractive-numbers.ml create mode 100644 Task/Attractive-numbers/PARI-GP/attractive-numbers-1.parigp create mode 100644 Task/Attractive-numbers/PARI-GP/attractive-numbers-2.parigp create mode 100644 Task/Average-loop-length/JavaScript/average-loop-length.js create mode 100644 Task/Averages-Arithmetic-mean/Ballerina/averages-arithmetic-mean.ballerina create mode 100644 Task/Averages-Mean-angle/Ballerina/averages-mean-angle.ballerina create mode 100644 Task/Averages-Mean-time-of-day/Ballerina/averages-mean-time-of-day.ballerina create mode 100644 Task/Averages-Median/Ballerina/averages-median.ballerina create mode 100644 Task/Averages-Mode/Ballerina/averages-mode.ballerina create mode 100644 Task/Averages-Mode/Crystal/averages-mode.cr create mode 100644 Task/Averages-Pythagorean-means/Ballerina/averages-pythagorean-means.ballerina create mode 100644 Task/Averages-Pythagorean-means/Crystal/averages-pythagorean-means.cr create mode 100644 Task/Averages-Root-mean-square/Ballerina/averages-root-mean-square.ballerina create mode 100644 Task/Averages-Simple-moving-average/Ballerina/averages-simple-moving-average.ballerina create mode 100644 Task/B-zier-curves-Intersections/Fortran/b-zier-curves-intersections.f create mode 100644 Task/B-zier-curves-Intersections/Mathematica/b-zier-curves-intersections.math create mode 100644 Task/B-zier-curves-Intersections/Rust/b-zier-curves-intersections.rs create mode 100644 Task/Babylonian-spiral/EasyLang/babylonian-spiral.easy create mode 100644 Task/Balanced-brackets/Ballerina/balanced-brackets.ballerina create mode 100644 Task/Balanced-brackets/Excel/balanced-brackets-3.excel create mode 100644 Task/Balanced-brackets/Excel/balanced-brackets-4.excel rename Task/Bell-numbers/C-sharp/{bell-numbers.cs => bell-numbers-1.cs} (100%) create mode 100644 Task/Bell-numbers/C-sharp/bell-numbers-2.cs create mode 100644 Task/Bifid-cipher/JavaScript/bifid-cipher.js create mode 100644 Task/Bifid-cipher/Rust/bifid-cipher.rs create mode 100644 Task/Bin-given-limits/AppleScript/bin-given-limits.applescript create mode 100644 Task/Bin-given-limits/Crystal/bin-given-limits.cr create mode 100644 Task/Bin-given-limits/XPL0/bin-given-limits.xpl0 create mode 100644 Task/Binary-digits/C3/binary-digits.c3 create mode 100644 Task/Bioinformatics-Global-alignment/FreeBASIC/bioinformatics-global-alignment.basic create mode 100644 Task/Bioinformatics-Global-alignment/Rust/bioinformatics-global-alignment.rs create mode 100644 Task/Bioinformatics-base-count/Uxntal/bioinformatics-base-count.uxnatl create mode 100644 Task/Bitcoin-address-validation/JavaScript/bitcoin-address-validation.js create mode 100644 Task/Blum-integer/Rust/blum-integer.rs create mode 100644 Task/Boolean-values/Ballerina/boolean-values.ballerina create mode 100644 Task/Box-the-compass/Standard-ML/box-the-compass.ml create mode 100644 Task/Boyer-Moore-string-search/C-sharp/boyer-moore-string-search.cs create mode 100644 Task/Boyer-Moore-string-search/EasyLang/boyer-moore-string-search.easy create mode 100644 Task/Boyer-Moore-string-search/Go/boyer-moore-string-search.go create mode 100644 Task/Boyer-Moore-string-search/JavaScript/boyer-moore-string-search.js create mode 100644 Task/Boyer-Moore-string-search/Rust/boyer-moore-string-search.rs create mode 100644 Task/Boyer-Moore-string-search/Scala/boyer-moore-string-search.scala create mode 100644 Task/Burrows-Wheeler-transform/JavaScript/burrows-wheeler-transform.js create mode 100644 Task/CSV-data-manipulation/Nu/csv-data-manipulation-1.nu create mode 100644 Task/CSV-data-manipulation/Nu/csv-data-manipulation-2.nu create mode 100644 Task/Caesar-cipher/Ballerina/caesar-cipher.ballerina create mode 100644 Task/Calculating-the-value-of-e/Ballerina/calculating-the-value-of-e.ballerina create mode 100644 Task/Calendar---for-REAL-programmers/Rust/calendar---for-real-programmers.rs create mode 100644 Task/Calkin-Wilf-sequence/C-sharp/calkin-wilf-sequence.cs create mode 100644 Task/Camel-case-and-snake-case/JavaScript/camel-case-and-snake-case.js create mode 100644 Task/Camel-case-and-snake-case/R/camel-case-and-snake-case.r create mode 100644 Task/Canonicalize-CIDR/Zig/canonicalize-cidr.zig delete mode 100644 Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes-1.rexx delete mode 100644 Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes-2.rexx create mode 100644 Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes.rexx create mode 100644 Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists-1.cpp create mode 100644 Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists-2.cpp delete mode 100644 Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists.cpp create mode 100644 Task/Cartesian-product-of-two-or-more-lists/M2000-Interpreter/cartesian-product-of-two-or-more-lists.m2000 create mode 100644 Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-3.rs create mode 100644 Task/Case-sensitivity-of-identifiers/Ballerina/case-sensitivity-of-identifiers.ballerina create mode 100644 Task/Character-codes/Ballerina/character-codes.ballerina create mode 100644 Task/Character-codes/Crystal/character-codes.cr create mode 100644 Task/Character-codes/OPL/character-codes.opl create mode 100644 Task/Character-codes/S-BASIC/character-codes.basic create mode 100644 Task/Check-input-device-is-a-terminal/Lua/check-input-device-is-a-terminal.lua create mode 100644 Task/Check-that-file-exists/Lua/check-that-file-exists-3.lua delete mode 100644 Task/Chowla-numbers/REXX/chowla-numbers-1.rexx rename Task/Chowla-numbers/REXX/{chowla-numbers-2.rexx => chowla-numbers.rexx} (90%) delete mode 100644 Task/Circular-primes/REXX/circular-primes-1.rexx rename Task/Circular-primes/REXX/{circular-primes-2.rexx => circular-primes.rexx} (77%) create mode 100644 Task/Circular-primes/Scheme/circular-primes.scm create mode 100644 Task/Cistercian-numerals/Ada/cistercian-numerals-1.ada create mode 100644 Task/Cistercian-numerals/Ada/cistercian-numerals-2.ada create mode 100644 Task/Cistercian-numerals/Ada/cistercian-numerals-3.ada create mode 100644 Task/Cistercian-numerals/Ada/cistercian-numerals-4.ada create mode 100644 Task/Cistercian-numerals/Ada/cistercian-numerals-5.ada create mode 100644 Task/Cistercian-numerals/Ada/cistercian-numerals-6.ada create mode 100644 Task/Cistercian-numerals/Ada/cistercian-numerals-7.ada create mode 100644 Task/Cistercian-numerals/Applesoft-BASIC/cistercian-numerals.basic create mode 100644 Task/Cistercian-numerals/Crystal/cistercian-numerals.cr create mode 100644 Task/Cistercian-numerals/FreeBASIC/cistercian-numerals.basic create mode 100644 Task/Classes/Ballerina/classes.ballerina create mode 100644 Task/Closures-Value-capture/Crystal/closures-value-capture.cr create mode 100644 Task/Color-of-a-screen-pixel/UNIX-Shell/color-of-a-screen-pixel.sh create mode 100644 Task/Color-quantization/UNIX-Shell/color-quantization.sh create mode 100644 Task/Color-wheel/C/color-wheel.c create mode 100644 Task/Color-wheel/Emacs-Lisp/color-wheel.l create mode 100644 Task/Colorful-numbers/JavaScript/colorful-numbers.js rename Task/Colour-bars-Display/Python/{colour-bars-display.py => colour-bars-display-1.py} (100%) create mode 100644 Task/Colour-bars-Display/Python/colour-bars-display-2.py create mode 100644 Task/Comma-quibbling/Crystal/comma-quibbling.cr create mode 100644 Task/Comma-quibbling/Elena/comma-quibbling-1.elena create mode 100644 Task/Comma-quibbling/Elena/comma-quibbling-2.elena rename Task/Command-line-arguments/AArch64-Assembly/{command-line-arguments.aarch64 => command-line-arguments-1.aarch64} (100%) create mode 100644 Task/Command-line-arguments/AArch64-Assembly/command-line-arguments-2.aarch64 create mode 100644 Task/Commatizing-numbers/JavaScript/commatizing-numbers.js create mode 100644 Task/Comments/OPL/comments.opl create mode 100644 Task/Comments/Uxntal/comments.uxnatl create mode 100644 Task/Compare-length-of-two-strings/K/compare-length-of-two-strings.k create mode 100644 Task/Compare-length-of-two-strings/M2000-Interpreter/compare-length-of-two-strings-1.m2000 create mode 100644 Task/Compare-length-of-two-strings/M2000-Interpreter/compare-length-of-two-strings-2.m2000 create mode 100644 Task/Compare-length-of-two-strings/OPL/compare-length-of-two-strings-1.opl create mode 100644 Task/Compare-length-of-two-strings/OPL/compare-length-of-two-strings-2.opl create mode 100644 Task/Compare-length-of-two-strings/Scheme/compare-length-of-two-strings.scm create mode 100644 Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-1.rs create mode 100644 Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-2.rs create mode 100644 Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-3.rs create mode 100644 Task/Compiler-AST-interpreter/Rust/compiler-ast-interpreter.rs create mode 100644 Task/Compiler-code-generator/JavaScript/compiler-code-generator.js create mode 100644 Task/Compiler-code-generator/Rust/compiler-code-generator.rs create mode 100644 Task/Compiler-lexical-analyzer/Rust/compiler-lexical-analyzer.rs create mode 100644 Task/Compiler-syntax-analyzer/FreeBASIC/compiler-syntax-analyzer.basic create mode 100644 Task/Compiler-syntax-analyzer/Rust/compiler-syntax-analyzer.rs create mode 100644 Task/Concurrent-computing/Elena/concurrent-computing.elena create mode 100644 Task/Conditional-structures/Excel/conditional-structures-1.excel create mode 100644 Task/Conditional-structures/Excel/conditional-structures-2.excel create mode 100644 Task/Conditional-structures/Excel/conditional-structures-3.excel create mode 100644 Task/Conditional-structures/Uxntal/conditional-structures.uxnatl delete mode 100644 Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences-1.rexx rename Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/{consecutive-primes-with-ascending-or-descending-differences-2.rexx => consecutive-primes-with-ascending-or-descending-differences.rexx} (51%) create mode 100644 Task/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n-/C-sharp/continued-fraction-arithmetic-g-matrix-ng-continued-fraction-n-.cs create mode 100644 Task/Convert-seconds-to-compound-duration/Crystal/convert-seconds-to-compound-duration.cr create mode 100644 Task/Convex-hull/Zig/convex-hull.zig create mode 100644 Task/Copy-a-string/OPL/copy-a-string.opl create mode 100644 Task/Copy-a-string/Uxntal/copy-a-string.uxnatl create mode 100644 Task/Copy-stdin-to-stdout/Objeck/copy-stdin-to-stdout.objeck delete mode 100644 Task/Count-in-factors/REXX/count-in-factors-1.rexx delete mode 100644 Task/Count-in-factors/REXX/count-in-factors-2.rexx rename Task/Count-in-factors/REXX/{count-in-factors-3.rexx => count-in-factors.rexx} (61%) create mode 100644 Task/Count-in-octal/Ballerina/count-in-octal.ballerina create mode 100644 Task/Create-a-file-on-magnetic-tape/JavaScript/create-a-file-on-magnetic-tape.js create mode 100644 Task/Create-a-two-dimensional-array-at-runtime/Uiua/create-a-two-dimensional-array-at-runtime.uiua create mode 100644 Task/Create-an-object-at-a-given-address/XPL0/create-an-object-at-a-given-address.xpl0 create mode 100644 Task/Cuban-primes/OCaml/cuban-primes.ml delete mode 100644 Task/Cuban-primes/REXX/cuban-primes-1.rexx rename Task/Cuban-primes/REXX/{cuban-primes-2.rexx => cuban-primes.rexx} (92%) create mode 100644 Task/Currency/Ballerina/currency.ballerina create mode 100644 Task/Currency/C++/currency.cpp create mode 100644 Task/Currying/Ballerina/currying.ballerina create mode 100644 Task/Curzon-numbers/Ada/curzon-numbers.ada create mode 100644 Task/Cyclotomic-polynomial/JavaScript/cyclotomic-polynomial.js create mode 100644 Task/Cyclotomic-polynomial/Rust/cyclotomic-polynomial.rs create mode 100644 Task/DNS-query/Free-Pascal-Lazarus/dns-query.pas create mode 100644 Task/Damm-algorithm/Uiua/damm-algorithm.uiua create mode 100644 Task/Date-manipulation/Pascal/date-manipulation.pas create mode 100644 Task/De-Bruijn-sequences/JavaScript/de-bruijn-sequences.js create mode 100644 Task/De-Bruijn-sequences/Zig/de-bruijn-sequences.zig create mode 100644 Task/Deconvolution-2D+/FreeBASIC/deconvolution-2d+.basic create mode 100644 Task/Department-numbers/Nu/department-numbers.nu create mode 100644 Task/Descending-primes/Rust/descending-primes-1.rs create mode 100644 Task/Descending-primes/Rust/descending-primes-2.rs create mode 100644 Task/Descending-primes/Rust/descending-primes-3.rs create mode 100644 Task/Descending-primes/Rust/descending-primes-4.rs rename Task/Detect-division-by-zero/REXX/{detect-division-by-zero.rexx => detect-division-by-zero-1.rexx} (100%) create mode 100644 Task/Detect-division-by-zero/REXX/detect-division-by-zero-2.rexx create mode 100644 Task/Detect-division-by-zero/REXX/detect-division-by-zero-3.rexx create mode 100644 Task/Determine-if-a-string-has-all-the-same-characters/Crystal/determine-if-a-string-has-all-the-same-characters.cr create mode 100644 Task/Determine-if-a-string-has-all-the-same-characters/Nu/determine-if-a-string-has-all-the-same-characters-1.nu create mode 100644 Task/Determine-if-a-string-has-all-the-same-characters/Nu/determine-if-a-string-has-all-the-same-characters-2.nu create mode 100644 Task/Determine-if-a-string-is-collapsible/Crystal/determine-if-a-string-is-collapsible.cr create mode 100644 Task/Determine-sentence-type/R/determine-sentence-type.r create mode 100644 Task/Dice-game-probabilities/Arturo/dice-game-probabilities.arturo create mode 100644 Task/Dice-game-probabilities/Quackery/dice-game-probabilities.quackery delete mode 100644 Task/Digital-root/REXX/digital-root-3.rexx delete mode 100644 Task/Digital-root/REXX/digital-root-4.rexx create mode 100644 Task/Dijkstras-algorithm/Crystal/dijkstras-algorithm.cr create mode 100644 Task/Dijkstras-algorithm/Zig/dijkstras-algorithm.zig create mode 100644 Task/Disarium-numbers/PARI-GP/disarium-numbers.parigp create mode 100644 Task/Disarium-numbers/R/disarium-numbers.r create mode 100644 Task/Display-a-linear-combination/R/display-a-linear-combination.r create mode 100644 Task/Distributed-programming/Objeck/distributed-programming.objeck create mode 100644 Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC/distribution-of-0-digits-in-factorial-series-1.basic create mode 100644 Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC/distribution-of-0-digits-in-factorial-series-2.basic create mode 100644 Task/Distribution-of-0-digits-in-factorial-series/JavaScript/distribution-of-0-digits-in-factorial-series.js create mode 100644 Task/Doubly-linked-list-Definition/Rust/doubly-linked-list-definition-1.rs create mode 100644 Task/Doubly-linked-list-Definition/Rust/doubly-linked-list-definition-2.rs delete mode 100644 Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition-1.rs delete mode 100644 Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition-2.rs create mode 100644 Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition.rs create mode 100644 Task/Doubly-linked-list-Traversal/Rust/doubly-linked-list-traversal.rs create mode 100644 Task/Draw-a-clock/OPL/draw-a-clock.opl create mode 100644 Task/Draw-a-cuboid/R/draw-a-cuboid.r create mode 100644 Task/Draw-a-pixel/OPL/draw-a-pixel.opl delete mode 100644 Task/Draw-a-pixel/Uxntal/draw-a-pixel.uxnatl create mode 100644 Task/Dutch-national-flag-problem/Crystal/dutch-national-flag-problem.cr create mode 100644 Task/Dutch-national-flag-problem/R/dutch-national-flag-problem.r create mode 100644 Task/Dynamic-variable-names/Ballerina/dynamic-variable-names.ballerina create mode 100644 Task/Element-wise-operations/Arturo/element-wise-operations.arturo create mode 100644 Task/Element-wise-operations/EasyLang/element-wise-operations.easy rename Task/Element-wise-operations/K/{element-wise-operations.k => element-wise-operations-1.k} (100%) create mode 100644 Task/Element-wise-operations/K/element-wise-operations-2.k create mode 100644 Task/Elliptic-Curve-Digital-Signature-Algorithm/C-sharp/elliptic-curve-digital-signature-algorithm.cs create mode 100644 Task/Elliptic-Curve-Digital-Signature-Algorithm/JavaScript/elliptic-curve-digital-signature-algorithm.js create mode 100644 Task/Elliptic-Curve-Digital-Signature-Algorithm/Rust/elliptic-curve-digital-signature-algorithm.rs create mode 100644 Task/Elliptic-curve-arithmetic/ALGOL-68/elliptic-curve-arithmetic.alg create mode 100644 Task/Elliptic-curve-arithmetic/FreeBASIC/elliptic-curve-arithmetic.basic create mode 100644 Task/Elliptic-curve-arithmetic/JavaScript/elliptic-curve-arithmetic.js delete mode 100644 Task/Emirp-primes/REXX/emirp-primes-3.rexx create mode 100644 Task/Empty-string/Ballerina/empty-string.ballerina create mode 100644 Task/Entropy-Narcissist/Arturo/entropy-narcissist.arturo create mode 100644 Task/Ethiopian-multiplication/Uiua/ethiopian-multiplication.uiua create mode 100644 Task/Euler-method/K/euler-method.k create mode 100644 Task/Euler-method/Odin/euler-method.odin create mode 100644 Task/Euler-method/Q/euler-method.q create mode 100644 Task/Eulers-constant-0.5772.../Fortran/eulers-constant-0.5772....f create mode 100644 Task/Evaluate-binomial-coefficients/Asymptote/evaluate-binomial-coefficients.asymptote create mode 100644 Task/Evaluate-binomial-coefficients/BASIC256/evaluate-binomial-coefficients.basic create mode 100644 Task/Evaluate-binomial-coefficients/Chipmunk-Basic/evaluate-binomial-coefficients.basic create mode 100644 Task/Evaluate-binomial-coefficients/Gambas/evaluate-binomial-coefficients.gambas create mode 100644 Task/Evaluate-binomial-coefficients/MSX-Basic/evaluate-binomial-coefficients.basic create mode 100644 Task/Evaluate-binomial-coefficients/Minimal-BASIC/evaluate-binomial-coefficients.basic create mode 100644 Task/Evaluate-binomial-coefficients/OxygenBasic/evaluate-binomial-coefficients.basic create mode 100644 Task/Evaluate-binomial-coefficients/Prolog/evaluate-binomial-coefficients.pro create mode 100644 Task/Evaluate-binomial-coefficients/QBasic/evaluate-binomial-coefficients.basic create mode 100644 Task/Evaluate-binomial-coefficients/True-BASIC/evaluate-binomial-coefficients-1.basic create mode 100644 Task/Evaluate-binomial-coefficients/True-BASIC/evaluate-binomial-coefficients-2.basic create mode 100644 Task/Evaluate-binomial-coefficients/Yabasic/evaluate-binomial-coefficients.basic create mode 100644 Task/Execute-Brain-/Crystal/execute-brain-.cr create mode 100644 Task/Execute-Brain-/Odin/execute-brain-.odin create mode 100644 Task/Execute-Computer-Zero/Perl/execute-computer-zero.pl create mode 100644 Task/Execute-a-Markov-algorithm/C-sharp/execute-a-markov-algorithm.cs create mode 100644 Task/Execute-a-Markov-algorithm/Zig/execute-a-markov-algorithm.zig create mode 100644 Task/Extensible-prime-generator/C-sharp/extensible-prime-generator.cs delete mode 100644 Task/Extensible-prime-generator/REXX/extensible-prime-generator-1.rexx delete mode 100644 Task/Extensible-prime-generator/REXX/extensible-prime-generator-3.rexx rename Task/Extensible-prime-generator/REXX/{extensible-prime-generator-2.rexx => extensible-prime-generator.rexx} (54%) create mode 100644 Task/Extreme-floating-point-values/Ballerina/extreme-floating-point-values.ballerina create mode 100644 Task/Factorial/Java/factorial-4.java delete mode 100644 Task/Factorial/REXX/factorial-3.rexx delete mode 100644 Task/Factorial/REXX/factorial-4.rexx delete mode 100644 Task/Factorial/REXX/factorial-5.rexx create mode 100644 Task/Factorial/SQL/factorial.sql create mode 100644 Task/Factorial/Tcl/factorial-7.tcl create mode 100644 Task/Factorions/EasyLang/factorions.easy create mode 100644 Task/Factorions/R/factorions.r delete mode 100644 Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number-1.rexx rename Task/Factors-of-a-Mersenne-number/REXX/{factors-of-a-mersenne-number-2.rexx => factors-of-a-mersenne-number.rexx} (72%) delete mode 100644 Task/Factors-of-an-integer/REXX/factors-of-an-integer-3.rexx create mode 100644 Task/Farey-sequence/Ballerina/farey-sequence.ballerina create mode 100644 Task/Faulhabers-formula/Rust/faulhabers-formula.rs delete mode 100644 Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation-1.rexx rename Task/Feigenbaum-constant-calculation/REXX/{feigenbaum-constant-calculation-2.rexx => feigenbaum-constant-calculation.rexx} (72%) create mode 100644 Task/Fermat-numbers/FreeBASIC/fermat-numbers.basic delete mode 100644 Task/Fermat-numbers/REXX/fermat-numbers-1.rexx delete mode 100644 Task/Fermat-numbers/REXX/fermat-numbers-2.rexx rename Task/Fermat-numbers/REXX/{fermat-numbers-3.rexx => fermat-numbers.rexx} (78%) create mode 100644 Task/Fibonacci-sequence/APL/fibonacci-sequence-5.apl create mode 100644 Task/Fibonacci-sequence/Uxntal/fibonacci-sequence.uxnatl create mode 100644 Task/Fibonacci-sequence/Zig/fibonacci-sequence.zig create mode 100644 Task/File-extension-is-in-extensions-list/C-sharp/file-extension-is-in-extensions-list.cs create mode 100644 Task/File-extension-is-in-extensions-list/M2000-Interpreter/file-extension-is-in-extensions-list.m2000 create mode 100644 Task/File-extension-is-in-extensions-list/Nu/file-extension-is-in-extensions-list.nu create mode 100644 Task/File-size-distribution/Nu/file-size-distribution.nu create mode 100644 Task/File-size-distribution/Tcl/file-size-distribution-1.tcl rename Task/File-size-distribution/Tcl/{file-size-distribution.tcl => file-size-distribution-2.tcl} (100%) create mode 100644 Task/Find-Chess960-starting-position-identifier/D/find-chess960-starting-position-identifier.d create mode 100644 Task/Find-common-directory-path/BQN/find-common-directory-path.bqn create mode 100644 Task/Find-if-a-point-is-within-a-triangle/C-sharp/find-if-a-point-is-within-a-triangle.cs create mode 100644 Task/Find-limit-of-recursion/Ballerina/find-limit-of-recursion.ballerina create mode 100644 Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/R/find-palindromic-numbers-in-both-binary-and-ternary-bases.r create mode 100644 Task/Find-the-missing-permutation/Zig/find-the-missing-permutation.zig create mode 100644 Task/First-perfect-square-in-base-n-with-n-unique-digits/Fortran/first-perfect-square-in-base-n-with-n-unique-digits.f create mode 100644 Task/Fivenum/Ballerina/fivenum.ballerina create mode 100644 Task/FizzBuzz/APL/fizzbuzz-7.apl rename Task/FizzBuzz/Erlang/{fizzbuzz.erl => fizzbuzz-1.erl} (100%) create mode 100644 Task/FizzBuzz/Erlang/fizzbuzz-2.erl create mode 100644 Task/FizzBuzz/Excel/fizzbuzz.excel create mode 100644 Task/FizzBuzz/Factor/fizzbuzz-4.factor create mode 100644 Task/FizzBuzz/J/fizzbuzz-10.j create mode 100644 Task/FizzBuzz/J/fizzbuzz-11.j create mode 100644 Task/FizzBuzz/J/fizzbuzz-8.j create mode 100644 Task/FizzBuzz/J/fizzbuzz-9.j delete mode 100644 Task/FizzBuzz/Pascal/fizzbuzz.pas create mode 100644 Task/FizzBuzz/Python/fizzbuzz-14.py create mode 100644 Task/FizzBuzz/Smalltalk/fizzbuzz-7.st create mode 100644 Task/Flow-control-structures/Uxntal/flow-control-structures.uxnatl create mode 100644 Task/Floyd-Warshall-algorithm/XPL0/floyd-warshall-algorithm.xpl0 create mode 100644 Task/Floyd-Warshall-algorithm/Zig/floyd-warshall-algorithm.zig create mode 100644 Task/Floyds-triangle/Ballerina/floyds-triangle.ballerina create mode 100644 Task/Floyds-triangle/Objeck/floyds-triangle.objeck create mode 100644 Task/Forest-fire/J/forest-fire-3.j create mode 100644 Task/Forest-fire/J/forest-fire-4.j rename Task/Formatted-numeric-output/ALGOL-68/{formatted-numeric-output.alg => formatted-numeric-output-1.alg} (100%) create mode 100644 Task/Formatted-numeric-output/ALGOL-68/formatted-numeric-output-2.alg create mode 100644 Task/Formatted-numeric-output/Applesoft-BASIC/formatted-numeric-output.basic delete mode 100644 Task/Fortunate-numbers/REXX/fortunate-numbers-1.rexx rename Task/Fortunate-numbers/REXX/{fortunate-numbers-2.rexx => fortunate-numbers.rexx} (92%) create mode 100644 Task/Four-bit-adder/Ballerina/four-bit-adder.ballerina create mode 100644 Task/Fractran/Odin/fractran.odin create mode 100644 Task/Function-definition/Ballerina/function-definition.ballerina create mode 100644 Task/Function-definition/Excel/function-definition.excel create mode 100644 Task/Gapful-numbers/Ballerina/gapful-numbers.ballerina create mode 100644 Task/Gauss-Jordan-matrix-inversion/JavaScript/gauss-jordan-matrix-inversion.js create mode 100644 Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-4.d create mode 100644 Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-5.d create mode 100644 Task/Generate-Chess960-starting-position/Delphi/generate-chess960-starting-position.pas create mode 100644 Task/Generate-Chess960-starting-position/Rust/generate-chess960-starting-position-3.rs create mode 100644 Task/Generate-lower-case-ASCII-alphabet/Objeck/generate-lower-case-ascii-alphabet.objeck rename Task/Generate-lower-case-ASCII-alphabet/Rust/{generate-lower-case-ascii-alphabet.rs => generate-lower-case-ascii-alphabet-1.rs} (100%) create mode 100644 Task/Generate-lower-case-ASCII-alphabet/Rust/generate-lower-case-ascii-alphabet-2.rs rename Task/Generator-Exponential/Tcl/{generator-exponential.tcl => generator-exponential-1.tcl} (100%) create mode 100644 Task/Generator-Exponential/Tcl/generator-exponential-2.tcl create mode 100644 Task/Generator-Exponential/Tcl/generator-exponential-3.tcl create mode 100644 Task/Globally-replace-text-in-several-files/BQN/globally-replace-text-in-several-files.bqn create mode 100644 Task/Goldbachs-comet/Go/goldbachs-comet.go create mode 100644 Task/Gotchas/C-sharp/gotchas.cs create mode 100644 Task/Graph-colouring/FreeBASIC/graph-colouring.basic create mode 100644 Task/Graph-colouring/JavaScript/graph-colouring.js create mode 100644 Task/Graph-colouring/Rust/graph-colouring.rs create mode 100644 Task/Gray-code/SETL/gray-code.setl create mode 100644 Task/Greatest-subsequential-sum/Ballerina/greatest-subsequential-sum.ballerina create mode 100644 Task/Greatest-subsequential-sum/M2000-Interpreter/greatest-subsequential-sum-1.m2000 create mode 100644 Task/Greatest-subsequential-sum/M2000-Interpreter/greatest-subsequential-sum-2.m2000 create mode 100644 Task/Greedy-algorithm-for-Egyptian-fractions/JavaScript/greedy-algorithm-for-egyptian-fractions.js create mode 100644 Task/HTTP/Elena/http.elena create mode 100644 Task/HTTPS/Elena/https.elena create mode 100644 Task/Hailstone-sequence/Ballerina/hailstone-sequence.ballerina create mode 100644 Task/Hailstone-sequence/Odin/hailstone-sequence.odin create mode 100644 Task/Halt-and-catch-fire/R/halt-and-catch-fire-1.r create mode 100644 Task/Halt-and-catch-fire/R/halt-and-catch-fire-2.r delete mode 100644 Task/Hamming-numbers/REXX/hamming-numbers-1.rexx delete mode 100644 Task/Hamming-numbers/REXX/hamming-numbers-2.rexx delete mode 100644 Task/Hamming-numbers/REXX/hamming-numbers-3.rexx delete mode 100644 Task/Hamming-numbers/REXX/hamming-numbers-4.rexx create mode 100644 Task/Hamming-numbers/REXX/hamming-numbers.rexx create mode 100644 Task/Harmonic-series/Fortran/harmonic-series.f rename Task/Hello-world-Graphical/{Autohotkey-V2 => AutoHotKey-V2}/hello-world-graphical.ahk (100%) create mode 100644 Task/Hello-world-Graphical/Odin/hello-world-graphical.odin create mode 100644 Task/Hello-world-Graphical/Uxntal/hello-world-graphical.uxnatl create mode 100644 Task/Hello-world-Newline-omission/Ballerina/hello-world-newline-omission.ballerina rename Task/Hello-world-Standard-error/AArch64-Assembly/{hello-world-standard-error.aarch64 => hello-world-standard-error-1.aarch64} (100%) create mode 100644 Task/Hello-world-Standard-error/AArch64-Assembly/hello-world-standard-error-2.aarch64 create mode 100644 Task/Hello-world-Standard-error/Ballerina/hello-world-standard-error.ballerina create mode 100644 Task/Hello-world-Standard-error/Crystal/hello-world-standard-error.cr create mode 100644 Task/Hello-world-Standard-error/Objeck/hello-world-standard-error.objeck create mode 100644 Task/Hello-world-Standard-error/Uxntal/hello-world-standard-error.uxnatl rename Task/Hello-world-Text/AArch64-Assembly/{hello-world-text.aarch64 => hello-world-text-1.aarch64} (100%) create mode 100644 Task/Hello-world-Text/AArch64-Assembly/hello-world-text-2.aarch64 create mode 100644 Task/Hello-world-Text/AArch64-Assembly/hello-world-text-3.aarch64 create mode 100644 Task/Hello-world-Text/OPL/hello-world-text.opl delete mode 100644 Task/Hello-world-Text/Uxntal/hello-world-text.uxnatl create mode 100644 Task/Hex-words/Crystal/hex-words.cr create mode 100644 Task/Hex-words/R/hex-words.r create mode 100644 Task/Hex-words/Rust/hex-words.rs delete mode 100644 Task/Higher-order-functions/REXX/higher-order-functions-2.rexx rename Task/Higher-order-functions/REXX/{higher-order-functions-1.rexx => higher-order-functions.rexx} (69%) delete mode 100644 Task/Home-primes/REXX/home-primes-1.rexx delete mode 100644 Task/Home-primes/REXX/home-primes-2.rexx create mode 100644 Task/Home-primes/REXX/home-primes.rexx delete mode 100644 Task/Humble-numbers/REXX/humble-numbers-1.rexx delete mode 100644 Task/Humble-numbers/REXX/humble-numbers-2.rexx create mode 100644 Task/Humble-numbers/REXX/humble-numbers.rexx create mode 100644 Task/I-before-E-except-after-C/Nu/i-before-e-except-after-c-1.nu create mode 100644 Task/I-before-E-except-after-C/Nu/i-before-e-except-after-c-2.nu rename Task/Identity-matrix/Excel/{identity-matrix.excel => identity-matrix-1.excel} (100%) create mode 100644 Task/Identity-matrix/Excel/identity-matrix-2.excel create mode 100644 Task/Im-a-software-engineer-get-me-out-of-here/Python/im-a-software-engineer-get-me-out-of-here.py create mode 100644 Task/Increment-a-numerical-string/Crystal/increment-a-numerical-string.cr create mode 100644 Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-1.tcl create mode 100644 Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-2.tcl create mode 100644 Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-3.tcl create mode 100644 Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-4.tcl create mode 100644 Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-5.tcl create mode 100644 Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-6.tcl delete mode 100644 Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string.tcl create mode 100644 Task/Index-finite-lists-of-positive-integers/C-sharp/index-finite-lists-of-positive-integers.cs rename Task/Input-loop/JavaScript/{input-loop.js => input-loop-1.js} (100%) create mode 100644 Task/Input-loop/JavaScript/input-loop-2.js create mode 100644 Task/Integer-sequence/Uxntal/integer-sequence.uxnatl create mode 100644 Task/Interactive-programming-repl-/Crystal/interactive-programming-repl-.cr rename Task/Inverted-syntax/Ruby/{inverted-syntax.rb => inverted-syntax-1.rb} (100%) create mode 100644 Task/Inverted-syntax/Ruby/inverted-syntax-2.rb create mode 100644 Task/Isqrt-integer-square-root-of-X/JavaScript/isqrt-integer-square-root-of-x.js create mode 100644 Task/Jacobi-symbol/JavaScript/jacobi-symbol.js create mode 100644 Task/Juggler-sequence/FreeBASIC/juggler-sequence.basic create mode 100644 Task/K-d-tree/C-sharp/k-d-tree.cs create mode 100644 Task/K-d-tree/Dart/k-d-tree.dart create mode 100644 Task/K-d-tree/JavaScript/k-d-tree.js create mode 100644 Task/Kernighans-large-earthquake-problem/R/kernighans-large-earthquake-problem.r create mode 100644 Task/Keyboard-input-Flush-the-keyboard-buffer/Emacs-Lisp/keyboard-input-flush-the-keyboard-buffer.l create mode 100644 Task/Keyboard-input-Keypress-check/Emacs-Lisp/keyboard-input-keypress-check.l create mode 100644 Task/Keyboard-input-Obtain-a-Y-or-N-response/Emacs-Lisp/keyboard-input-obtain-a-y-or-n-response.l create mode 100644 Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-3.tcl create mode 100644 Task/Knuth-shuffle/Objeck/knuth-shuffle.objeck create mode 100644 Task/Knuth-shuffle/Wisp/knuth-shuffle.wisp create mode 100644 Task/Knuths-algorithm-S/Fortran/knuths-algorithm-s.f create mode 100644 Task/Knuths-algorithm-S/FreeBASIC/knuths-algorithm-s.basic create mode 100644 Task/Knuths-algorithm-S/JavaScript/knuths-algorithm-s.js create mode 100644 Task/Knuths-power-tree/FreeBASIC/knuths-power-tree.basic create mode 100644 Task/Knuths-power-tree/JavaScript/knuths-power-tree.js create mode 100644 Task/Kosaraju/Rust/kosaraju.rs create mode 100644 Task/Largest-int-from-concatenated-ints/XPL0/largest-int-from-concatenated-ints.xpl0 create mode 100644 Task/Largest-proper-divisor-of-n/ALGOL-60/largest-proper-divisor-of-n.alg create mode 100644 Task/Last-letter-first-letter/FreeBASIC/last-letter-first-letter.basic create mode 100644 Task/Last-letter-first-letter/XPL0/last-letter-first-letter.xpl0 create mode 100644 Task/Latin-Squares-in-reduced-form/Rust/latin-squares-in-reduced-form.rs create mode 100644 Task/Latin-Squares-in-reduced-form/Zig/latin-squares-in-reduced-form.zig create mode 100644 Task/Leonardo-numbers/ERRE/leonardo-numbers.erre rename Task/Letter-frequency/Nu/{letter-frequency.nu => letter-frequency-1.nu} (100%) create mode 100644 Task/Letter-frequency/Nu/letter-frequency-2.nu create mode 100644 Task/Levenshtein-distance/ANSI-BASIC/levenshtein-distance.basic create mode 100644 Task/Levenshtein-distance/Applesoft-BASIC/levenshtein-distance.basic create mode 100644 Task/Levenshtein-distance/Ballerina/levenshtein-distance.ballerina create mode 100644 Task/Levenshtein-distance/Free-Pascal-Lazarus/levenshtein-distance.pas create mode 100644 Task/Levenshtein-distance/GW-BASIC/levenshtein-distance.basic create mode 100644 Task/Levenshtein-distance/Nascom-BASIC/levenshtein-distance.basic delete mode 100644 Task/Levenshtein-distance/Pascal/levenshtein-distance.pas create mode 100644 Task/Levenshtein-distance/RapidQ/levenshtein-distance.rapidq create mode 100644 Task/Levenshtein-distance/XBasic/levenshtein-distance.basic create mode 100644 Task/Levenshtein-distance/XPL0/levenshtein-distance.xpl0 delete mode 100644 Task/Literals-Floating-point/REXX/literals-floating-point-1.rexx delete mode 100644 Task/Literals-Floating-point/REXX/literals-floating-point-2.rexx create mode 100644 Task/Literals-Floating-point/REXX/literals-floating-point.rexx delete mode 100644 Task/Long-primes/REXX/long-primes-1.rexx delete mode 100644 Task/Long-primes/REXX/long-primes-2.rexx delete mode 100644 Task/Long-primes/REXX/long-primes-3.rexx create mode 100644 Task/Long-primes/REXX/long-primes.rexx create mode 100644 Task/Longest-string-challenge/C-sharp/longest-string-challenge.cs create mode 100644 Task/Look-and-say-sequence/MAD/look-and-say-sequence.mad create mode 100644 Task/Look-and-say-sequence/Python/look-and-say-sequence-5.py create mode 100644 Task/Loop-over-multiple-arrays-simultaneously/Ballerina/loop-over-multiple-arrays-simultaneously.ballerina create mode 100644 Task/Loops-Break/Ballerina/loops-break.ballerina create mode 100644 Task/Loops-Break/Uxntal/loops-break.uxnatl create mode 100644 Task/Loops-Continue/Ballerina/loops-continue.ballerina create mode 100644 Task/Loops-Continue/Uxntal/loops-continue.uxnatl create mode 100644 Task/Loops-Do-while/Ballerina/loops-do-while-1.ballerina create mode 100644 Task/Loops-Do-while/Ballerina/loops-do-while-2.ballerina create mode 100644 Task/Loops-Do-while/SETL/loops-do-while.setl create mode 100644 Task/Loops-Do-while/Uxntal/loops-do-while.uxnatl create mode 100644 Task/Loops-Downward-for/Ballerina/loops-downward-for.ballerina create mode 100644 Task/Loops-For-with-a-specified-step/Ballerina/loops-for-with-a-specified-step.ballerina create mode 100644 Task/Loops-For-with-a-specified-step/Uxntal/loops-for-with-a-specified-step.uxnatl create mode 100644 Task/Loops-For/Ballerina/loops-for.ballerina create mode 100644 Task/Loops-For/Excel/loops-for.excel create mode 100644 Task/Loops-For/M2000-Interpreter/loops-for-1.m2000 create mode 100644 Task/Loops-For/M2000-Interpreter/loops-for-2.m2000 delete mode 100644 Task/Loops-For/M2000-Interpreter/loops-for.m2000 create mode 100644 Task/Loops-Foreach/Ballerina/loops-foreach.ballerina create mode 100644 Task/Loops-Foreach/Uxntal/loops-foreach.uxnatl create mode 100644 Task/Loops-Increment-loop-index-within-loop-body/ALGOL-60/loops-increment-loop-index-within-loop-body.alg create mode 100644 Task/Loops-Increment-loop-index-within-loop-body/Ballerina/loops-increment-loop-index-within-loop-body.ballerina create mode 100644 Task/Loops-Increment-loop-index-within-loop-body/Icon/loops-increment-loop-index-within-loop-body.icon create mode 100644 Task/Loops-Increment-loop-index-within-loop-body/S-BASIC/loops-increment-loop-index-within-loop-body.basic create mode 100644 Task/Loops-Increment-loop-index-within-loop-body/SETL/loops-increment-loop-index-within-loop-body.setl create mode 100644 Task/Loops-Infinite/8080-Assembly/loops-infinite.8080 create mode 100644 Task/Loops-Infinite/APL/loops-infinite.apl create mode 100644 Task/Loops-Infinite/Ballerina/loops-infinite.ballerina create mode 100644 Task/Loops-Infinite/J/loops-infinite-3.j create mode 100644 Task/Loops-Infinite/K/loops-infinite-1.k create mode 100644 Task/Loops-Infinite/K/loops-infinite-2.k delete mode 100644 Task/Loops-Infinite/K/loops-infinite.k create mode 100644 Task/Loops-Infinite/Miranda/loops-infinite.miranda create mode 100644 Task/Loops-Infinite/Refal/loops-infinite.refal create mode 100644 Task/Loops-Infinite/SETL/loops-infinite.setl create mode 100644 Task/Loops-N-plus-one-half/Ballerina/loops-n-plus-one-half.ballerina create mode 100644 Task/Loops-N-plus-one-half/Crystal/loops-n-plus-one-half.cr create mode 100644 Task/Loops-N-plus-one-half/Uxntal/loops-n-plus-one-half.uxnatl create mode 100644 Task/Loops-Nested/Ballerina/loops-nested.ballerina create mode 100644 Task/Loops-While/Uxntal/loops-while.uxnatl create mode 100644 Task/Loops-With-multiple-ranges/Ballerina/loops-with-multiple-ranges.ballerina create mode 100644 Task/Loops-Wrong-ranges/Ballerina/loops-wrong-ranges.ballerina rename Task/Lucas-Lehmer-test/Raku/{lucas-lehmer-test.raku => lucas-lehmer-test-1.raku} (100%) create mode 100644 Task/Lucas-Lehmer-test/Raku/lucas-lehmer-test-2.raku rename Task/Luhn-test-of-credit-card-numbers/Lua/{luhn-test-of-credit-card-numbers.lua => luhn-test-of-credit-card-numbers-1.lua} (75%) create mode 100644 Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-2.lua create mode 100644 Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-3.lua create mode 100644 Task/M-bius-function/ANSI-BASIC/m-bius-function.basic create mode 100644 Task/M-bius-function/ASIC/m-bius-function.asic create mode 100644 Task/M-bius-function/JavaScript/m-bius-function-1.js create mode 100644 Task/M-bius-function/JavaScript/m-bius-function-2.js create mode 100644 Task/M-bius-function/K/m-bius-function.k create mode 100644 Task/M-bius-function/Modula-2/m-bius-function.mod2 create mode 100644 Task/M-bius-function/PHP/m-bius-function.php delete mode 100644 Task/M-bius-function/REXX/m-bius-function-1.rexx delete mode 100644 Task/M-bius-function/REXX/m-bius-function-2.rexx create mode 100644 Task/M-bius-function/REXX/m-bius-function.rexx create mode 100644 Task/M-bius-function/RapidQ/m-bius-function.rapidq create mode 100644 Task/MD5-Implementation/JavaScript/md5-implementation.js create mode 100644 Task/Mad-Libs/EasyLang/mad-libs.easy create mode 100644 Task/Mad-Libs/F-Sharp/mad-libs.fs create mode 100644 Task/Mad-Libs/Objeck/mad-libs.objeck create mode 100644 Task/Magic-8-ball/Crystal/magic-8-ball.cr create mode 100644 Task/Magic-constant/ANSI-BASIC/magic-constant.basic create mode 100644 Task/Magic-constant/C/magic-constant.c create mode 100644 Task/Magic-constant/GW-BASIC/magic-constant.basic create mode 100644 Task/Magic-constant/Gambas/magic-constant.gambas create mode 100644 Task/Magic-constant/Modula-2/magic-constant.mod2 create mode 100644 Task/Magic-constant/PHP/magic-constant.php create mode 100644 Task/Magic-constant/REXX/magic-constant.rexx create mode 100644 Task/Magic-constant/Tiny-BASIC/magic-constant.basic create mode 100644 Task/Map-range/ANSI-BASIC/map-range.basic create mode 100644 Task/Map-range/Free-Pascal-Lazarus/map-range-1.pas create mode 100644 Task/Map-range/Free-Pascal-Lazarus/map-range-2.pas create mode 100644 Task/Map-range/GW-BASIC/map-range.basic create mode 100644 Task/Map-range/Modula-2/map-range.mod2 create mode 100644 Task/Map-range/PHP/map-range.php delete mode 100644 Task/Map-range/Pascal/map-range-1.pas delete mode 100644 Task/Map-range/Pascal/map-range-2.pas create mode 100644 Task/Map-range/QBasic/map-range.basic create mode 100644 Task/Map-range/RapidQ/map-range.rapidq create mode 100644 Task/Map-range/TypeScript/map-range.ts create mode 100644 Task/Matrix-transposition/Uiua/matrix-transposition.uiua create mode 100644 Task/Median-filter/Rust/median-filter.rs rename Task/Merge-and-aggregate-datasets/FreeBASIC/{merge-and-aggregate-datasets.basic => merge-and-aggregate-datasets-1.basic} (100%) create mode 100644 Task/Merge-and-aggregate-datasets/FreeBASIC/merge-and-aggregate-datasets-2.basic create mode 100644 Task/Merge-and-aggregate-datasets/Logo/merge-and-aggregate-datasets-1.logo create mode 100644 Task/Merge-and-aggregate-datasets/Logo/merge-and-aggregate-datasets-2.logo rename Task/Morse-code/Java/{morse-code.java => morse-code-1.java} (100%) create mode 100644 Task/Morse-code/Java/morse-code-2.java create mode 100644 Task/Move-to-front-algorithm/Zig/move-to-front-algorithm.zig create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-1.basic create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-2.basic create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-3.basic create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-4.basic create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-5.basic create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-6.basic create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-7.basic create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-8.basic create mode 100644 Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-9.basic rename Task/Multi-dimensional-array/C++/{multi-dimensional-array.cpp => multi-dimensional-array-1.cpp} (88%) create mode 100644 Task/Multi-dimensional-array/C++/multi-dimensional-array-2.cpp create mode 100644 Task/Multiplication-tables/Objeck/multiplication-tables.objeck create mode 100644 Task/Munchausen-numbers/J/munchausen-numbers-3.j create mode 100644 Task/Munchausen-numbers/R/munchausen-numbers.r create mode 100644 Task/Munching-squares/Arturo/munching-squares.arturo create mode 100644 Task/Munching-squares/Uiua/munching-squares.uiua create mode 100644 Task/N-queens-problem/Jq/n-queens-problem-6.jq create mode 100644 Task/N-queens-problem/Jq/n-queens-problem-7.jq create mode 100644 Task/N-queens-problem/Python/n-queens-problem-10.py create mode 100644 Task/Natural-sorting/FreeBASIC/natural-sorting.basic create mode 100644 Task/Natural-sorting/JavaScript/natural-sorting-1.js rename Task/Natural-sorting/JavaScript/{natural-sorting.js => natural-sorting-2.js} (100%) create mode 100644 Task/Natural-sorting/Rust/natural-sorting.rs create mode 100644 Task/Natural-sorting/Zig/natural-sorting.zig create mode 100644 Task/Non-decimal-radices-Convert/Crystal/non-decimal-radices-convert.cr create mode 100644 Task/Nonogram-solver/Rust/nonogram-solver.rs create mode 100644 Task/Nth-root/AppleScript/nth-root.applescript delete mode 100644 Task/Numerical-integration-Gauss-Legendre-Quadrature/REXX/numerical-integration-gauss-legendre-quadrature-3.rexx rename Task/Numerical-integration/Julia/{numerical-integration.jl => numerical-integration-1.jl} (100%) create mode 100644 Task/Numerical-integration/Julia/numerical-integration-2.jl create mode 100644 Task/Old-Russian-measure-of-length/R/old-russian-measure-of-length.r create mode 100644 Task/OpenWebNet-password/Rust/openwebnet-password.rs create mode 100644 Task/Order-by-pair-comparisons/Crystal/order-by-pair-comparisons.cr create mode 100644 Task/Order-two-numerical-lists/Crystal/order-two-numerical-lists.cr create mode 100644 Task/P-Adic-numbers-basic/C-sharp/p-adic-numbers-basic.cs create mode 100644 Task/P-Adic-numbers-basic/JavaScript/p-adic-numbers-basic.js create mode 100644 Task/P-Adic-numbers-basic/Rust/p-adic-numbers-basic.rs create mode 100644 Task/P-Adic-numbers-basic/Zig/p-adic-numbers-basic.zig create mode 100644 Task/P-Adic-square-roots/Go/p-adic-square-roots.go create mode 100644 Task/P-Adic-square-roots/JavaScript/p-adic-square-roots.js create mode 100644 Task/P-Adic-square-roots/Rust/p-adic-square-roots.rs create mode 100644 Task/P-Adic-square-roots/Zig/p-adic-square-roots.zig create mode 100644 Task/Pancake-numbers/PascalABC.NET/pancake-numbers.pas create mode 100644 Task/Pangram-checker/PascalABC.NET/pangram-checker.pas create mode 100644 Task/Pangram-checker/Uiua/pangram-checker.uiua create mode 100644 Task/Paraffins/PascalABC.NET/paraffins.pas create mode 100644 Task/Parallel-calculations/PascalABC.NET/parallel-calculations.pas create mode 100644 Task/Parse-an-IP-Address/Erlang/parse-an-ip-address.erl create mode 100644 Task/Parse-an-IP-Address/Lua/parse-an-ip-address-1.lua create mode 100644 Task/Parse-an-IP-Address/Lua/parse-an-ip-address-2.lua create mode 100644 Task/Parsing-RPN-calculator-algorithm/PascalABC.NET/parsing-rpn-calculator-algorithm.pas create mode 100644 Task/Parsing-RPN-calculator-algorithm/Zig/parsing-rpn-calculator-algorithm.zig create mode 100644 Task/Parsing-Shunting-yard-algorithm/Zig/parsing-shunting-yard-algorithm.zig create mode 100644 Task/Partition-an-integer-x-into-n-primes/BASIC/partition-an-integer-x-into-n-primes.basic create mode 100644 Task/Partition-an-integer-x-into-n-primes/PascalABC.NET/partition-an-integer-x-into-n-primes.pas create mode 100644 Task/Pascal-matrix-generation/PascalABC.NET/pascal-matrix-generation.pas create mode 100644 Task/Pascals-triangle-Puzzle/PascalABC.NET/pascals-triangle-puzzle.pas create mode 100644 Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-1.hs create mode 100644 Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-2.hs create mode 100644 Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-3.hs create mode 100644 Task/Pathological-floating-point-problems/PascalABC.NET/pathological-floating-point-problems.pas create mode 100644 Task/Pells-equation/PascalABC.NET/pells-equation.pas create mode 100644 Task/Penneys-game/Dart/penneys-game.dart create mode 100644 Task/Perfect-numbers/REXX/perfect-numbers-8.rexx create mode 100644 Task/Perfect-shuffle/PascalABC.NET/perfect-shuffle.pas create mode 100644 Task/Perfect-totient-numbers/PascalABC.NET/perfect-totient-numbers.pas create mode 100644 Task/Perlin-noise/JavaScript/perlin-noise.js create mode 100644 Task/Permutation-test/ALGOL-68/permutation-test.alg create mode 100644 Task/Permutation-test/EasyLang/permutation-test.easy create mode 100644 Task/Permutation-test/PascalABC.NET/permutation-test.pas delete mode 100644 Task/Permutations/C/permutations-4.c create mode 100644 Task/Phrase-reversals/Crystal/phrase-reversals.cr create mode 100644 Task/Pi/Atari-BASIC/pi.basic create mode 100644 Task/Pierpont-primes/REXX/pierpont-primes-1.rexx create mode 100644 Task/Pierpont-primes/REXX/pierpont-primes-2.rexx delete mode 100644 Task/Pierpont-primes/REXX/pierpont-primes.rexx create mode 100644 Task/Playfair-cipher/JavaScript/playfair-cipher.js create mode 100644 Task/Playfair-cipher/Rust/playfair-cipher.rs create mode 100644 Task/Polynomial-regression/Rust/polynomial-regression.rs create mode 100644 Task/Polynomial-regression/XPL0/polynomial-regression.xpl0 create mode 100644 Task/Power-set/Crystal/power-set.cr create mode 100644 Task/Power-set/M2000-Interpreter/power-set.m2000 create mode 100644 Task/Power-set/Refal/power-set.refal create mode 100644 Task/Primality-by-trial-division/Odin/primality-by-trial-division.odin delete mode 100644 Task/Primality-by-trial-division/REXX/primality-by-trial-division-1.rexx delete mode 100644 Task/Primality-by-trial-division/REXX/primality-by-trial-division-2.rexx delete mode 100644 Task/Primality-by-trial-division/REXX/primality-by-trial-division-3.rexx create mode 100644 Task/Primality-by-trial-division/REXX/primality-by-trial-division.rexx rename Task/Prime-conspiracy/REXX/{prime-conspiracy.rexx => prime-conspiracy-1.rexx} (100%) create mode 100644 Task/Prime-conspiracy/REXX/prime-conspiracy-2.rexx delete mode 100644 Task/Prime-decomposition/REXX/prime-decomposition-1.rexx delete mode 100644 Task/Prime-decomposition/REXX/prime-decomposition-2.rexx delete mode 100644 Task/Prime-decomposition/REXX/prime-decomposition-3.rexx delete mode 100644 Task/Prime-decomposition/REXX/prime-decomposition-4.rexx create mode 100644 Task/Prime-decomposition/REXX/prime-decomposition.rexx create mode 100644 Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/EasyLang/prime-numbers-whose-neighboring-pairs-are-tetraprimes.easy create mode 100644 Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/PARI-GP/prime-numbers-whose-neighboring-pairs-are-tetraprimes.parigp create mode 100644 Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/Python/prime-numbers-whose-neighboring-pairs-are-tetraprimes.py create mode 100644 Task/Primes---allocate-descendants-to-their-ancestors/ALGOL-68/primes---allocate-descendants-to-their-ancestors.alg create mode 100644 Task/Primes---allocate-descendants-to-their-ancestors/EasyLang/primes---allocate-descendants-to-their-ancestors.easy create mode 100644 Task/Primes---allocate-descendants-to-their-ancestors/REXX/primes---allocate-descendants-to-their-ancestors.rexx create mode 100644 Task/Program-termination/OPL/program-termination.opl create mode 100644 Task/Proper-divisors/ALGOL-60/proper-divisors.alg delete mode 100644 Task/Proper-divisors/REXX/proper-divisors-3.rexx delete mode 100644 Task/Proper-divisors/REXX/proper-divisors-4.rexx create mode 100644 Task/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a/Rust/pseudo-random-numbers-combined-recursive-generator-mrg32k3a.rs create mode 100644 Task/Pseudo-random-numbers-Middle-square-method/Rust/pseudo-random-numbers-middle-square-method.rs create mode 100644 Task/Pseudo-random-numbers-Splitmix64/Rust/pseudo-random-numbers-splitmix64.rs create mode 100644 Task/Pythagoras-tree/ALGOL-68/pythagoras-tree.alg create mode 100644 Task/Pythagoras-tree/Maple/pythagoras-tree.maple create mode 100644 Task/QR-decomposition/Rust/qr-decomposition.rs create mode 100644 Task/Quickselect-algorithm/Zig/quickselect-algorithm.zig create mode 100644 Task/Quine/Rust/quine-5.rs create mode 100644 Task/Quine/V-(Vlang)/quine.v create mode 100644 Task/Quine/Zig/quine.zig create mode 100644 Task/Radical-of-an-integer/SETL/radical-of-an-integer.setl create mode 100644 Task/Ramanujan-primes-twins/REXX/ramanujan-primes-twins.rexx create mode 100644 Task/Ramer-Douglas-Peucker-line-simplification/Lua/ramer-douglas-peucker-line-simplification.lua create mode 100644 Task/Ramer-Douglas-Peucker-line-simplification/Modula-2/ramer-douglas-peucker-line-simplification.mod2 delete mode 100644 Task/Random-number-generator-device-/C/random-number-generator-device--5.c delete mode 100644 Task/Random-number-generator-device-/REXX/random-number-generator-device--1.rexx delete mode 100644 Task/Random-number-generator-device-/REXX/random-number-generator-device--2.rexx create mode 100644 Task/Random-number-generator-device-/REXX/random-number-generator-device-.rexx create mode 100644 Task/Read-a-configuration-file/XPL0/read-a-configuration-file.xpl0 create mode 100644 Task/Read-entire-file/OoRexx/read-entire-file-4.rexx delete mode 100644 Task/Real-constants-and-functions/REXX/real-constants-and-functions-5.rexx delete mode 100644 Task/Real-constants-and-functions/REXX/real-constants-and-functions-6.rexx delete mode 100644 Task/Real-constants-and-functions/REXX/real-constants-and-functions-7.rexx delete mode 100644 Task/Real-constants-and-functions/REXX/real-constants-and-functions-8.rexx delete mode 100644 Task/Real-constants-and-functions/REXX/real-constants-and-functions-9.rexx create mode 100644 Task/Reflection-Get-source/C-sharp/reflection-get-source.cs create mode 100644 Task/Rendezvous/Rust/rendezvous.rs create mode 100644 Task/Repeat-a-string/Excel/repeat-a-string.excel create mode 100644 Task/Resistor-mesh/Rust/resistor-mesh.rs rename Task/Reverse-a-string/Common-Lisp/{reverse-a-string.lisp => reverse-a-string-1.lisp} (100%) create mode 100644 Task/Reverse-a-string/Common-Lisp/reverse-a-string-2.lisp create mode 100644 Task/Reverse-a-string/Excel/reverse-a-string.excel create mode 100644 Task/Roman-numerals-Decode/Objeck/roman-numerals-decode.objeck create mode 100644 Task/Rosetta-Code-Find-unimplemented-tasks/Objeck/rosetta-code-find-unimplemented-tasks.objeck create mode 100644 Task/Rosetta-Code-Fix-code-tags/FreeBASIC/rosetta-code-fix-code-tags.basic create mode 100644 Task/Rosetta-Code-Rank-languages-by-popularity/FreeBASIC/rosetta-code-rank-languages-by-popularity.basic create mode 100644 Task/Run-length-encoding/8080-Assembly/run-length-encoding.8080 create mode 100644 Task/Run-length-encoding/Crystal/run-length-encoding.cr create mode 100644 Task/Run-length-encoding/MACRO-11/run-length-encoding.macro11 create mode 100644 Task/Run-length-encoding/Miranda/run-length-encoding.miranda create mode 100644 Task/Run-length-encoding/Refal/run-length-encoding.refal create mode 100644 Task/Runge-Kutta-method/Odin/runge-kutta-method.odin create mode 100644 Task/Runge-Kutta-method/Ol/runge-kutta-method.ol create mode 100644 Task/Runge-Kutta-method/Scheme/runge-kutta-method.scm create mode 100644 Task/SHA-1/JavaScript/sha-1.js create mode 100644 Task/SHA-1/Zig/sha-1.zig create mode 100644 Task/SQL-based-authentication/FreeBASIC/sql-based-authentication.basic delete mode 100644 Task/Semiprime/REXX/semiprime-3.rexx delete mode 100644 Task/Semiprime/REXX/semiprime-4.rexx create mode 100644 Task/Semordnilap/R/semordnilap.r create mode 100644 Task/Sequence-of-primes-by-trial-division/ALGOL-60/sequence-of-primes-by-trial-division.alg delete mode 100644 Task/Sequence-of-primes-by-trial-division/REXX/sequence-of-primes-by-trial-division-1.rexx delete mode 100644 Task/Sequence-of-primes-by-trial-division/REXX/sequence-of-primes-by-trial-division-2.rexx create mode 100644 Task/Sequence-of-primes-by-trial-division/REXX/sequence-of-primes-by-trial-division.rexx create mode 100644 Task/Sequence-of-primorial-primes/REXX/sequence-of-primorial-primes.rexx create mode 100644 Task/Sequence:-smallest-number-with-exactly-n-divisors/C-sharp/sequence:-smallest-number-with-exactly-n-divisors.cs create mode 100644 Task/Set-puzzle/JavaScript/set-puzzle.js create mode 100644 Task/Shoelace-formula-for-polygonal-area/Rust/shoelace-formula-for-polygonal-area.rs delete mode 100644 Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-3.rexx delete mode 100644 Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-4.rexx create mode 100644 Task/Sieve-of-Pritchard/REXX/sieve-of-pritchard.rexx create mode 100644 Task/Simple-turtle-graphics/M2000-Interpreter/simple-turtle-graphics.m2000 create mode 100644 Task/Simple-turtle-graphics/Raku/simple-turtle-graphics.raku create mode 100644 Task/Simulate-input-Keyboard/FreeBASIC/simulate-input-keyboard.basic create mode 100644 Task/Sisyphus-sequence/Mathematica/sisyphus-sequence.math create mode 100644 Task/Sleep/JavaScript/sleep-1.js create mode 100644 Task/Sleep/JavaScript/sleep-2.js create mode 100644 Task/Sleep/JavaScript/sleep-3.js delete mode 100644 Task/Sleep/JavaScript/sleep.js create mode 100644 Task/Solve-a-Hidato-puzzle/JavaScript/solve-a-hidato-puzzle.js create mode 100644 Task/Solve-a-Holy-Knights-tour/Rust/solve-a-holy-knights-tour.rs create mode 100644 Task/Solve-a-Holy-Knights-tour/Zig/solve-a-holy-knights-tour.zig create mode 100644 Task/Solve-a-Hopido-puzzle/Rust/solve-a-hopido-puzzle.rs create mode 100644 Task/Solve-a-Numbrix-puzzle/ALGOL-68/solve-a-numbrix-puzzle.alg create mode 100644 Task/Solve-a-Numbrix-puzzle/EasyLang/solve-a-numbrix-puzzle.easy create mode 100644 Task/Solve-a-Numbrix-puzzle/JavaScript/solve-a-numbrix-puzzle.js create mode 100644 Task/Solve-a-Numbrix-puzzle/Rust/solve-a-numbrix-puzzle.rs create mode 100644 Task/Solve-the-no-connection-puzzle/ALGOL-68/solve-the-no-connection-puzzle.alg create mode 100644 Task/Solve-the-no-connection-puzzle/EasyLang/solve-the-no-connection-puzzle.easy create mode 100644 Task/Sort-a-list-of-object-identifiers/APL/sort-a-list-of-object-identifiers.apl create mode 100644 Task/Sort-an-array-of-composite-structures/Crystal/sort-an-array-of-composite-structures.cr delete mode 100644 Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-3.rexx delete mode 100644 Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-4.rexx create mode 100644 Task/Sort-numbers-lexicographically/Crystal/sort-numbers-lexicographically.cr create mode 100644 Task/Sort-numbers-lexicographically/R/sort-numbers-lexicographically.r create mode 100644 Task/Sort-three-variables/Crystal/sort-three-variables.cr create mode 100644 Task/Sort-three-variables/XPL0/sort-three-variables.xpl0 create mode 100644 Task/Sorting-Algorithms-Circle-Sort/Crystal/sorting-algorithms-circle-sort.cr create mode 100644 Task/Sorting-algorithms-Bead-sort/Rust/sorting-algorithms-bead-sort.rs create mode 100644 Task/Sorting-algorithms-Bubble-sort/Crystal/sorting-algorithms-bubble-sort.cr delete mode 100644 Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-3.rexx create mode 100644 Task/Sorting-algorithms-Patience-sort/EasyLang/sorting-algorithms-patience-sort.easy create mode 100644 Task/Sorting-algorithms-Patience-sort/Rust/sorting-algorithms-patience-sort.rs create mode 100644 Task/Sorting-algorithms-Patience-sort/Zig/sorting-algorithms-patience-sort.zig delete mode 100644 Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-6.rexx create mode 100644 Task/Sorting-algorithms-Radix-sort/JavaScript/sorting-algorithms-radix-sort.js rename Task/Sorting-algorithms-Radix-sort/Rust/{sorting-algorithms-radix-sort.rs => sorting-algorithms-radix-sort-1.rs} (80%) create mode 100644 Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-2.rs create mode 100644 Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-3.rs create mode 100644 Task/Sorting-algorithms-Strand-sort/FreeBASIC/sorting-algorithms-strand-sort.basic create mode 100644 Task/Sorting-algorithms-Strand-sort/M2000-Interpreter/sorting-algorithms-strand-sort.m2000 create mode 100644 Task/Sorting-algorithms-Strand-sort/Rust/sorting-algorithms-strand-sort.rs create mode 100644 Task/Sorting-algorithms-Strand-sort/Zig/sorting-algorithms-strand-sort.zig create mode 100644 Task/Spelling-of-ordinal-numbers/JavaScript/spelling-of-ordinal-numbers.js create mode 100644 Task/Sphenic-numbers/Mathematica/sphenic-numbers.math create mode 100644 Task/Spiral-matrix/Uiua/spiral-matrix.uiua rename Task/Split-a-character-string-based-on-change-of-character/C/{split-a-character-string-based-on-change-of-character.c => split-a-character-string-based-on-change-of-character-1.c} (100%) create mode 100644 Task/Split-a-character-string-based-on-change-of-character/C/split-a-character-string-based-on-change-of-character-2.c create mode 100644 Task/Split-a-character-string-based-on-change-of-character/Crystal/split-a-character-string-based-on-change-of-character.cr create mode 100644 Task/Split-a-character-string-based-on-change-of-character/Emacs-Lisp/split-a-character-string-based-on-change-of-character.l create mode 100644 Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-3.rs create mode 100644 Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-4.rs create mode 100644 Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-5.rs create mode 100644 Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-6.rs create mode 100644 Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-7.rs create mode 100644 Task/Square-form-factorization/Python/square-form-factorization.py create mode 100644 Task/Stack-traces/Crystal/stack-traces.cr create mode 100644 Task/Stack-traces/Uxntal/stack-traces.uxnatl create mode 100644 Task/Stack/Ballerina/stack-1.ballerina create mode 100644 Task/Stack/Ballerina/stack-2.ballerina create mode 100644 Task/State-name-puzzle/JavaScript/state-name-puzzle.js create mode 100644 Task/Statistics-Basic/Ballerina/statistics-basic.ballerina create mode 100644 Task/Steffensens-method/Rust/steffensens-method.rs create mode 100644 Task/Strassens-algorithm/C++/strassens-algorithm.cpp create mode 100644 Task/Strassens-algorithm/C-sharp/strassens-algorithm.cs create mode 100644 Task/Strassens-algorithm/Java/strassens-algorithm.java create mode 100644 Task/Strassens-algorithm/JavaScript/strassens-algorithm-1.js create mode 100644 Task/Strassens-algorithm/JavaScript/strassens-algorithm-2.js create mode 100644 Task/Strassens-algorithm/Rust/strassens-algorithm.rs create mode 100644 Task/Strassens-algorithm/Zig/strassens-algorithm.zig create mode 100644 Task/Stream-merge/Rust/stream-merge.rs create mode 100644 Task/String-length/Crystal/string-length-3.cr create mode 100644 Task/String-length/Uxntal/string-length.uxnatl create mode 100644 Task/String-prepend/Crystal/string-prepend.cr create mode 100644 Task/String-prepend/OPL/string-prepend.opl create mode 100644 Task/Strip-a-set-of-characters-from-a-string/Java/strip-a-set-of-characters-from-a-string-4.java create mode 100644 Task/Strip-a-set-of-characters-from-a-string/M2000-Interpreter/strip-a-set-of-characters-from-a-string.m2000 create mode 100644 Task/Strip-a-set-of-characters-from-a-string/Objeck/strip-a-set-of-characters-from-a-string.objeck create mode 100644 Task/Strip-a-set-of-characters-from-a-string/Odin/strip-a-set-of-characters-from-a-string.odin create mode 100644 Task/Strip-a-set-of-characters-from-a-string/R/strip-a-set-of-characters-from-a-string.r create mode 100644 Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-4.rs create mode 100644 Task/Strip-comments-from-a-string/APL/strip-comments-from-a-string.apl create mode 100644 Task/Strip-comments-from-a-string/Emacs-Lisp/strip-comments-from-a-string.l create mode 100644 Task/Strip-comments-from-a-string/Refal/strip-comments-from-a-string.refal create mode 100644 Task/Strip-comments-from-a-string/SETL/strip-comments-from-a-string.setl create mode 100644 Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail-1.cpp rename Task/Strip-whitespace-from-a-string-Top-and-tail/C++/{strip-whitespace-from-a-string-top-and-tail.cpp => strip-whitespace-from-a-string-top-and-tail-2.cpp} (54%) create mode 100644 Task/Substitution-cipher/JavaScript/substitution-cipher.js create mode 100644 Task/Substring/K/substring.k create mode 100644 Task/Sudan-function/Rust/sudan-function.rs rename Task/Sum-digits-of-an-integer/Nu/{sum-digits-of-an-integer.nu => sum-digits-of-an-integer-1.nu} (100%) create mode 100644 Task/Sum-digits-of-an-integer/Nu/sum-digits-of-an-integer-2.nu create mode 100644 Task/Sum-of-a-series/ALGOL-60/sum-of-a-series-1.alg create mode 100644 Task/Sum-of-a-series/ALGOL-60/sum-of-a-series-2.alg delete mode 100644 Task/Sum-of-a-series/ALGOL-60/sum-of-a-series.alg create mode 100644 Task/Sum-of-a-series/S-BASIC/sum-of-a-series.basic create mode 100644 Task/Sum-of-a-series/TypeScript/sum-of-a-series.ts create mode 100644 Task/Sum-of-elements-below-main-diagonal-of-matrix/Quackery/sum-of-elements-below-main-diagonal-of-matrix.quackery create mode 100644 Task/Sutherland-Hodgman-polygon-clipping/Zig/sutherland-hodgman-polygon-clipping.zig create mode 100644 Task/Take-notes-on-the-command-line/Crystal/take-notes-on-the-command-line.cr rename Task/Tau-number/REXX/{tau-number.rexx => tau-number-1.rexx} (100%) create mode 100644 Task/Tau-number/REXX/tau-number-2.rexx create mode 100644 Task/Terminal-control-Clear-the-screen/X86-64-Assembly/terminal-control-clear-the-screen.x86-64 create mode 100644 Task/Text-processing-1/XPL0/text-processing-1.xpl0 create mode 100644 Task/Text-processing-2/ALGOL-68/text-processing-2.alg create mode 100644 Task/Text-processing-2/FreeBASIC/text-processing-2.basic create mode 100644 Task/Text-processing-2/XPL0/text-processing-2.xpl0 create mode 100644 Task/Thieles-interpolation-formula/Fortran/thieles-interpolation-formula.f create mode 100644 Task/Thue-Morse/Zig/thue-morse.zig create mode 100644 Task/Tic-tac-toe/APL/tic-tac-toe-1.apl create mode 100644 Task/Tic-tac-toe/APL/tic-tac-toe-2.apl create mode 100644 Task/Tic-tac-toe/Factor/tic-tac-toe-1.factor create mode 100644 Task/Tic-tac-toe/Factor/tic-tac-toe-2.factor create mode 100644 Task/Tic-tac-toe/J/tic-tac-toe-4.j create mode 100644 Task/Tic-tac-toe/JavaScript/tic-tac-toe-3.js delete mode 100644 Task/Time-a-function/REXX/time-a-function-3.rexx delete mode 100644 Task/Time-a-function/REXX/time-a-function-4.rexx rename Task/Tokenize-a-string-with-escaping/Lua/{tokenize-a-string-with-escaping.lua => tokenize-a-string-with-escaping-1.lua} (67%) create mode 100644 Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-2.lua create mode 100644 Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-3.lua create mode 100644 Task/Tokenize-a-string/Excel/tokenize-a-string-1.excel create mode 100644 Task/Tokenize-a-string/Excel/tokenize-a-string-2.excel create mode 100644 Task/Tonelli-Shanks-algorithm/JavaScript/tonelli-shanks-algorithm.js create mode 100644 Task/Tonelli-Shanks-algorithm/Rust/tonelli-shanks-algorithm.rs create mode 100644 Task/Tonelli-Shanks-algorithm/Zig/tonelli-shanks-algorithm.zig delete mode 100644 Task/Totient-function/REXX/totient-function-1.rexx delete mode 100644 Task/Totient-function/REXX/totient-function-2.rexx delete mode 100644 Task/Totient-function/REXX/totient-function-3.rexx create mode 100644 Task/Totient-function/REXX/totient-function.rexx create mode 100644 Task/Towers-of-Hanoi/Applesoft-BASIC/towers-of-hanoi.basic create mode 100644 Task/Towers-of-Hanoi/Ballerina/towers-of-hanoi.ballerina create mode 100644 Task/Towers-of-Hanoi/Excel/towers-of-hanoi-3.excel delete mode 100644 Task/Trigonometric-functions/REXX/trigonometric-functions-1.rexx rename Task/Trigonometric-functions/REXX/{trigonometric-functions-2.rexx => trigonometric-functions.rexx} (93%) create mode 100644 Task/Truncatable-primes/Ballerina/truncatable-primes.ballerina rename Task/Truncatable-primes/REXX/{truncatable-primes.rexx => truncatable-primes-1.rexx} (100%) create mode 100644 Task/Truncatable-primes/REXX/truncatable-primes-2.rexx delete mode 100644 Task/Twin-primes/REXX/twin-primes-1.rexx delete mode 100644 Task/Twin-primes/REXX/twin-primes-2.rexx create mode 100644 Task/Twin-primes/REXX/twin-primes.rexx create mode 100644 Task/Two-bullet-roulette/Quackery/two-bullet-roulette.quackery create mode 100644 Task/UTF-8-encode-and-decode/K/utf-8-encode-and-decode.k create mode 100644 Task/Ukkonen-s-suffix-tree-construction/FreeBASIC/ukkonen-s-suffix-tree-construction-1.basic create mode 100644 Task/Ukkonen-s-suffix-tree-construction/FreeBASIC/ukkonen-s-suffix-tree-construction-2.basic create mode 100644 Task/Ukkonen-s-suffix-tree-construction/JavaScript/ukkonen-s-suffix-tree-construction.js create mode 100644 Task/Ukkonen-s-suffix-tree-construction/Rust/ukkonen-s-suffix-tree-construction.rs delete mode 100644 Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes--1.rexx delete mode 100644 Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes--2.rexx create mode 100644 Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes-.rexx create mode 100644 Task/Unicode-strings/Tcl/unicode-strings.tcl create mode 100644 Task/Unicode-variable-names/Ballerina/unicode-variable-names.ballerina create mode 100644 Task/Unicode-variable-names/Odin/unicode-variable-names.odin create mode 100644 Task/Unicode-variable-names/Scheme/unicode-variable-names.scm create mode 100644 Task/Unprimeable-numbers/EasyLang/unprimeable-numbers.easy create mode 100644 Task/Update-a-configuration-file/Lua/update-a-configuration-file.lua create mode 100644 Task/User-input-Text/JavaScript/user-input-text-3.js create mode 100644 Task/User-input-Text/OPL/user-input-text.opl create mode 100644 Task/Verhoeff-algorithm/JavaScript/verhoeff-algorithm.js create mode 100644 Task/Verhoeff-algorithm/Rust/verhoeff-algorithm.rs create mode 100644 Task/Vigen-re-cipher-Cryptanalysis/JavaScript/vigen-re-cipher-cryptanalysis.js create mode 100644 Task/Vogels-approximation-method/Fortran/vogels-approximation-method.f create mode 100644 Task/Vogels-approximation-method/JavaScript/vogels-approximation-method.js create mode 100644 Task/Wagstaff-primes/Mathematica/wagstaff-primes.math create mode 100644 Task/Wasteful-equidigital-and-frugal-numbers/ALGOL-68/wasteful-equidigital-and-frugal-numbers.alg create mode 100644 Task/Wasteful-equidigital-and-frugal-numbers/EasyLang/wasteful-equidigital-and-frugal-numbers.easy create mode 100644 Task/Wasteful-equidigital-and-frugal-numbers/Python/wasteful-equidigital-and-frugal-numbers.py rename Task/Wieferich-primes/REXX/{wieferich-primes.rexx => wieferich-primes-1.rexx} (100%) create mode 100644 Task/Wieferich-primes/REXX/wieferich-primes-2.rexx create mode 100644 Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n-1.rexx create mode 100644 Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n-2.rexx delete mode 100644 Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n.rexx create mode 100644 Task/Word-frequency/Emacs-Lisp/word-frequency.l create mode 100644 Task/Word-frequency/Nu/word-frequency.nu create mode 100644 Task/Word-ladder/FreeBASIC/word-ladder.basic create mode 100644 Task/Wordiff/JavaScript/wordiff.js create mode 100644 Task/Write-entire-file/Odin/write-entire-file.odin create mode 100644 Task/Write-float-arrays-to-a-text-file/AppleScript/write-float-arrays-to-a-text-file.applescript create mode 100644 Task/Write-float-arrays-to-a-text-file/K/write-float-arrays-to-a-text-file.k create mode 100644 Task/Xiaolin-Wus-line-algorithm/Rust/xiaolin-wus-line-algorithm.rs create mode 100644 Task/Y-combinator/F-Sharp/y-combinator-5.fs create mode 100644 Task/Y-combinator/Zig/y-combinator.zig delete mode 100644 Task/Yellowstone-sequence/REXX/yellowstone-sequence-1.rexx delete mode 100644 Task/Yellowstone-sequence/REXX/yellowstone-sequence-2.rexx create mode 100644 Task/Yellowstone-sequence/REXX/yellowstone-sequence.rexx create mode 100644 Task/Zebra-puzzle/JavaScript/zebra-puzzle.js create mode 100644 Task/Zig-zag-matrix/Uiua/zig-zag-matrix.uiua diff --git a/Lang/8080-Assembly/Loops-Infinite b/Lang/8080-Assembly/Loops-Infinite new file mode 120000 index 0000000000..f6336ebca0 --- /dev/null +++ b/Lang/8080-Assembly/Loops-Infinite @@ -0,0 +1 @@ +../../Task/Loops-Infinite/8080-Assembly \ No newline at end of file diff --git a/Lang/8080-Assembly/Run-length-encoding b/Lang/8080-Assembly/Run-length-encoding new file mode 120000 index 0000000000..bc3ed9076c --- /dev/null +++ b/Lang/8080-Assembly/Run-length-encoding @@ -0,0 +1 @@ +../../Task/Run-length-encoding/8080-Assembly \ No newline at end of file diff --git a/Lang/8086-Assembly/00-LANG.txt b/Lang/8086-Assembly/00-LANG.txt index 7cf10761fa..9120d12d87 100644 --- a/Lang/8086-Assembly/00-LANG.txt +++ b/Lang/8086-Assembly/00-LANG.txt @@ -4,13 +4,13 @@ ===Segmented Memory=== The 8086 uses a segmented memory model, similar to the Super Nintendo Entertainment System. Unlike banked memory models used in the Commodore 64 and late NES games, segment addresses are held in segment registers. These segment registers are 16 bit and get left-shifted by 4 and added to the pointer register of interest to determine the memory address to look up. The 8086 has four in total, but only the DS and ES registers can be used by the programmer. (The other two work with the stack pointer and instruction pointer, and are loaded for you.) On the 8086, you can only load segment registers with the value in a data register, or with the POP command. So first you must load a segment into a data register, THEN into a segment register. -;This is NOT valid code! +;This is NOT valid code! mov ds, @data ;you're trying to move the data segment location directly into DS. You can't! ;This is the proper way: mov ax, @data ;I chose AX but I could have used BX, CX, or DX. -mov ds, ax ;load DS with the data segment. +mov ds, ax ;load DS with the data segment. It's important to remember the subtle distinction between a ''segment'' and a ''segment register.'' Your program might have labeled ''segments'' such as .data and .code, but in order to properly read from/write to these sections you'll need to load their memory locations into ''segment registers.'' @@ -18,17 +18,17 @@ It's important to remember the subtle distinction between a ''segment'' and a '' There are four data registers: AX, BX, CX, and DX. While most commands can use any of them, some only work with particular data registers. System calls in particular are very specific about which registers can be used for what. On [[MS-DOS]], the AX register is used for selecting the desired interrupt to use with the INT command. Each data register is 16-bit, but has two eight bit halves ending in H or L, e.g. AH, AL. Instructions can be executed using the whole register or just half of it. -mov ax, 1000h ;move 1000h into AX, or equivalently, move 10h into AH and 00h into AL. +mov ax, 1000h ;move 1000h into AX, or equivalently, move 10h into AH and 00h into AL. Moving a value smaller than 16 bits into ?X is the same as moving it into ?L, and moving 0 into ?H. (? represents the data register of your choice. They are all the same in this regard.) -mov ax,0030h +mov ax,0030h ;is the same as: mov al, 30h -mov ah, 0h +mov ah, 0h Commands that alter the contents of a single register will not affect the other half. -mov ax,00FFh -inc al +mov ax,00FFh +inc al If we had executed INC AX, then AX would have been incremented to 0x100. Since we only incremented AL, only AL was incremented in this case, and AH '''still equals 0x00!''' Generally speaking, the 8086's registers serve the following purposes: @@ -42,24 +42,24 @@ When writing to or reading from consecutive sections of memory, it is helpful to The syntax for offsetting an index register will vary depending on your assembler. Many assemblers will often accept multiple different ways of writing it, and it comes down to personal preference. -mov si, offset MyArray +mov si, offset MyArray mov bx,2 mov al,[bx+si] ;loads decimal 30 into AL MyArray: -byte 10,20,30,40,50 +byte 10,20,30,40,50 ===The Stack=== As with [[Z80 Assembly]], you can't push 8-bit registers onto the stack. For data registers, you have to push/pop both halves. -;This is valid code. +;This is valid code. push ax push bx pop bx pop ax -;This is NOT valid code. +;This is NOT valid code. push ah push al push bh @@ -69,14 +69,14 @@ push bl pop bl pop bh pop al -pop ah +pop ah As with all processors that use a stack, if you push one or more registers and want to restore the backed-up values correctly, you must pop them in the reverse order. You can pop them out of order on purpose to swap registers around. In fact, this is a quick way to move the segment from DS into ES, or vice-versa: -push DS -pop ES ;you can't do "mov es, ds" but you can do this! +push DS +pop ES ;you can't do "mov es, ds" but you can do this! The proper way to use the stack to preserve registers: - + call foo mov ax,4C00h @@ -91,7 +91,7 @@ push cx pop cx pop bx pop ax -ret +ret If one of the push/pop commands in the routine above were missing, the RET instruction would not properly return to where it came from. As long as you pop at the end the same number of registers you pushed at the start, the stack is "balanced" and your return instruction will return correctly. This is because RET is actually POP IP (IP being the instruction pointer, which you can think of as what "line" of code the CPU is on.) The CPU assumes the top of the stack is the correct place to return to, but has no way of actually verifying it. If the function you just wrote causes the CPU to crash or jump to a completely different part of the code, there's a good chance you might have forgotten to balance the stack properly. @@ -107,40 +107,40 @@ One other caveat to mention: On early IBM PCs and compatibles, the 8087 was not ===Looping Constructs=== The 8086 has a lot more of these than most CPUs. The most obvious one is LOOP, which will subtract 1 from CX, then jump back to a specified label if CX is nonzero after the subtraction. If CX becomes zero after subtracting 1, then no jump will occur and the instruction pointer simply moves to the next instruction. -mov cx,0100h ;set the loop counter's starting value. This must be outside the loop, otherwise you'll loop forever! +mov cx,0100h ;set the loop counter's starting value. This must be outside the loop, otherwise you'll loop forever! foo: ;; your code that you want to loop goes here -loop foo +loop foo It's important not to alter CX inside the loop. It's easy to make a mistake like this if you're in a hurry: -foobar: +foobar: mov cx,1000h ;your code goes here -loop foobar +loop foobar It may not be obvious at first but the above loop will never end. CX decrements to 0x0FFF with the LOOP instruction but the mov cx,1000h was mistakenly placed ''inside'' the loop, resetting the loop counter back to 0x1000, which means no progress is really being made. The correct way to do this is to set the starting loop counter '''outside''' the loop, like so: -mov cx,1000h +mov cx,1000h foobar: ;your code goes here -loop foobar +loop foobar Sometimes you'll have to change CX during a loop, like if you want to do bit shifts with a shift amount other than 1, for example. There's a simple fix - use the stack to stash and retrieve the loop counter. -mov cx,0100h +mov cx,0100h foo: push cx mov cl,2 ror ax,cl ;starting with the 80186 you don't need CL for bit shifting. pop cx -loop foo +loop foo By using PUSH CX and POP CX, you can temporarily use CX for something else, as long as you restore it before the LOOP instruction. You can use other registers as loop counters as well, but not with the LOOP instruction - it's hardcoded to only work with CX. But you can do this: -mov dx,0100h +mov dx,0100h baz: ;your code goes here dec dx @@ -148,7 +148,7 @@ jnz baz ; A minor note for advanced programmers: ; If you're expecting the flags to be in a particular state based on the loop body, tough luck! ; They'll only reflect the decrement of DX from 1 to 0 at this point in the code. -; LOOP doesn't change the flags, which makes it more useful for loops meant to compare things. +; LOOP doesn't change the flags, which makes it more useful for loops meant to compare things. Another frequently used looping construct is REP. REP can be combined with certain instructions to repeat that instruction until CX equals zero. However, unlike LOOP, which can be used to repeat a block of instructions, REP can only repeat one. It doesn't work on all instructions, only the "string" instructions which operate on a block of memory. Typically these include MOVSB, LODSB, STOSB, CMPSB, and SCASB (each has a variant that ends in W instead of B, for 16-bit data.) There are also REPZ and REPNZ, which stand for "Repeat if Zero" and "Repeat if Nonzero" respectively. These two only work properly with CMPSB and SCASB, as MOVSB, LODSB, STOSB do not affect the flags. (The CPU doesn't detect whether CX equals zero using the flags, as the flags never reflect this equality to zero like you would expect.) diff --git a/Lang/ALGOL-60/Additive-primes b/Lang/ALGOL-60/Additive-primes new file mode 120000 index 0000000000..360a570784 --- /dev/null +++ b/Lang/ALGOL-60/Additive-primes @@ -0,0 +1 @@ +../../Task/Additive-primes/ALGOL-60 \ No newline at end of file diff --git a/Lang/ALGOL-60/Largest-proper-divisor-of-n b/Lang/ALGOL-60/Largest-proper-divisor-of-n new file mode 120000 index 0000000000..bd5f1adbca --- /dev/null +++ b/Lang/ALGOL-60/Largest-proper-divisor-of-n @@ -0,0 +1 @@ +../../Task/Largest-proper-divisor-of-n/ALGOL-60 \ No newline at end of file diff --git a/Lang/ALGOL-60/Loops-Increment-loop-index-within-loop-body b/Lang/ALGOL-60/Loops-Increment-loop-index-within-loop-body new file mode 120000 index 0000000000..b6ef8c8c0c --- /dev/null +++ b/Lang/ALGOL-60/Loops-Increment-loop-index-within-loop-body @@ -0,0 +1 @@ +../../Task/Loops-Increment-loop-index-within-loop-body/ALGOL-60 \ No newline at end of file diff --git a/Lang/ALGOL-60/Proper-divisors b/Lang/ALGOL-60/Proper-divisors new file mode 120000 index 0000000000..7bb12e66dd --- /dev/null +++ b/Lang/ALGOL-60/Proper-divisors @@ -0,0 +1 @@ +../../Task/Proper-divisors/ALGOL-60 \ No newline at end of file diff --git a/Lang/ALGOL-60/Sequence-of-primes-by-trial-division b/Lang/ALGOL-60/Sequence-of-primes-by-trial-division new file mode 120000 index 0000000000..b95a2ebdcc --- /dev/null +++ b/Lang/ALGOL-60/Sequence-of-primes-by-trial-division @@ -0,0 +1 @@ +../../Task/Sequence-of-primes-by-trial-division/ALGOL-60 \ No newline at end of file diff --git a/Lang/ALGOL-68/00-LANG.txt b/Lang/ALGOL-68/00-LANG.txt index 875b4abf89..d037dbcad0 100644 --- a/Lang/ALGOL-68/00-LANG.txt +++ b/Lang/ALGOL-68/00-LANG.txt @@ -68,209 +68,11 @@ A syntax chart is available [http://www.softwarepreservation.org/projects/ALGOL/ *Dec. 1968: Report on the Algorithmic Language ALGOL 68 - Offprint from Numerische Mathematik, 14, 79-218 (1969); Springer-Verlag. - Edited by: A. van Wijngaarden, B.J. Mailloux, J.E.L. Peck and C.H.A. Koster. *Sep 1973: Revised Report on the Algorithmic Language Algol 68 - Springer-Verlag 1976 - Edited by: A. van Wijngaarden, B.J. Mailloux, J.E.L. Peck, C.H.A. Koster, M. Sintzoff, C.H. Lindsey, L.G.L.T. Meertens and R.G. Fisker. ==Coding style of samples, alphabets and stropping== -Click "Expand" for more details. -
-
- -Many of the code samples provided here have a leading main:( and a matching ) at the end. These are not actually required in the language, but are included so as to highlight the main routine. - -On some compilers, it may be necessary to include appropriate "job cards" -or preludes in order for the programs to compile successfully. Hopefully -not too much else is required. Examples: -{|border="1" style="border-collapse: collapse; border: 5px double grey;" align="center" -|| Brief Algol68 -|| Algol68 as in rosettacode -|| Actual ELLA Algol 68RS code -|- -|| - print(("Hello, world!",new line)) -|| - main:( - print(("Hello, world!",new line)) - ) -|| - PROGRAM helloworld CONTEXT VOID - USE standard - BEGIN - print(("Hello, world!", new line)) - END - FINISH -|} -

'''Alphabets''' -

-Notionally, Algol 68 source is written in two alphabets. The reserved words, mode indicants (type names) and operators that are non-symbolic (.e.g. '''and''', '''or''', ...) are generally referred to as "bold words" and usually shown in a bold font in literature. Words that are identifiers (used for "variable" names, procedure names, structure member names, ...) are in a separate, non-bold font.
-The [https://www.softwarepreservation.org/projects/ALGOL/manual/a68s.txt/view Manual for CMU ALGOL 68S (on softwarepreservation.org)] refers to the non-bold words as being in timid face. -

'''Examples of different program representations''' -

-At the time when ALGOL 68 was defined some predominant computers had -24 or 36 bit words, with 6 bit character sets. Hence it was desirable that -ALGOL 68 should be able to run on machines with only uppercase. -As multiple fonts were generally unavailable, a method of identifying the bold words was required.
-The official spec provided for different representations of the same -program. -Quote stropping (enclosing the bold words in single quotes) -and Point stropping (preceeding the bold words with a dot) -were used.
-A variant of Point stropping called RES stropping was also defined. -In RES stropping some language-defined bold words are not preceded by a dot.
-A pragmatic comment may have been required to indicate which -stropping convention was to be used, as in some of the examples below.
-Upper stropping (representing the bold words by upper case and -non-bold words in lower case) was introduced by Algol 68R.
-Upper stropping is used by Algol 68RS and is one of the options for Algol 68G.
-Rutgers ALGOL 68 uses quote stropping.
-Most of the samples on Rosetta Code use Upper stropping.

-Examples (pragmatic comments to set the stropping regime not shown): -{|border="1" style="border-collapse: collapse; border: 2px double grey;" align="left" -|| Algol68 as typically published - '''mode''' '''xint''' = '''int'''; - '''xint''' sum sq:=0; - '''for''' i '''while''' - sum sq≠70×70 - '''do''' - sum sq+:=i↑2 - '''od''' -|| QUOTE stropping (similar to wiki) - 'mode' 'xint' = 'int'; - 'xint' sum sq:=0; - 'for' i 'while' - sum sq≠70×70 - 'do' - sum sq+:=i↑2 - 'od' -|| POINT stropping - .MODE .XINT = .INT; - .XINT SUM SQ:=0; - .FOR I .WHILE - SUM SQ .NE 70*70 - .DO - SUM SQ .PLUSAB I .UP 2 - .OD -|| RES stropping - mode .xint = int; - .xint sum sq:=0; - for i while - sum sq≠70×70 - do - sum sq+:=i↑2 - od -|| Upper stropping - MODE XINT = INT; - XINT sum sq:=0; - FOR i WHILE - sum sq /= 70*70 - DO - sum sq PLUSAB i UP 2 - OD -|} - -
+See [[ALGOL 68 Representation]]. == Coercion (casting) == -ALGOL 68 has a hierarchy of contexts which determine which kind of coercions are available at a particular point in the program. -
-Click "Expand" for more details. -
-
- -These contexts are: -{|class="wikitable" -!rowspan=2| N
-a
-m
-e -!rowspan=2| Context location -!colspan=5| Coercions available in this context -!rowspan=2| Coercion examples -|- -|bgcolor=aaaaff|Soft -|bgcolor=aaeeaa|Weak -|bgcolor=ffee99|Meek -|bgcolor=ffcc99|Firm -|bgcolor=ffcccc|Strong -|- -!S
-t
-r
-o
-n
-g -||Right hand side of: -* Identity-declarations, as "~" in: REAL x = ~ -* Initialisations, as "~" in: REAL x := ~ -Also: -* Actual-parameters of calls, as "~" in:PROC: sin(~) -* Enclosed clauses of casts, as "~" in: REAL(~) -* Units of routine-texts -* Statements yielding VOID -* All parts (but one) of a balanced clause -* One side of an identity relation, as "~" in: ~ IS ~ -|bgcolor=aaaaff rowspan=4 width="50px"| deproc- eduring -|bgcolor=aaeeaa rowspan=3 width="50px"| all '''soft''' then weak deref- erencing -|bgcolor=ffee99 rowspan=2 width="50px"| all '''weak''' then deref- erencing -|bgcolor=ffcc99 rowspan=1 width="50px"| all '''meek''' then uniting -|bgcolor=ffcccc width="50px"| all '''firm''' then widening, rowing and voiding -|colspan=1 bgcolor=ffcccc| -Widening occurs if there is no loss of precision. For example: An INT will be coerced to a REAL, and a REAL will be coerced to a LONG REAL. But not vice-versa. Examples: -INT to LONG INT -INT to REAL -REAL to COMPL -BITS to []BOOL -BYTES to STRING -A variable can also be coerced (rowed) to an array of length 1. - -For example: -INT to [1]INT -REAL to [1]REAL etc -|- -!F
-i
-r
-m -|| -*Operands of formulas as "~" in:OP: ~ * ~ -*Parameters of transput calls -|colspan=3 bgcolor=ffcc99| Example: -UNION(INT,REAL) var := 1 -|- -!M
-e
-e
-k -|| -* Trimscripts (yielding INT) -* Enquiries: e.g. as "~" in the following -IF ~ THEN ... FI and -FROM ~ BY ~ TO ~ WHILE ~ DO ... OD etc -* Primaries of calls (e.g. sin in sin(x)) -|colspan=4 bgcolor=ffee99|Examples: -REF REF BOOL to BOOL -REF REF REF INT to INT -|- -!W
-e
-a
-k -|| -* Primaries of slices, as in "~" in: ~[1:99] -* Secondaries of selections, as "~" in: value OF ~ -|colspan=5 bgcolor=aaeeaa|Examples: -REF BOOL to REF BOOL -REF REF INT to REF INT -REF REF REF REAL to REF REAL -REF REF REF REF STRUCT to REF STRUCT -|- -!S
-o
-f
-t -|| The LHS of assignments, as "~" in: ~ := ... -|colspan=6 bgcolor=aaaaff| Example: -* deproceduring of: PROC REAL random: e.g. random -|} -For more details about Primaries and Secondaries refer to [[Operator_precedence#ALGOL_68|Operator precedence]]. - -
+ALGOL 68 has a hierarchy of contexts which determine which kind of coercions are available at a particular point in the program.
+See [[:Category:ALGOL_68_Coercions|ALGOL 68 Coercions]] for more details. ==See also== *[[Web 68]] @@ -284,13 +86,14 @@ For more details about Primaries and Secondaries refer to [[Operator_precedence# * [https://en.wikipedia.org/wiki/S3_(programming_language) S3 for ICL 2900] == Library code used in Rosetta Code samples == -[https://rosettacode.org/wiki/ALGOL_68/prelude Various (including the standard prelude)]
-
-[https://rosettacode.org/wiki/Category:ALGOL_68-files File related]
-[https://rosettacode.org/wiki/Category:ALGOL_68-l-system L-System related]
-[https://rosettacode.org/wiki/Category:ALGOL_68-primes Prime related]
-[https://rosettacode.org/wiki/Category:ALGOL_68-rows Row (array) related]
-[https://rosettacode.org/wiki/Category:ALGOL_68-sort Sorting related]
+* [[ALGOL_68/prelude|Various (including the standard prelude)]] +* +* [[:Category:ALGOL_68-bits|bit-manipulation related]] +* [[:Category:ALGOL_68-files|File related]] +* [[:Category:ALGOL_68-l-system|L-System related]] +* [[:Category:ALGOL_68-primes|Prime related]] +* [[:Category:ALGOL_68-rows|Row (array) related]] +* [[:Category:ALGOL_68-sort|Sorting related]] == Tools == [[Syntax_highlighting_using_Mediawiki_formatting#ALGOL 68|Format an upper-stropped Algol 68 source with Mediawiki markup]]
diff --git a/Lang/ALGOL-68/Elliptic-curve-arithmetic b/Lang/ALGOL-68/Elliptic-curve-arithmetic new file mode 120000 index 0000000000..88681d69e9 --- /dev/null +++ b/Lang/ALGOL-68/Elliptic-curve-arithmetic @@ -0,0 +1 @@ +../../Task/Elliptic-curve-arithmetic/ALGOL-68 \ No newline at end of file diff --git a/Lang/ALGOL-68/Permutation-test b/Lang/ALGOL-68/Permutation-test new file mode 120000 index 0000000000..1a8b7f20df --- /dev/null +++ b/Lang/ALGOL-68/Permutation-test @@ -0,0 +1 @@ +../../Task/Permutation-test/ALGOL-68 \ No newline at end of file diff --git a/Lang/ALGOL-68/Primes---allocate-descendants-to-their-ancestors b/Lang/ALGOL-68/Primes---allocate-descendants-to-their-ancestors new file mode 120000 index 0000000000..9bf6ed3e36 --- /dev/null +++ b/Lang/ALGOL-68/Primes---allocate-descendants-to-their-ancestors @@ -0,0 +1 @@ +../../Task/Primes---allocate-descendants-to-their-ancestors/ALGOL-68 \ No newline at end of file diff --git a/Lang/ALGOL-68/Pythagoras-tree b/Lang/ALGOL-68/Pythagoras-tree new file mode 120000 index 0000000000..8c304d8b68 --- /dev/null +++ b/Lang/ALGOL-68/Pythagoras-tree @@ -0,0 +1 @@ +../../Task/Pythagoras-tree/ALGOL-68 \ No newline at end of file diff --git a/Lang/ALGOL-68/Solve-a-Numbrix-puzzle b/Lang/ALGOL-68/Solve-a-Numbrix-puzzle new file mode 120000 index 0000000000..14e9e80e97 --- /dev/null +++ b/Lang/ALGOL-68/Solve-a-Numbrix-puzzle @@ -0,0 +1 @@ +../../Task/Solve-a-Numbrix-puzzle/ALGOL-68 \ No newline at end of file diff --git a/Lang/ALGOL-68/Solve-the-no-connection-puzzle b/Lang/ALGOL-68/Solve-the-no-connection-puzzle new file mode 120000 index 0000000000..0ffda5f1f9 --- /dev/null +++ b/Lang/ALGOL-68/Solve-the-no-connection-puzzle @@ -0,0 +1 @@ +../../Task/Solve-the-no-connection-puzzle/ALGOL-68 \ No newline at end of file diff --git a/Lang/ALGOL-68/Text-processing-2 b/Lang/ALGOL-68/Text-processing-2 new file mode 120000 index 0000000000..124fe3bf6c --- /dev/null +++ b/Lang/ALGOL-68/Text-processing-2 @@ -0,0 +1 @@ +../../Task/Text-processing-2/ALGOL-68 \ No newline at end of file diff --git a/Lang/ALGOL-68/Wasteful-equidigital-and-frugal-numbers b/Lang/ALGOL-68/Wasteful-equidigital-and-frugal-numbers new file mode 120000 index 0000000000..6de9ddaea1 --- /dev/null +++ b/Lang/ALGOL-68/Wasteful-equidigital-and-frugal-numbers @@ -0,0 +1 @@ +../../Task/Wasteful-equidigital-and-frugal-numbers/ALGOL-68 \ No newline at end of file diff --git a/Lang/ALGOL-M/Additive-primes b/Lang/ALGOL-M/Additive-primes new file mode 120000 index 0000000000..974f9484e7 --- /dev/null +++ b/Lang/ALGOL-M/Additive-primes @@ -0,0 +1 @@ +../../Task/Additive-primes/ALGOL-M \ No newline at end of file diff --git a/Lang/ANSI-BASIC/Levenshtein-distance b/Lang/ANSI-BASIC/Levenshtein-distance new file mode 120000 index 0000000000..92b553d536 --- /dev/null +++ b/Lang/ANSI-BASIC/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/ANSI-BASIC \ No newline at end of file diff --git a/Lang/ANSI-BASIC/M-bius-function b/Lang/ANSI-BASIC/M-bius-function new file mode 120000 index 0000000000..f786d2b99e --- /dev/null +++ b/Lang/ANSI-BASIC/M-bius-function @@ -0,0 +1 @@ +../../Task/M-bius-function/ANSI-BASIC \ No newline at end of file diff --git a/Lang/ANSI-BASIC/Magic-constant b/Lang/ANSI-BASIC/Magic-constant new file mode 120000 index 0000000000..7d2184182c --- /dev/null +++ b/Lang/ANSI-BASIC/Magic-constant @@ -0,0 +1 @@ +../../Task/Magic-constant/ANSI-BASIC \ No newline at end of file diff --git a/Lang/ANSI-BASIC/Map-range b/Lang/ANSI-BASIC/Map-range new file mode 120000 index 0000000000..829dfc3a26 --- /dev/null +++ b/Lang/ANSI-BASIC/Map-range @@ -0,0 +1 @@ +../../Task/Map-range/ANSI-BASIC \ No newline at end of file diff --git a/Lang/APL/Loops-Infinite b/Lang/APL/Loops-Infinite new file mode 120000 index 0000000000..0f3ec957d2 --- /dev/null +++ b/Lang/APL/Loops-Infinite @@ -0,0 +1 @@ +../../Task/Loops-Infinite/APL \ No newline at end of file diff --git a/Lang/APL/Sort-a-list-of-object-identifiers b/Lang/APL/Sort-a-list-of-object-identifiers new file mode 120000 index 0000000000..400cb9fc60 --- /dev/null +++ b/Lang/APL/Sort-a-list-of-object-identifiers @@ -0,0 +1 @@ +../../Task/Sort-a-list-of-object-identifiers/APL \ No newline at end of file diff --git a/Lang/APL/Strip-comments-from-a-string b/Lang/APL/Strip-comments-from-a-string new file mode 120000 index 0000000000..ff78e120aa --- /dev/null +++ b/Lang/APL/Strip-comments-from-a-string @@ -0,0 +1 @@ +../../Task/Strip-comments-from-a-string/APL \ No newline at end of file diff --git a/Lang/APL/Tic-tac-toe b/Lang/APL/Tic-tac-toe new file mode 120000 index 0000000000..58bb681d1c --- /dev/null +++ b/Lang/APL/Tic-tac-toe @@ -0,0 +1 @@ +../../Task/Tic-tac-toe/APL \ No newline at end of file diff --git a/Lang/ASIC/M-bius-function b/Lang/ASIC/M-bius-function new file mode 120000 index 0000000000..7848f34d54 --- /dev/null +++ b/Lang/ASIC/M-bius-function @@ -0,0 +1 @@ +../../Task/M-bius-function/ASIC \ No newline at end of file diff --git a/Lang/Action-/00-LANG.txt b/Lang/Action-/00-LANG.txt index b37eb47c8f..3811c3c636 100644 --- a/Lang/Action-/00-LANG.txt +++ b/Lang/Action-/00-LANG.txt @@ -4,7 +4,7 @@ }} Action! is a language written by Clinton Parker and published by Optimized Sytems Software (OSS) for the Atari 8-bit line of home computers. It is related to ALGOL and optimized for single-pass compilation to 6502 code. - +A manual for the language is available at https://seriouscomputerist.atariverse.com/media/pdf/manual/OSS%20OS-A+%20-%20Manual%20(1983).pdf ==See Also== * [[wp:Action!_(programming_language)|Action! on Wikipedia]] * [[ALGOL 68]] diff --git a/Lang/Ada/Cistercian-numerals b/Lang/Ada/Cistercian-numerals new file mode 120000 index 0000000000..a03109c188 --- /dev/null +++ b/Lang/Ada/Cistercian-numerals @@ -0,0 +1 @@ +../../Task/Cistercian-numerals/Ada \ No newline at end of file diff --git a/Lang/Ada/Curzon-numbers b/Lang/Ada/Curzon-numbers new file mode 120000 index 0000000000..4a77e1da8a --- /dev/null +++ b/Lang/Ada/Curzon-numbers @@ -0,0 +1 @@ +../../Task/Curzon-numbers/Ada \ No newline at end of file diff --git a/Lang/AppleScript/Bin-given-limits b/Lang/AppleScript/Bin-given-limits new file mode 120000 index 0000000000..955dc82ffb --- /dev/null +++ b/Lang/AppleScript/Bin-given-limits @@ -0,0 +1 @@ +../../Task/Bin-given-limits/AppleScript \ No newline at end of file diff --git a/Lang/AppleScript/Nth-root b/Lang/AppleScript/Nth-root new file mode 120000 index 0000000000..24be4fbbed --- /dev/null +++ b/Lang/AppleScript/Nth-root @@ -0,0 +1 @@ +../../Task/Nth-root/AppleScript \ No newline at end of file diff --git a/Lang/AppleScript/Write-float-arrays-to-a-text-file b/Lang/AppleScript/Write-float-arrays-to-a-text-file new file mode 120000 index 0000000000..d7524dd990 --- /dev/null +++ b/Lang/AppleScript/Write-float-arrays-to-a-text-file @@ -0,0 +1 @@ +../../Task/Write-float-arrays-to-a-text-file/AppleScript \ No newline at end of file diff --git a/Lang/Applesoft-BASIC/Cistercian-numerals b/Lang/Applesoft-BASIC/Cistercian-numerals new file mode 120000 index 0000000000..2c5e6c52c1 --- /dev/null +++ b/Lang/Applesoft-BASIC/Cistercian-numerals @@ -0,0 +1 @@ +../../Task/Cistercian-numerals/Applesoft-BASIC \ No newline at end of file diff --git a/Lang/Applesoft-BASIC/Formatted-numeric-output b/Lang/Applesoft-BASIC/Formatted-numeric-output new file mode 120000 index 0000000000..52c4ceb520 --- /dev/null +++ b/Lang/Applesoft-BASIC/Formatted-numeric-output @@ -0,0 +1 @@ +../../Task/Formatted-numeric-output/Applesoft-BASIC \ No newline at end of file diff --git a/Lang/Applesoft-BASIC/Levenshtein-distance b/Lang/Applesoft-BASIC/Levenshtein-distance new file mode 120000 index 0000000000..890eb3e044 --- /dev/null +++ b/Lang/Applesoft-BASIC/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/Applesoft-BASIC \ No newline at end of file diff --git a/Lang/Applesoft-BASIC/Multi-dimensional-array b/Lang/Applesoft-BASIC/Multi-dimensional-array new file mode 120000 index 0000000000..c47a96b8ff --- /dev/null +++ b/Lang/Applesoft-BASIC/Multi-dimensional-array @@ -0,0 +1 @@ +../../Task/Multi-dimensional-array/Applesoft-BASIC \ No newline at end of file diff --git a/Lang/Applesoft-BASIC/Towers-of-Hanoi b/Lang/Applesoft-BASIC/Towers-of-Hanoi new file mode 120000 index 0000000000..7e7bc24b30 --- /dev/null +++ b/Lang/Applesoft-BASIC/Towers-of-Hanoi @@ -0,0 +1 @@ +../../Task/Towers-of-Hanoi/Applesoft-BASIC \ No newline at end of file diff --git a/Lang/Arturo/Arithmetic-derivative b/Lang/Arturo/Arithmetic-derivative new file mode 120000 index 0000000000..d1b6630a6c --- /dev/null +++ b/Lang/Arturo/Arithmetic-derivative @@ -0,0 +1 @@ +../../Task/Arithmetic-derivative/Arturo \ No newline at end of file diff --git a/Lang/Arturo/Dice-game-probabilities b/Lang/Arturo/Dice-game-probabilities new file mode 120000 index 0000000000..963933dbf3 --- /dev/null +++ b/Lang/Arturo/Dice-game-probabilities @@ -0,0 +1 @@ +../../Task/Dice-game-probabilities/Arturo \ No newline at end of file diff --git a/Lang/Arturo/Element-wise-operations b/Lang/Arturo/Element-wise-operations new file mode 120000 index 0000000000..da54867937 --- /dev/null +++ b/Lang/Arturo/Element-wise-operations @@ -0,0 +1 @@ +../../Task/Element-wise-operations/Arturo \ No newline at end of file diff --git a/Lang/Arturo/Entropy-Narcissist b/Lang/Arturo/Entropy-Narcissist new file mode 120000 index 0000000000..a5a91d666a --- /dev/null +++ b/Lang/Arturo/Entropy-Narcissist @@ -0,0 +1 @@ +../../Task/Entropy-Narcissist/Arturo \ No newline at end of file diff --git a/Lang/Arturo/Munching-squares b/Lang/Arturo/Munching-squares new file mode 120000 index 0000000000..3d1757b680 --- /dev/null +++ b/Lang/Arturo/Munching-squares @@ -0,0 +1 @@ +../../Task/Munching-squares/Arturo \ No newline at end of file diff --git a/Lang/Asymptote/Evaluate-binomial-coefficients b/Lang/Asymptote/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..8408c303d7 --- /dev/null +++ b/Lang/Asymptote/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/Asymptote \ No newline at end of file diff --git a/Lang/Atari-BASIC/Pi b/Lang/Atari-BASIC/Pi new file mode 120000 index 0000000000..b081cc7024 --- /dev/null +++ b/Lang/Atari-BASIC/Pi @@ -0,0 +1 @@ +../../Task/Pi/Atari-BASIC \ No newline at end of file diff --git a/Lang/AutoHotKey-V2/00-LANG.txt b/Lang/AutoHotKey-V2/00-LANG.txt new file mode 100644 index 0000000000..a333f928af --- /dev/null +++ b/Lang/AutoHotKey-V2/00-LANG.txt @@ -0,0 +1 @@ +{{stub}}{{language|AutoHotKey V2}} \ No newline at end of file diff --git a/Lang/AutoHotKey-V2/00-META.yaml b/Lang/AutoHotKey-V2/00-META.yaml new file mode 100644 index 0000000000..316ebe0ccb --- /dev/null +++ b/Lang/AutoHotKey-V2/00-META.yaml @@ -0,0 +1,2 @@ +--- +from: http://rosettacode.org/wiki/Category:AutoHotKey_V2 diff --git a/Lang/AutoHotKey-V2/Hello-world-Graphical b/Lang/AutoHotKey-V2/Hello-world-Graphical new file mode 120000 index 0000000000..89783bc714 --- /dev/null +++ b/Lang/AutoHotKey-V2/Hello-world-Graphical @@ -0,0 +1 @@ +../../Task/Hello-world-Graphical/AutoHotKey-V2 \ No newline at end of file diff --git a/Lang/Autohotkey-V2/00-LANG.txt b/Lang/Autohotkey-V2/00-LANG.txt deleted file mode 100644 index b3e33b65ab..0000000000 --- a/Lang/Autohotkey-V2/00-LANG.txt +++ /dev/null @@ -1,16 +0,0 @@ -{{stub}}AutoHotkey V2 is an [[open source]] programming language for Microsoft [[Windows]]. - -AutoHotkey v2 is a major update to the AutoHotkey language, which includes numerous new features and improvements. - -== Citations == - -* [https://www.autohotkey.com/docs/v2/ Documentation] -* [http://autohotkey.com/download Downloads] -* [http://autohotkey.com/docs/scripts/ Script Showcase] -* [http://autohotkey.com/boards/ New Community forum] -* [http://www.autohotkey.com/forum/ Archived Community forum] -* [http://ahkscript.org/foundation AutoHotkey Foundation LLC] -* [[wp:AutoHotkey|AutoHotkey on Wikipedia]] -* #ahk on [http://webchat.freenode.net/?channels=%23ahk Freenode Web interface] -* [[:Category:AutoHotkey_Originated]] -{{language|Ayrch}} \ No newline at end of file diff --git a/Lang/Autohotkey-V2/00-META.yaml b/Lang/Autohotkey-V2/00-META.yaml deleted file mode 100644 index 651d1bc21b..0000000000 --- a/Lang/Autohotkey-V2/00-META.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -from: http://rosettacode.org/wiki/Category:Autohotkey_V2 diff --git a/Lang/Autohotkey-V2/Hello-world-Graphical b/Lang/Autohotkey-V2/Hello-world-Graphical deleted file mode 120000 index 0375a8eeb7..0000000000 --- a/Lang/Autohotkey-V2/Hello-world-Graphical +++ /dev/null @@ -1 +0,0 @@ -../../Task/Hello-world-Graphical/Autohotkey-V2 \ No newline at end of file diff --git a/Lang/BASIC/Partition-an-integer-x-into-n-primes b/Lang/BASIC/Partition-an-integer-x-into-n-primes new file mode 120000 index 0000000000..8db316776d --- /dev/null +++ b/Lang/BASIC/Partition-an-integer-x-into-n-primes @@ -0,0 +1 @@ +../../Task/Partition-an-integer-x-into-n-primes/BASIC \ No newline at end of file diff --git a/Lang/BASIC256/Evaluate-binomial-coefficients b/Lang/BASIC256/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..415fd5e54e --- /dev/null +++ b/Lang/BASIC256/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/BASIC256 \ No newline at end of file diff --git a/Lang/BQN/Find-common-directory-path b/Lang/BQN/Find-common-directory-path new file mode 120000 index 0000000000..d4456eaa79 --- /dev/null +++ b/Lang/BQN/Find-common-directory-path @@ -0,0 +1 @@ +../../Task/Find-common-directory-path/BQN \ No newline at end of file diff --git a/Lang/BQN/Globally-replace-text-in-several-files b/Lang/BQN/Globally-replace-text-in-several-files new file mode 120000 index 0000000000..b13db5355b --- /dev/null +++ b/Lang/BQN/Globally-replace-text-in-several-files @@ -0,0 +1 @@ +../../Task/Globally-replace-text-in-several-files/BQN \ No newline at end of file diff --git a/Lang/Ballerina/00-LANG.txt b/Lang/Ballerina/00-LANG.txt index af215acfd5..f56f4083d5 100644 --- a/Lang/Ballerina/00-LANG.txt +++ b/Lang/Ballerina/00-LANG.txt @@ -1 +1,17 @@ -{{stub}}{{language|Ballerina}} \ No newline at end of file +{{language|Ballerina +|exec=bytecode +|strength=strong +|safety=safe +|express=explicit +|checking=static +|gc=yes +|hopl=no +|site=https://ballerina.io +}} +'''[https://en.wikipedia.org/wiki/Ballerina_(programming_language) Ballerina]''' is an open source general-purpose programming language designed and supported by [https://wso2.com/ WSO2] for cloud-era application programmers. + +It is under development on [https://github.com/ballerina-platform/ballerina-lang GitHub] and is fully documented [https://ballerina.io here]. + +Ballerina was first publicly announced in 2017 and version 1.0 was released on September 10, 2019. However, a major overhaul took place in 2022 when [https://blog.ballerina.io/posts/2022-02-01-announcing-ballerina-2201.0.0-swan-lake/ Ballerina 2201.0.0 (Swan Lake)] was released. + +The current version (2201.12.3) has distributions available for Windows, Linux and macOS and can be downloaded [https://ballerina.io/downloads/ here]. \ No newline at end of file diff --git a/Lang/Ballerina/A+B b/Lang/Ballerina/A+B new file mode 120000 index 0000000000..e9aab74a73 --- /dev/null +++ b/Lang/Ballerina/A+B @@ -0,0 +1 @@ +../../Task/A+B/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/ABC-problem b/Lang/Ballerina/ABC-problem new file mode 120000 index 0000000000..49ca7ac9ad --- /dev/null +++ b/Lang/Ballerina/ABC-problem @@ -0,0 +1 @@ +../../Task/ABC-problem/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/AKS-test-for-primes b/Lang/Ballerina/AKS-test-for-primes new file mode 120000 index 0000000000..9b19f08d80 --- /dev/null +++ b/Lang/Ballerina/AKS-test-for-primes @@ -0,0 +1 @@ +../../Task/AKS-test-for-primes/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Abundant-deficient-and-perfect-number-classifications b/Lang/Ballerina/Abundant-deficient-and-perfect-number-classifications new file mode 120000 index 0000000000..b5353658a4 --- /dev/null +++ b/Lang/Ballerina/Abundant-deficient-and-perfect-number-classifications @@ -0,0 +1 @@ +../../Task/Abundant-deficient-and-perfect-number-classifications/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Abundant-odd-numbers b/Lang/Ballerina/Abundant-odd-numbers new file mode 120000 index 0000000000..0b3a97c4a1 --- /dev/null +++ b/Lang/Ballerina/Abundant-odd-numbers @@ -0,0 +1 @@ +../../Task/Abundant-odd-numbers/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Accumulator-factory b/Lang/Ballerina/Accumulator-factory new file mode 120000 index 0000000000..837dbbe6a0 --- /dev/null +++ b/Lang/Ballerina/Accumulator-factory @@ -0,0 +1 @@ +../../Task/Accumulator-factory/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Achilles-numbers b/Lang/Ballerina/Achilles-numbers new file mode 120000 index 0000000000..3336ab1c37 --- /dev/null +++ b/Lang/Ballerina/Achilles-numbers @@ -0,0 +1 @@ +../../Task/Achilles-numbers/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Ackermann-function b/Lang/Ballerina/Ackermann-function new file mode 120000 index 0000000000..b9748d884d --- /dev/null +++ b/Lang/Ballerina/Ackermann-function @@ -0,0 +1 @@ +../../Task/Ackermann-function/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Add-a-variable-to-a-class-instance-at-runtime b/Lang/Ballerina/Add-a-variable-to-a-class-instance-at-runtime new file mode 120000 index 0000000000..12efd91bd6 --- /dev/null +++ b/Lang/Ballerina/Add-a-variable-to-a-class-instance-at-runtime @@ -0,0 +1 @@ +../../Task/Add-a-variable-to-a-class-instance-at-runtime/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Additive-primes b/Lang/Ballerina/Additive-primes new file mode 120000 index 0000000000..a504210ea7 --- /dev/null +++ b/Lang/Ballerina/Additive-primes @@ -0,0 +1 @@ +../../Task/Additive-primes/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Address-of-a-variable b/Lang/Ballerina/Address-of-a-variable new file mode 120000 index 0000000000..6428e75ce3 --- /dev/null +++ b/Lang/Ballerina/Address-of-a-variable @@ -0,0 +1 @@ +../../Task/Address-of-a-variable/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Almost-prime b/Lang/Ballerina/Almost-prime new file mode 120000 index 0000000000..33d501af1e --- /dev/null +++ b/Lang/Ballerina/Almost-prime @@ -0,0 +1 @@ +../../Task/Almost-prime/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Amb b/Lang/Ballerina/Amb new file mode 120000 index 0000000000..7acc58d7c4 --- /dev/null +++ b/Lang/Ballerina/Amb @@ -0,0 +1 @@ +../../Task/Amb/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Angle-difference-between-two-bearings b/Lang/Ballerina/Angle-difference-between-two-bearings new file mode 120000 index 0000000000..04ff00d986 --- /dev/null +++ b/Lang/Ballerina/Angle-difference-between-two-bearings @@ -0,0 +1 @@ +../../Task/Angle-difference-between-two-bearings/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Anti-primes b/Lang/Ballerina/Anti-primes new file mode 120000 index 0000000000..9911fc0bcb --- /dev/null +++ b/Lang/Ballerina/Anti-primes @@ -0,0 +1 @@ +../../Task/Anti-primes/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Apply-a-callback-to-an-array b/Lang/Ballerina/Apply-a-callback-to-an-array new file mode 120000 index 0000000000..9911480671 --- /dev/null +++ b/Lang/Ballerina/Apply-a-callback-to-an-array @@ -0,0 +1 @@ +../../Task/Apply-a-callback-to-an-array/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Approximate-equality b/Lang/Ballerina/Approximate-equality new file mode 120000 index 0000000000..0ea6692d0d --- /dev/null +++ b/Lang/Ballerina/Approximate-equality @@ -0,0 +1 @@ +../../Task/Approximate-equality/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Arithmetic-Complex b/Lang/Ballerina/Arithmetic-Complex new file mode 120000 index 0000000000..f87fd15204 --- /dev/null +++ b/Lang/Ballerina/Arithmetic-Complex @@ -0,0 +1 @@ +../../Task/Arithmetic-Complex/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Arithmetic-Integer b/Lang/Ballerina/Arithmetic-Integer new file mode 120000 index 0000000000..a4c8cf5206 --- /dev/null +++ b/Lang/Ballerina/Arithmetic-Integer @@ -0,0 +1 @@ +../../Task/Arithmetic-Integer/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Arithmetic-Rational b/Lang/Ballerina/Arithmetic-Rational new file mode 120000 index 0000000000..422af5f88b --- /dev/null +++ b/Lang/Ballerina/Arithmetic-Rational @@ -0,0 +1 @@ +../../Task/Arithmetic-Rational/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Arithmetic-numbers b/Lang/Ballerina/Arithmetic-numbers new file mode 120000 index 0000000000..38541780a0 --- /dev/null +++ b/Lang/Ballerina/Arithmetic-numbers @@ -0,0 +1 @@ +../../Task/Arithmetic-numbers/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Array-concatenation b/Lang/Ballerina/Array-concatenation new file mode 120000 index 0000000000..41c2603b74 --- /dev/null +++ b/Lang/Ballerina/Array-concatenation @@ -0,0 +1 @@ +../../Task/Array-concatenation/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Array-length b/Lang/Ballerina/Array-length new file mode 120000 index 0000000000..25020148f9 --- /dev/null +++ b/Lang/Ballerina/Array-length @@ -0,0 +1 @@ +../../Task/Array-length/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Arrays b/Lang/Ballerina/Arrays new file mode 120000 index 0000000000..ec5c5a266e --- /dev/null +++ b/Lang/Ballerina/Arrays @@ -0,0 +1 @@ +../../Task/Arrays/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Ascending-primes b/Lang/Ballerina/Ascending-primes new file mode 120000 index 0000000000..51444ceb96 --- /dev/null +++ b/Lang/Ballerina/Ascending-primes @@ -0,0 +1 @@ +../../Task/Ascending-primes/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Associative-array-Creation b/Lang/Ballerina/Associative-array-Creation new file mode 120000 index 0000000000..2639b285f3 --- /dev/null +++ b/Lang/Ballerina/Associative-array-Creation @@ -0,0 +1 @@ +../../Task/Associative-array-Creation/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Associative-array-Iteration b/Lang/Ballerina/Associative-array-Iteration new file mode 120000 index 0000000000..d3e31d2374 --- /dev/null +++ b/Lang/Ballerina/Associative-array-Iteration @@ -0,0 +1 @@ +../../Task/Associative-array-Iteration/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Associative-array-Merging b/Lang/Ballerina/Associative-array-Merging new file mode 120000 index 0000000000..cd38137d75 --- /dev/null +++ b/Lang/Ballerina/Associative-array-Merging @@ -0,0 +1 @@ +../../Task/Associative-array-Merging/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Averages-Arithmetic-mean b/Lang/Ballerina/Averages-Arithmetic-mean new file mode 120000 index 0000000000..039d1f0de8 --- /dev/null +++ b/Lang/Ballerina/Averages-Arithmetic-mean @@ -0,0 +1 @@ +../../Task/Averages-Arithmetic-mean/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Averages-Mean-angle b/Lang/Ballerina/Averages-Mean-angle new file mode 120000 index 0000000000..adf77693ce --- /dev/null +++ b/Lang/Ballerina/Averages-Mean-angle @@ -0,0 +1 @@ +../../Task/Averages-Mean-angle/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Averages-Mean-time-of-day b/Lang/Ballerina/Averages-Mean-time-of-day new file mode 120000 index 0000000000..c969ed84e4 --- /dev/null +++ b/Lang/Ballerina/Averages-Mean-time-of-day @@ -0,0 +1 @@ +../../Task/Averages-Mean-time-of-day/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Averages-Median b/Lang/Ballerina/Averages-Median new file mode 120000 index 0000000000..5bbd39cecb --- /dev/null +++ b/Lang/Ballerina/Averages-Median @@ -0,0 +1 @@ +../../Task/Averages-Median/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Averages-Mode b/Lang/Ballerina/Averages-Mode new file mode 120000 index 0000000000..72d0e02dae --- /dev/null +++ b/Lang/Ballerina/Averages-Mode @@ -0,0 +1 @@ +../../Task/Averages-Mode/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Averages-Pythagorean-means b/Lang/Ballerina/Averages-Pythagorean-means new file mode 120000 index 0000000000..fd607a9ee8 --- /dev/null +++ b/Lang/Ballerina/Averages-Pythagorean-means @@ -0,0 +1 @@ +../../Task/Averages-Pythagorean-means/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Averages-Root-mean-square b/Lang/Ballerina/Averages-Root-mean-square new file mode 120000 index 0000000000..48056410d9 --- /dev/null +++ b/Lang/Ballerina/Averages-Root-mean-square @@ -0,0 +1 @@ +../../Task/Averages-Root-mean-square/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Averages-Simple-moving-average b/Lang/Ballerina/Averages-Simple-moving-average new file mode 120000 index 0000000000..7e2849cced --- /dev/null +++ b/Lang/Ballerina/Averages-Simple-moving-average @@ -0,0 +1 @@ +../../Task/Averages-Simple-moving-average/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Balanced-brackets b/Lang/Ballerina/Balanced-brackets new file mode 120000 index 0000000000..3d78b77dd3 --- /dev/null +++ b/Lang/Ballerina/Balanced-brackets @@ -0,0 +1 @@ +../../Task/Balanced-brackets/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Boolean-values b/Lang/Ballerina/Boolean-values new file mode 120000 index 0000000000..c01657f16a --- /dev/null +++ b/Lang/Ballerina/Boolean-values @@ -0,0 +1 @@ +../../Task/Boolean-values/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Caesar-cipher b/Lang/Ballerina/Caesar-cipher new file mode 120000 index 0000000000..8e1a6603e9 --- /dev/null +++ b/Lang/Ballerina/Caesar-cipher @@ -0,0 +1 @@ +../../Task/Caesar-cipher/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Calculating-the-value-of-e b/Lang/Ballerina/Calculating-the-value-of-e new file mode 120000 index 0000000000..af3085b824 --- /dev/null +++ b/Lang/Ballerina/Calculating-the-value-of-e @@ -0,0 +1 @@ +../../Task/Calculating-the-value-of-e/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Case-sensitivity-of-identifiers b/Lang/Ballerina/Case-sensitivity-of-identifiers new file mode 120000 index 0000000000..42725d41da --- /dev/null +++ b/Lang/Ballerina/Case-sensitivity-of-identifiers @@ -0,0 +1 @@ +../../Task/Case-sensitivity-of-identifiers/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Character-codes b/Lang/Ballerina/Character-codes new file mode 120000 index 0000000000..6abede048f --- /dev/null +++ b/Lang/Ballerina/Character-codes @@ -0,0 +1 @@ +../../Task/Character-codes/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Classes b/Lang/Ballerina/Classes new file mode 120000 index 0000000000..0c8bd2434d --- /dev/null +++ b/Lang/Ballerina/Classes @@ -0,0 +1 @@ +../../Task/Classes/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Count-in-octal b/Lang/Ballerina/Count-in-octal new file mode 120000 index 0000000000..7e70a67830 --- /dev/null +++ b/Lang/Ballerina/Count-in-octal @@ -0,0 +1 @@ +../../Task/Count-in-octal/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Currency b/Lang/Ballerina/Currency new file mode 120000 index 0000000000..2b278dfa20 --- /dev/null +++ b/Lang/Ballerina/Currency @@ -0,0 +1 @@ +../../Task/Currency/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Currying b/Lang/Ballerina/Currying new file mode 120000 index 0000000000..7e465c7834 --- /dev/null +++ b/Lang/Ballerina/Currying @@ -0,0 +1 @@ +../../Task/Currying/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Dynamic-variable-names b/Lang/Ballerina/Dynamic-variable-names new file mode 120000 index 0000000000..5c549728ae --- /dev/null +++ b/Lang/Ballerina/Dynamic-variable-names @@ -0,0 +1 @@ +../../Task/Dynamic-variable-names/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Empty-string b/Lang/Ballerina/Empty-string new file mode 120000 index 0000000000..a86a0ffc9d --- /dev/null +++ b/Lang/Ballerina/Empty-string @@ -0,0 +1 @@ +../../Task/Empty-string/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Extreme-floating-point-values b/Lang/Ballerina/Extreme-floating-point-values new file mode 120000 index 0000000000..7f91d37268 --- /dev/null +++ b/Lang/Ballerina/Extreme-floating-point-values @@ -0,0 +1 @@ +../../Task/Extreme-floating-point-values/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Farey-sequence b/Lang/Ballerina/Farey-sequence new file mode 120000 index 0000000000..d542459c5f --- /dev/null +++ b/Lang/Ballerina/Farey-sequence @@ -0,0 +1 @@ +../../Task/Farey-sequence/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Find-limit-of-recursion b/Lang/Ballerina/Find-limit-of-recursion new file mode 120000 index 0000000000..0c9c45aca0 --- /dev/null +++ b/Lang/Ballerina/Find-limit-of-recursion @@ -0,0 +1 @@ +../../Task/Find-limit-of-recursion/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Fivenum b/Lang/Ballerina/Fivenum new file mode 120000 index 0000000000..0df90aeb78 --- /dev/null +++ b/Lang/Ballerina/Fivenum @@ -0,0 +1 @@ +../../Task/Fivenum/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Floyds-triangle b/Lang/Ballerina/Floyds-triangle new file mode 120000 index 0000000000..524ef8d9d5 --- /dev/null +++ b/Lang/Ballerina/Floyds-triangle @@ -0,0 +1 @@ +../../Task/Floyds-triangle/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Four-bit-adder b/Lang/Ballerina/Four-bit-adder new file mode 120000 index 0000000000..da1ccb0292 --- /dev/null +++ b/Lang/Ballerina/Four-bit-adder @@ -0,0 +1 @@ +../../Task/Four-bit-adder/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Function-definition b/Lang/Ballerina/Function-definition new file mode 120000 index 0000000000..aad5e07c0c --- /dev/null +++ b/Lang/Ballerina/Function-definition @@ -0,0 +1 @@ +../../Task/Function-definition/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Gapful-numbers b/Lang/Ballerina/Gapful-numbers new file mode 120000 index 0000000000..16bb3670f6 --- /dev/null +++ b/Lang/Ballerina/Gapful-numbers @@ -0,0 +1 @@ +../../Task/Gapful-numbers/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Greatest-subsequential-sum b/Lang/Ballerina/Greatest-subsequential-sum new file mode 120000 index 0000000000..edc1a686d7 --- /dev/null +++ b/Lang/Ballerina/Greatest-subsequential-sum @@ -0,0 +1 @@ +../../Task/Greatest-subsequential-sum/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Hailstone-sequence b/Lang/Ballerina/Hailstone-sequence new file mode 120000 index 0000000000..41dfb14066 --- /dev/null +++ b/Lang/Ballerina/Hailstone-sequence @@ -0,0 +1 @@ +../../Task/Hailstone-sequence/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Hello-world-Newline-omission b/Lang/Ballerina/Hello-world-Newline-omission new file mode 120000 index 0000000000..1016c5553e --- /dev/null +++ b/Lang/Ballerina/Hello-world-Newline-omission @@ -0,0 +1 @@ +../../Task/Hello-world-Newline-omission/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Hello-world-Standard-error b/Lang/Ballerina/Hello-world-Standard-error new file mode 120000 index 0000000000..c4921dce1f --- /dev/null +++ b/Lang/Ballerina/Hello-world-Standard-error @@ -0,0 +1 @@ +../../Task/Hello-world-Standard-error/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Levenshtein-distance b/Lang/Ballerina/Levenshtein-distance new file mode 120000 index 0000000000..4824e03354 --- /dev/null +++ b/Lang/Ballerina/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loop-over-multiple-arrays-simultaneously b/Lang/Ballerina/Loop-over-multiple-arrays-simultaneously new file mode 120000 index 0000000000..9b68d094d5 --- /dev/null +++ b/Lang/Ballerina/Loop-over-multiple-arrays-simultaneously @@ -0,0 +1 @@ +../../Task/Loop-over-multiple-arrays-simultaneously/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Break b/Lang/Ballerina/Loops-Break new file mode 120000 index 0000000000..6ab612b087 --- /dev/null +++ b/Lang/Ballerina/Loops-Break @@ -0,0 +1 @@ +../../Task/Loops-Break/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Continue b/Lang/Ballerina/Loops-Continue new file mode 120000 index 0000000000..175be123b9 --- /dev/null +++ b/Lang/Ballerina/Loops-Continue @@ -0,0 +1 @@ +../../Task/Loops-Continue/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Do-while b/Lang/Ballerina/Loops-Do-while new file mode 120000 index 0000000000..b90c6b3171 --- /dev/null +++ b/Lang/Ballerina/Loops-Do-while @@ -0,0 +1 @@ +../../Task/Loops-Do-while/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Downward-for b/Lang/Ballerina/Loops-Downward-for new file mode 120000 index 0000000000..e977389f54 --- /dev/null +++ b/Lang/Ballerina/Loops-Downward-for @@ -0,0 +1 @@ +../../Task/Loops-Downward-for/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-For b/Lang/Ballerina/Loops-For new file mode 120000 index 0000000000..8ad2b8fd0c --- /dev/null +++ b/Lang/Ballerina/Loops-For @@ -0,0 +1 @@ +../../Task/Loops-For/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-For-with-a-specified-step b/Lang/Ballerina/Loops-For-with-a-specified-step new file mode 120000 index 0000000000..cc892dc7f2 --- /dev/null +++ b/Lang/Ballerina/Loops-For-with-a-specified-step @@ -0,0 +1 @@ +../../Task/Loops-For-with-a-specified-step/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Foreach b/Lang/Ballerina/Loops-Foreach new file mode 120000 index 0000000000..f819fadabe --- /dev/null +++ b/Lang/Ballerina/Loops-Foreach @@ -0,0 +1 @@ +../../Task/Loops-Foreach/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Increment-loop-index-within-loop-body b/Lang/Ballerina/Loops-Increment-loop-index-within-loop-body new file mode 120000 index 0000000000..1c9b81a58a --- /dev/null +++ b/Lang/Ballerina/Loops-Increment-loop-index-within-loop-body @@ -0,0 +1 @@ +../../Task/Loops-Increment-loop-index-within-loop-body/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Infinite b/Lang/Ballerina/Loops-Infinite new file mode 120000 index 0000000000..312369ce48 --- /dev/null +++ b/Lang/Ballerina/Loops-Infinite @@ -0,0 +1 @@ +../../Task/Loops-Infinite/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-N-plus-one-half b/Lang/Ballerina/Loops-N-plus-one-half new file mode 120000 index 0000000000..220ecbad7f --- /dev/null +++ b/Lang/Ballerina/Loops-N-plus-one-half @@ -0,0 +1 @@ +../../Task/Loops-N-plus-one-half/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Nested b/Lang/Ballerina/Loops-Nested new file mode 120000 index 0000000000..f32c9a3c17 --- /dev/null +++ b/Lang/Ballerina/Loops-Nested @@ -0,0 +1 @@ +../../Task/Loops-Nested/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-With-multiple-ranges b/Lang/Ballerina/Loops-With-multiple-ranges new file mode 120000 index 0000000000..2fad29a9f9 --- /dev/null +++ b/Lang/Ballerina/Loops-With-multiple-ranges @@ -0,0 +1 @@ +../../Task/Loops-With-multiple-ranges/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Loops-Wrong-ranges b/Lang/Ballerina/Loops-Wrong-ranges new file mode 120000 index 0000000000..6c8ada2aa7 --- /dev/null +++ b/Lang/Ballerina/Loops-Wrong-ranges @@ -0,0 +1 @@ +../../Task/Loops-Wrong-ranges/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Stack b/Lang/Ballerina/Stack new file mode 120000 index 0000000000..e073045735 --- /dev/null +++ b/Lang/Ballerina/Stack @@ -0,0 +1 @@ +../../Task/Stack/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Statistics-Basic b/Lang/Ballerina/Statistics-Basic new file mode 120000 index 0000000000..7ef892b782 --- /dev/null +++ b/Lang/Ballerina/Statistics-Basic @@ -0,0 +1 @@ +../../Task/Statistics-Basic/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Towers-of-Hanoi b/Lang/Ballerina/Towers-of-Hanoi new file mode 120000 index 0000000000..81bf7985bd --- /dev/null +++ b/Lang/Ballerina/Towers-of-Hanoi @@ -0,0 +1 @@ +../../Task/Towers-of-Hanoi/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Truncatable-primes b/Lang/Ballerina/Truncatable-primes new file mode 120000 index 0000000000..044dcb5d58 --- /dev/null +++ b/Lang/Ballerina/Truncatable-primes @@ -0,0 +1 @@ +../../Task/Truncatable-primes/Ballerina \ No newline at end of file diff --git a/Lang/Ballerina/Unicode-variable-names b/Lang/Ballerina/Unicode-variable-names new file mode 120000 index 0000000000..7f61255815 --- /dev/null +++ b/Lang/Ballerina/Unicode-variable-names @@ -0,0 +1 @@ +../../Task/Unicode-variable-names/Ballerina \ No newline at end of file diff --git a/Lang/C++/Currency b/Lang/C++/Currency new file mode 120000 index 0000000000..ae0e8d6190 --- /dev/null +++ b/Lang/C++/Currency @@ -0,0 +1 @@ +../../Task/Currency/C++ \ No newline at end of file diff --git a/Lang/C++/Strassens-algorithm b/Lang/C++/Strassens-algorithm new file mode 120000 index 0000000000..1423f44a39 --- /dev/null +++ b/Lang/C++/Strassens-algorithm @@ -0,0 +1 @@ +../../Task/Strassens-algorithm/C++ \ No newline at end of file diff --git a/Lang/C-sharp/ADFGVX-cipher b/Lang/C-sharp/ADFGVX-cipher new file mode 120000 index 0000000000..1bd5856497 --- /dev/null +++ b/Lang/C-sharp/ADFGVX-cipher @@ -0,0 +1 @@ +../../Task/ADFGVX-cipher/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/ASCII-art-diagram-converter b/Lang/C-sharp/ASCII-art-diagram-converter new file mode 120000 index 0000000000..a3c0a49ccd --- /dev/null +++ b/Lang/C-sharp/ASCII-art-diagram-converter @@ -0,0 +1 @@ +../../Task/ASCII-art-diagram-converter/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Arithmetic-derivative b/Lang/C-sharp/Arithmetic-derivative new file mode 120000 index 0000000000..99fc50446f --- /dev/null +++ b/Lang/C-sharp/Arithmetic-derivative @@ -0,0 +1 @@ +../../Task/Arithmetic-derivative/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Boyer-Moore-string-search b/Lang/C-sharp/Boyer-Moore-string-search new file mode 120000 index 0000000000..6d8ebe0502 --- /dev/null +++ b/Lang/C-sharp/Boyer-Moore-string-search @@ -0,0 +1 @@ +../../Task/Boyer-Moore-string-search/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Calkin-Wilf-sequence b/Lang/C-sharp/Calkin-Wilf-sequence new file mode 120000 index 0000000000..75d6e98750 --- /dev/null +++ b/Lang/C-sharp/Calkin-Wilf-sequence @@ -0,0 +1 @@ +../../Task/Calkin-Wilf-sequence/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n- b/Lang/C-sharp/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n- new file mode 120000 index 0000000000..2adfbd6635 --- /dev/null +++ b/Lang/C-sharp/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n- @@ -0,0 +1 @@ +../../Task/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n-/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Elliptic-Curve-Digital-Signature-Algorithm b/Lang/C-sharp/Elliptic-Curve-Digital-Signature-Algorithm new file mode 120000 index 0000000000..82412a8f32 --- /dev/null +++ b/Lang/C-sharp/Elliptic-Curve-Digital-Signature-Algorithm @@ -0,0 +1 @@ +../../Task/Elliptic-Curve-Digital-Signature-Algorithm/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Execute-a-Markov-algorithm b/Lang/C-sharp/Execute-a-Markov-algorithm new file mode 120000 index 0000000000..fac2e3f425 --- /dev/null +++ b/Lang/C-sharp/Execute-a-Markov-algorithm @@ -0,0 +1 @@ +../../Task/Execute-a-Markov-algorithm/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Extensible-prime-generator b/Lang/C-sharp/Extensible-prime-generator new file mode 120000 index 0000000000..1e4636d3bb --- /dev/null +++ b/Lang/C-sharp/Extensible-prime-generator @@ -0,0 +1 @@ +../../Task/Extensible-prime-generator/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/File-extension-is-in-extensions-list b/Lang/C-sharp/File-extension-is-in-extensions-list new file mode 120000 index 0000000000..caec470709 --- /dev/null +++ b/Lang/C-sharp/File-extension-is-in-extensions-list @@ -0,0 +1 @@ +../../Task/File-extension-is-in-extensions-list/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Find-if-a-point-is-within-a-triangle b/Lang/C-sharp/Find-if-a-point-is-within-a-triangle new file mode 120000 index 0000000000..0c9dec87d9 --- /dev/null +++ b/Lang/C-sharp/Find-if-a-point-is-within-a-triangle @@ -0,0 +1 @@ +../../Task/Find-if-a-point-is-within-a-triangle/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Gotchas b/Lang/C-sharp/Gotchas new file mode 120000 index 0000000000..c20938cf21 --- /dev/null +++ b/Lang/C-sharp/Gotchas @@ -0,0 +1 @@ +../../Task/Gotchas/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Index-finite-lists-of-positive-integers b/Lang/C-sharp/Index-finite-lists-of-positive-integers new file mode 120000 index 0000000000..692e611ddc --- /dev/null +++ b/Lang/C-sharp/Index-finite-lists-of-positive-integers @@ -0,0 +1 @@ +../../Task/Index-finite-lists-of-positive-integers/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/K-d-tree b/Lang/C-sharp/K-d-tree new file mode 120000 index 0000000000..9ea6355b83 --- /dev/null +++ b/Lang/C-sharp/K-d-tree @@ -0,0 +1 @@ +../../Task/K-d-tree/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Longest-string-challenge b/Lang/C-sharp/Longest-string-challenge new file mode 120000 index 0000000000..bd57b65702 --- /dev/null +++ b/Lang/C-sharp/Longest-string-challenge @@ -0,0 +1 @@ +../../Task/Longest-string-challenge/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/P-Adic-numbers-basic b/Lang/C-sharp/P-Adic-numbers-basic new file mode 120000 index 0000000000..564565afb6 --- /dev/null +++ b/Lang/C-sharp/P-Adic-numbers-basic @@ -0,0 +1 @@ +../../Task/P-Adic-numbers-basic/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Reflection-Get-source b/Lang/C-sharp/Reflection-Get-source new file mode 120000 index 0000000000..a8b2f45e4c --- /dev/null +++ b/Lang/C-sharp/Reflection-Get-source @@ -0,0 +1 @@ +../../Task/Reflection-Get-source/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Sequence:-smallest-number-with-exactly-n-divisors b/Lang/C-sharp/Sequence:-smallest-number-with-exactly-n-divisors new file mode 120000 index 0000000000..71508d1c44 --- /dev/null +++ b/Lang/C-sharp/Sequence:-smallest-number-with-exactly-n-divisors @@ -0,0 +1 @@ +../../Task/Sequence:-smallest-number-with-exactly-n-divisors/C-sharp \ No newline at end of file diff --git a/Lang/C-sharp/Strassens-algorithm b/Lang/C-sharp/Strassens-algorithm new file mode 120000 index 0000000000..45fd91dfa9 --- /dev/null +++ b/Lang/C-sharp/Strassens-algorithm @@ -0,0 +1 @@ +../../Task/Strassens-algorithm/C-sharp \ No newline at end of file diff --git a/Lang/C/Color-wheel b/Lang/C/Color-wheel new file mode 120000 index 0000000000..9d6561adcd --- /dev/null +++ b/Lang/C/Color-wheel @@ -0,0 +1 @@ +../../Task/Color-wheel/C \ No newline at end of file diff --git a/Lang/C/Magic-constant b/Lang/C/Magic-constant new file mode 120000 index 0000000000..3d29fd6624 --- /dev/null +++ b/Lang/C/Magic-constant @@ -0,0 +1 @@ +../../Task/Magic-constant/C \ No newline at end of file diff --git a/Lang/C3/Binary-digits b/Lang/C3/Binary-digits new file mode 120000 index 0000000000..34a04afae2 --- /dev/null +++ b/Lang/C3/Binary-digits @@ -0,0 +1 @@ +../../Task/Binary-digits/C3 \ No newline at end of file diff --git a/Lang/Chipmunk-Basic/Evaluate-binomial-coefficients b/Lang/Chipmunk-Basic/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..b45aed06e2 --- /dev/null +++ b/Lang/Chipmunk-Basic/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/Chipmunk-Basic \ No newline at end of file diff --git a/Lang/Crystal/Abbreviations-easy b/Lang/Crystal/Abbreviations-easy new file mode 120000 index 0000000000..b3a87e7119 --- /dev/null +++ b/Lang/Crystal/Abbreviations-easy @@ -0,0 +1 @@ +../../Task/Abbreviations-easy/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Anagrams-Deranged-anagrams b/Lang/Crystal/Anagrams-Deranged-anagrams new file mode 120000 index 0000000000..01826ee4a9 --- /dev/null +++ b/Lang/Crystal/Anagrams-Deranged-anagrams @@ -0,0 +1 @@ +../../Task/Anagrams-Deranged-anagrams/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Arithmetic-Complex b/Lang/Crystal/Arithmetic-Complex new file mode 120000 index 0000000000..db70676449 --- /dev/null +++ b/Lang/Crystal/Arithmetic-Complex @@ -0,0 +1 @@ +../../Task/Arithmetic-Complex/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Arithmetic-geometric-mean b/Lang/Crystal/Arithmetic-geometric-mean new file mode 120000 index 0000000000..c8754aa805 --- /dev/null +++ b/Lang/Crystal/Arithmetic-geometric-mean @@ -0,0 +1 @@ +../../Task/Arithmetic-geometric-mean/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Averages-Mode b/Lang/Crystal/Averages-Mode new file mode 120000 index 0000000000..bb15fa305b --- /dev/null +++ b/Lang/Crystal/Averages-Mode @@ -0,0 +1 @@ +../../Task/Averages-Mode/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Averages-Pythagorean-means b/Lang/Crystal/Averages-Pythagorean-means new file mode 120000 index 0000000000..a97d5df819 --- /dev/null +++ b/Lang/Crystal/Averages-Pythagorean-means @@ -0,0 +1 @@ +../../Task/Averages-Pythagorean-means/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Bin-given-limits b/Lang/Crystal/Bin-given-limits new file mode 120000 index 0000000000..40a049c833 --- /dev/null +++ b/Lang/Crystal/Bin-given-limits @@ -0,0 +1 @@ +../../Task/Bin-given-limits/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Character-codes b/Lang/Crystal/Character-codes new file mode 120000 index 0000000000..bd4879b77c --- /dev/null +++ b/Lang/Crystal/Character-codes @@ -0,0 +1 @@ +../../Task/Character-codes/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Cistercian-numerals b/Lang/Crystal/Cistercian-numerals new file mode 120000 index 0000000000..b439a8a963 --- /dev/null +++ b/Lang/Crystal/Cistercian-numerals @@ -0,0 +1 @@ +../../Task/Cistercian-numerals/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Closures-Value-capture b/Lang/Crystal/Closures-Value-capture new file mode 120000 index 0000000000..f3038be393 --- /dev/null +++ b/Lang/Crystal/Closures-Value-capture @@ -0,0 +1 @@ +../../Task/Closures-Value-capture/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Comma-quibbling b/Lang/Crystal/Comma-quibbling new file mode 120000 index 0000000000..3151a9c58f --- /dev/null +++ b/Lang/Crystal/Comma-quibbling @@ -0,0 +1 @@ +../../Task/Comma-quibbling/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Convert-seconds-to-compound-duration b/Lang/Crystal/Convert-seconds-to-compound-duration new file mode 120000 index 0000000000..313254bee3 --- /dev/null +++ b/Lang/Crystal/Convert-seconds-to-compound-duration @@ -0,0 +1 @@ +../../Task/Convert-seconds-to-compound-duration/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Determine-if-a-string-has-all-the-same-characters b/Lang/Crystal/Determine-if-a-string-has-all-the-same-characters new file mode 120000 index 0000000000..a0bef4d19a --- /dev/null +++ b/Lang/Crystal/Determine-if-a-string-has-all-the-same-characters @@ -0,0 +1 @@ +../../Task/Determine-if-a-string-has-all-the-same-characters/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Determine-if-a-string-is-collapsible b/Lang/Crystal/Determine-if-a-string-is-collapsible new file mode 120000 index 0000000000..7e2d57c2cb --- /dev/null +++ b/Lang/Crystal/Determine-if-a-string-is-collapsible @@ -0,0 +1 @@ +../../Task/Determine-if-a-string-is-collapsible/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Dijkstras-algorithm b/Lang/Crystal/Dijkstras-algorithm new file mode 120000 index 0000000000..829bbaa132 --- /dev/null +++ b/Lang/Crystal/Dijkstras-algorithm @@ -0,0 +1 @@ +../../Task/Dijkstras-algorithm/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Dutch-national-flag-problem b/Lang/Crystal/Dutch-national-flag-problem new file mode 120000 index 0000000000..a920e0b89a --- /dev/null +++ b/Lang/Crystal/Dutch-national-flag-problem @@ -0,0 +1 @@ +../../Task/Dutch-national-flag-problem/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Execute-Brain- b/Lang/Crystal/Execute-Brain- new file mode 120000 index 0000000000..4ffee47edd --- /dev/null +++ b/Lang/Crystal/Execute-Brain- @@ -0,0 +1 @@ +../../Task/Execute-Brain-/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Hello-world-Standard-error b/Lang/Crystal/Hello-world-Standard-error new file mode 120000 index 0000000000..560e23c97c --- /dev/null +++ b/Lang/Crystal/Hello-world-Standard-error @@ -0,0 +1 @@ +../../Task/Hello-world-Standard-error/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Hex-words b/Lang/Crystal/Hex-words new file mode 120000 index 0000000000..1390f8d3e3 --- /dev/null +++ b/Lang/Crystal/Hex-words @@ -0,0 +1 @@ +../../Task/Hex-words/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Increment-a-numerical-string b/Lang/Crystal/Increment-a-numerical-string new file mode 120000 index 0000000000..aeae95c765 --- /dev/null +++ b/Lang/Crystal/Increment-a-numerical-string @@ -0,0 +1 @@ +../../Task/Increment-a-numerical-string/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Interactive-programming-repl- b/Lang/Crystal/Interactive-programming-repl- new file mode 120000 index 0000000000..348f845b57 --- /dev/null +++ b/Lang/Crystal/Interactive-programming-repl- @@ -0,0 +1 @@ +../../Task/Interactive-programming-repl-/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Loops-N-plus-one-half b/Lang/Crystal/Loops-N-plus-one-half new file mode 120000 index 0000000000..baee612204 --- /dev/null +++ b/Lang/Crystal/Loops-N-plus-one-half @@ -0,0 +1 @@ +../../Task/Loops-N-plus-one-half/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Magic-8-ball b/Lang/Crystal/Magic-8-ball new file mode 120000 index 0000000000..7694de9dbd --- /dev/null +++ b/Lang/Crystal/Magic-8-ball @@ -0,0 +1 @@ +../../Task/Magic-8-ball/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Non-decimal-radices-Convert b/Lang/Crystal/Non-decimal-radices-Convert new file mode 120000 index 0000000000..342df0f845 --- /dev/null +++ b/Lang/Crystal/Non-decimal-radices-Convert @@ -0,0 +1 @@ +../../Task/Non-decimal-radices-Convert/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Order-by-pair-comparisons b/Lang/Crystal/Order-by-pair-comparisons new file mode 120000 index 0000000000..7f819e26a0 --- /dev/null +++ b/Lang/Crystal/Order-by-pair-comparisons @@ -0,0 +1 @@ +../../Task/Order-by-pair-comparisons/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Order-two-numerical-lists b/Lang/Crystal/Order-two-numerical-lists new file mode 120000 index 0000000000..44bdc040e5 --- /dev/null +++ b/Lang/Crystal/Order-two-numerical-lists @@ -0,0 +1 @@ +../../Task/Order-two-numerical-lists/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Phrase-reversals b/Lang/Crystal/Phrase-reversals new file mode 120000 index 0000000000..7a12cc6718 --- /dev/null +++ b/Lang/Crystal/Phrase-reversals @@ -0,0 +1 @@ +../../Task/Phrase-reversals/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Power-set b/Lang/Crystal/Power-set new file mode 120000 index 0000000000..0fd70fd5b9 --- /dev/null +++ b/Lang/Crystal/Power-set @@ -0,0 +1 @@ +../../Task/Power-set/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Run-length-encoding b/Lang/Crystal/Run-length-encoding new file mode 120000 index 0000000000..1a2b6b241a --- /dev/null +++ b/Lang/Crystal/Run-length-encoding @@ -0,0 +1 @@ +../../Task/Run-length-encoding/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Sort-an-array-of-composite-structures b/Lang/Crystal/Sort-an-array-of-composite-structures new file mode 120000 index 0000000000..5ea781aef9 --- /dev/null +++ b/Lang/Crystal/Sort-an-array-of-composite-structures @@ -0,0 +1 @@ +../../Task/Sort-an-array-of-composite-structures/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Sort-numbers-lexicographically b/Lang/Crystal/Sort-numbers-lexicographically new file mode 120000 index 0000000000..884dc88521 --- /dev/null +++ b/Lang/Crystal/Sort-numbers-lexicographically @@ -0,0 +1 @@ +../../Task/Sort-numbers-lexicographically/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Sort-three-variables b/Lang/Crystal/Sort-three-variables new file mode 120000 index 0000000000..e206daaf02 --- /dev/null +++ b/Lang/Crystal/Sort-three-variables @@ -0,0 +1 @@ +../../Task/Sort-three-variables/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Sorting-Algorithms-Circle-Sort b/Lang/Crystal/Sorting-Algorithms-Circle-Sort new file mode 120000 index 0000000000..2618e0f461 --- /dev/null +++ b/Lang/Crystal/Sorting-Algorithms-Circle-Sort @@ -0,0 +1 @@ +../../Task/Sorting-Algorithms-Circle-Sort/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Sorting-algorithms-Bubble-sort b/Lang/Crystal/Sorting-algorithms-Bubble-sort new file mode 120000 index 0000000000..88a150acfe --- /dev/null +++ b/Lang/Crystal/Sorting-algorithms-Bubble-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Bubble-sort/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Split-a-character-string-based-on-change-of-character b/Lang/Crystal/Split-a-character-string-based-on-change-of-character new file mode 120000 index 0000000000..874feaced9 --- /dev/null +++ b/Lang/Crystal/Split-a-character-string-based-on-change-of-character @@ -0,0 +1 @@ +../../Task/Split-a-character-string-based-on-change-of-character/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Stack-traces b/Lang/Crystal/Stack-traces new file mode 120000 index 0000000000..9cc8cddb52 --- /dev/null +++ b/Lang/Crystal/Stack-traces @@ -0,0 +1 @@ +../../Task/Stack-traces/Crystal \ No newline at end of file diff --git a/Lang/Crystal/String-prepend b/Lang/Crystal/String-prepend new file mode 120000 index 0000000000..2c5c171e4c --- /dev/null +++ b/Lang/Crystal/String-prepend @@ -0,0 +1 @@ +../../Task/String-prepend/Crystal \ No newline at end of file diff --git a/Lang/Crystal/Take-notes-on-the-command-line b/Lang/Crystal/Take-notes-on-the-command-line new file mode 120000 index 0000000000..e978486e4d --- /dev/null +++ b/Lang/Crystal/Take-notes-on-the-command-line @@ -0,0 +1 @@ +../../Task/Take-notes-on-the-command-line/Crystal \ No newline at end of file diff --git a/Lang/D/Find-Chess960-starting-position-identifier b/Lang/D/Find-Chess960-starting-position-identifier new file mode 120000 index 0000000000..79e07139b9 --- /dev/null +++ b/Lang/D/Find-Chess960-starting-position-identifier @@ -0,0 +1 @@ +../../Task/Find-Chess960-starting-position-identifier/D \ No newline at end of file diff --git a/Lang/Dart/24-game-Solve b/Lang/Dart/24-game-Solve new file mode 120000 index 0000000000..ae64875d6c --- /dev/null +++ b/Lang/Dart/24-game-Solve @@ -0,0 +1 @@ +../../Task/24-game-Solve/Dart \ No newline at end of file diff --git a/Lang/Dart/K-d-tree b/Lang/Dart/K-d-tree new file mode 120000 index 0000000000..4b4a8013e5 --- /dev/null +++ b/Lang/Dart/K-d-tree @@ -0,0 +1 @@ +../../Task/K-d-tree/Dart \ No newline at end of file diff --git a/Lang/Dart/Penneys-game b/Lang/Dart/Penneys-game new file mode 120000 index 0000000000..f054d83b87 --- /dev/null +++ b/Lang/Dart/Penneys-game @@ -0,0 +1 @@ +../../Task/Penneys-game/Dart \ No newline at end of file diff --git a/Lang/Delphi/Generate-Chess960-starting-position b/Lang/Delphi/Generate-Chess960-starting-position new file mode 120000 index 0000000000..2c3a66190d --- /dev/null +++ b/Lang/Delphi/Generate-Chess960-starting-position @@ -0,0 +1 @@ +../../Task/Generate-Chess960-starting-position/Delphi \ No newline at end of file diff --git a/Lang/ERRE/Leonardo-numbers b/Lang/ERRE/Leonardo-numbers new file mode 120000 index 0000000000..3e0d0050d1 --- /dev/null +++ b/Lang/ERRE/Leonardo-numbers @@ -0,0 +1 @@ +../../Task/Leonardo-numbers/ERRE \ No newline at end of file diff --git a/Lang/EasyLang/00-LANG.txt b/Lang/EasyLang/00-LANG.txt index ba3b92e229..e09a925b83 100644 --- a/Lang/EasyLang/00-LANG.txt +++ b/Lang/EasyLang/00-LANG.txt @@ -11,7 +11,7 @@ ''Easylang'' is a (beginners) programming language with built-in commands for graphics output. The statically typed language has a reduced syntax and semantics. Variables do not have to be declared, the data type is encoded in the variable name - as was usual in the earlier home computer BASIC. The data types are strings and numbers (floating point), arrays of strings and numbers, and arrays of arrays. Arrays are 1-based and can grow. Programs compiled into an AST tree run in the browser or in the browser IDE. -[https://easylang.dev/ide/ A browser IDE] with different tutorials, one for beginners, makes programming and learning to program as easy as possible. +[https://easylang.online/ide/ A browser IDE] with different tutorials, one for beginners, makes programming and learning to program as easy as possible. The finished programs can be easily integrated into a [https://easylang.online/apps/ website]. diff --git a/Lang/EasyLang/2048 b/Lang/EasyLang/2048 new file mode 120000 index 0000000000..4a69b16207 --- /dev/null +++ b/Lang/EasyLang/2048 @@ -0,0 +1 @@ +../../Task/2048/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Abbreviations-automatic b/Lang/EasyLang/Abbreviations-automatic new file mode 120000 index 0000000000..10b2251691 --- /dev/null +++ b/Lang/EasyLang/Abbreviations-automatic @@ -0,0 +1 @@ +../../Task/Abbreviations-automatic/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Abbreviations-easy b/Lang/EasyLang/Abbreviations-easy new file mode 120000 index 0000000000..9f43877f2b --- /dev/null +++ b/Lang/EasyLang/Abbreviations-easy @@ -0,0 +1 @@ +../../Task/Abbreviations-easy/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Abbreviations-simple b/Lang/EasyLang/Abbreviations-simple new file mode 120000 index 0000000000..53295111be --- /dev/null +++ b/Lang/EasyLang/Abbreviations-simple @@ -0,0 +1 @@ +../../Task/Abbreviations-simple/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Amb b/Lang/EasyLang/Amb new file mode 120000 index 0000000000..cee73196db --- /dev/null +++ b/Lang/EasyLang/Amb @@ -0,0 +1 @@ +../../Task/Amb/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Anagrams b/Lang/EasyLang/Anagrams new file mode 120000 index 0000000000..1a48ded8aa --- /dev/null +++ b/Lang/EasyLang/Anagrams @@ -0,0 +1 @@ +../../Task/Anagrams/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Anagrams-Deranged-anagrams b/Lang/EasyLang/Anagrams-Deranged-anagrams new file mode 120000 index 0000000000..b7af47405b --- /dev/null +++ b/Lang/EasyLang/Anagrams-Deranged-anagrams @@ -0,0 +1 @@ +../../Task/Anagrams-Deranged-anagrams/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Babylonian-spiral b/Lang/EasyLang/Babylonian-spiral new file mode 120000 index 0000000000..a141d2cd6b --- /dev/null +++ b/Lang/EasyLang/Babylonian-spiral @@ -0,0 +1 @@ +../../Task/Babylonian-spiral/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Boyer-Moore-string-search b/Lang/EasyLang/Boyer-Moore-string-search new file mode 120000 index 0000000000..189112146a --- /dev/null +++ b/Lang/EasyLang/Boyer-Moore-string-search @@ -0,0 +1 @@ +../../Task/Boyer-Moore-string-search/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Element-wise-operations b/Lang/EasyLang/Element-wise-operations new file mode 120000 index 0000000000..79d10fbb82 --- /dev/null +++ b/Lang/EasyLang/Element-wise-operations @@ -0,0 +1 @@ +../../Task/Element-wise-operations/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Factorions b/Lang/EasyLang/Factorions new file mode 120000 index 0000000000..52bf4a578c --- /dev/null +++ b/Lang/EasyLang/Factorions @@ -0,0 +1 @@ +../../Task/Factorions/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Mad-Libs b/Lang/EasyLang/Mad-Libs new file mode 120000 index 0000000000..80e4f5b2e7 --- /dev/null +++ b/Lang/EasyLang/Mad-Libs @@ -0,0 +1 @@ +../../Task/Mad-Libs/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Permutation-test b/Lang/EasyLang/Permutation-test new file mode 120000 index 0000000000..d3b1950f7a --- /dev/null +++ b/Lang/EasyLang/Permutation-test @@ -0,0 +1 @@ +../../Task/Permutation-test/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Prime-numbers-whose-neighboring-pairs-are-tetraprimes b/Lang/EasyLang/Prime-numbers-whose-neighboring-pairs-are-tetraprimes new file mode 120000 index 0000000000..deadbe682f --- /dev/null +++ b/Lang/EasyLang/Prime-numbers-whose-neighboring-pairs-are-tetraprimes @@ -0,0 +1 @@ +../../Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Primes---allocate-descendants-to-their-ancestors b/Lang/EasyLang/Primes---allocate-descendants-to-their-ancestors new file mode 120000 index 0000000000..c5cfa0147b --- /dev/null +++ b/Lang/EasyLang/Primes---allocate-descendants-to-their-ancestors @@ -0,0 +1 @@ +../../Task/Primes---allocate-descendants-to-their-ancestors/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Solve-a-Numbrix-puzzle b/Lang/EasyLang/Solve-a-Numbrix-puzzle new file mode 120000 index 0000000000..9dc56df255 --- /dev/null +++ b/Lang/EasyLang/Solve-a-Numbrix-puzzle @@ -0,0 +1 @@ +../../Task/Solve-a-Numbrix-puzzle/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Solve-the-no-connection-puzzle b/Lang/EasyLang/Solve-the-no-connection-puzzle new file mode 120000 index 0000000000..759be373e6 --- /dev/null +++ b/Lang/EasyLang/Solve-the-no-connection-puzzle @@ -0,0 +1 @@ +../../Task/Solve-the-no-connection-puzzle/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Sorting-algorithms-Patience-sort b/Lang/EasyLang/Sorting-algorithms-Patience-sort new file mode 120000 index 0000000000..6123828d8e --- /dev/null +++ b/Lang/EasyLang/Sorting-algorithms-Patience-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Patience-sort/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Unprimeable-numbers b/Lang/EasyLang/Unprimeable-numbers new file mode 120000 index 0000000000..ae808307c7 --- /dev/null +++ b/Lang/EasyLang/Unprimeable-numbers @@ -0,0 +1 @@ +../../Task/Unprimeable-numbers/EasyLang \ No newline at end of file diff --git a/Lang/EasyLang/Wasteful-equidigital-and-frugal-numbers b/Lang/EasyLang/Wasteful-equidigital-and-frugal-numbers new file mode 120000 index 0000000000..2c61d301f5 --- /dev/null +++ b/Lang/EasyLang/Wasteful-equidigital-and-frugal-numbers @@ -0,0 +1 @@ +../../Task/Wasteful-equidigital-and-frugal-numbers/EasyLang \ No newline at end of file diff --git a/Lang/Elena/00-LANG.txt b/Lang/Elena/00-LANG.txt index 671257e3ee..c3a21bf2d4 100644 --- a/Lang/Elena/00-LANG.txt +++ b/Lang/Elena/00-LANG.txt @@ -1,5 +1,5 @@ {{language|Elena -|site=http://elenalang.sourceforge.net +|site=https://elena-lang.github.io/ |exec=bytecode |strength=strong |safety=safe diff --git a/Lang/Elena/Comma-quibbling b/Lang/Elena/Comma-quibbling new file mode 120000 index 0000000000..f92aff5654 --- /dev/null +++ b/Lang/Elena/Comma-quibbling @@ -0,0 +1 @@ +../../Task/Comma-quibbling/Elena \ No newline at end of file diff --git a/Lang/Elena/Concurrent-computing b/Lang/Elena/Concurrent-computing new file mode 120000 index 0000000000..d22278e519 --- /dev/null +++ b/Lang/Elena/Concurrent-computing @@ -0,0 +1 @@ +../../Task/Concurrent-computing/Elena \ No newline at end of file diff --git a/Lang/Elena/HTTP b/Lang/Elena/HTTP new file mode 120000 index 0000000000..c94b6f99cd --- /dev/null +++ b/Lang/Elena/HTTP @@ -0,0 +1 @@ +../../Task/HTTP/Elena \ No newline at end of file diff --git a/Lang/Elena/HTTPS b/Lang/Elena/HTTPS new file mode 120000 index 0000000000..879dfcb045 --- /dev/null +++ b/Lang/Elena/HTTPS @@ -0,0 +1 @@ +../../Task/HTTPS/Elena \ No newline at end of file diff --git a/Lang/Emacs-Lisp/Color-wheel b/Lang/Emacs-Lisp/Color-wheel new file mode 120000 index 0000000000..90b9cec116 --- /dev/null +++ b/Lang/Emacs-Lisp/Color-wheel @@ -0,0 +1 @@ +../../Task/Color-wheel/Emacs-Lisp \ No newline at end of file diff --git a/Lang/Emacs-Lisp/Keyboard-input-Flush-the-keyboard-buffer b/Lang/Emacs-Lisp/Keyboard-input-Flush-the-keyboard-buffer new file mode 120000 index 0000000000..db888b4ffd --- /dev/null +++ b/Lang/Emacs-Lisp/Keyboard-input-Flush-the-keyboard-buffer @@ -0,0 +1 @@ +../../Task/Keyboard-input-Flush-the-keyboard-buffer/Emacs-Lisp \ No newline at end of file diff --git a/Lang/Emacs-Lisp/Keyboard-input-Keypress-check b/Lang/Emacs-Lisp/Keyboard-input-Keypress-check new file mode 120000 index 0000000000..1bf55a234e --- /dev/null +++ b/Lang/Emacs-Lisp/Keyboard-input-Keypress-check @@ -0,0 +1 @@ +../../Task/Keyboard-input-Keypress-check/Emacs-Lisp \ No newline at end of file diff --git a/Lang/Emacs-Lisp/Keyboard-input-Obtain-a-Y-or-N-response b/Lang/Emacs-Lisp/Keyboard-input-Obtain-a-Y-or-N-response new file mode 120000 index 0000000000..d6205cc54b --- /dev/null +++ b/Lang/Emacs-Lisp/Keyboard-input-Obtain-a-Y-or-N-response @@ -0,0 +1 @@ +../../Task/Keyboard-input-Obtain-a-Y-or-N-response/Emacs-Lisp \ No newline at end of file diff --git a/Lang/Emacs-Lisp/Split-a-character-string-based-on-change-of-character b/Lang/Emacs-Lisp/Split-a-character-string-based-on-change-of-character new file mode 120000 index 0000000000..7bff70bc55 --- /dev/null +++ b/Lang/Emacs-Lisp/Split-a-character-string-based-on-change-of-character @@ -0,0 +1 @@ +../../Task/Split-a-character-string-based-on-change-of-character/Emacs-Lisp \ No newline at end of file diff --git a/Lang/Emacs-Lisp/Strip-comments-from-a-string b/Lang/Emacs-Lisp/Strip-comments-from-a-string new file mode 120000 index 0000000000..e8fcd5a3c3 --- /dev/null +++ b/Lang/Emacs-Lisp/Strip-comments-from-a-string @@ -0,0 +1 @@ +../../Task/Strip-comments-from-a-string/Emacs-Lisp \ No newline at end of file diff --git a/Lang/Emacs-Lisp/Word-frequency b/Lang/Emacs-Lisp/Word-frequency new file mode 120000 index 0000000000..74fd09e7f4 --- /dev/null +++ b/Lang/Emacs-Lisp/Word-frequency @@ -0,0 +1 @@ +../../Task/Word-frequency/Emacs-Lisp \ No newline at end of file diff --git a/Lang/Erlang/Parse-an-IP-Address b/Lang/Erlang/Parse-an-IP-Address new file mode 120000 index 0000000000..3e48d0f0b1 --- /dev/null +++ b/Lang/Erlang/Parse-an-IP-Address @@ -0,0 +1 @@ +../../Task/Parse-an-IP-Address/Erlang \ No newline at end of file diff --git a/Lang/Excel/Arrays b/Lang/Excel/Arrays new file mode 120000 index 0000000000..bad8c856a9 --- /dev/null +++ b/Lang/Excel/Arrays @@ -0,0 +1 @@ +../../Task/Arrays/Excel \ No newline at end of file diff --git a/Lang/Excel/Conditional-structures b/Lang/Excel/Conditional-structures new file mode 120000 index 0000000000..f4ffdbd4b9 --- /dev/null +++ b/Lang/Excel/Conditional-structures @@ -0,0 +1 @@ +../../Task/Conditional-structures/Excel \ No newline at end of file diff --git a/Lang/Excel/FizzBuzz b/Lang/Excel/FizzBuzz new file mode 120000 index 0000000000..15df08a856 --- /dev/null +++ b/Lang/Excel/FizzBuzz @@ -0,0 +1 @@ +../../Task/FizzBuzz/Excel \ No newline at end of file diff --git a/Lang/Excel/Function-definition b/Lang/Excel/Function-definition new file mode 120000 index 0000000000..e6ecf64bef --- /dev/null +++ b/Lang/Excel/Function-definition @@ -0,0 +1 @@ +../../Task/Function-definition/Excel \ No newline at end of file diff --git a/Lang/Excel/Loops-For b/Lang/Excel/Loops-For new file mode 120000 index 0000000000..876b47b179 --- /dev/null +++ b/Lang/Excel/Loops-For @@ -0,0 +1 @@ +../../Task/Loops-For/Excel \ No newline at end of file diff --git a/Lang/Excel/Repeat-a-string b/Lang/Excel/Repeat-a-string new file mode 120000 index 0000000000..2c684073cb --- /dev/null +++ b/Lang/Excel/Repeat-a-string @@ -0,0 +1 @@ +../../Task/Repeat-a-string/Excel \ No newline at end of file diff --git a/Lang/Excel/Reverse-a-string b/Lang/Excel/Reverse-a-string new file mode 120000 index 0000000000..2a3cf97cfe --- /dev/null +++ b/Lang/Excel/Reverse-a-string @@ -0,0 +1 @@ +../../Task/Reverse-a-string/Excel \ No newline at end of file diff --git a/Lang/Excel/Tokenize-a-string b/Lang/Excel/Tokenize-a-string new file mode 120000 index 0000000000..9d5af3b4b4 --- /dev/null +++ b/Lang/Excel/Tokenize-a-string @@ -0,0 +1 @@ +../../Task/Tokenize-a-string/Excel \ No newline at end of file diff --git a/Lang/F-Sharp/Mad-Libs b/Lang/F-Sharp/Mad-Libs new file mode 120000 index 0000000000..69a30ced53 --- /dev/null +++ b/Lang/F-Sharp/Mad-Libs @@ -0,0 +1 @@ +../../Task/Mad-Libs/F-Sharp \ No newline at end of file diff --git a/Lang/Factor/Tic-tac-toe b/Lang/Factor/Tic-tac-toe new file mode 120000 index 0000000000..183c5fb3e0 --- /dev/null +++ b/Lang/Factor/Tic-tac-toe @@ -0,0 +1 @@ +../../Task/Tic-tac-toe/Factor \ No newline at end of file diff --git a/Lang/Forth/Almost-prime b/Lang/Forth/Almost-prime new file mode 120000 index 0000000000..bbe907fa90 --- /dev/null +++ b/Lang/Forth/Almost-prime @@ -0,0 +1 @@ +../../Task/Almost-prime/Forth \ No newline at end of file diff --git a/Lang/Fortran/Apply-a-digital-filter-direct-form-II-transposed- b/Lang/Fortran/Apply-a-digital-filter-direct-form-II-transposed- new file mode 120000 index 0000000000..dd0e66389d --- /dev/null +++ b/Lang/Fortran/Apply-a-digital-filter-direct-form-II-transposed- @@ -0,0 +1 @@ +../../Task/Apply-a-digital-filter-direct-form-II-transposed-/Fortran \ No newline at end of file diff --git a/Lang/Fortran/B-zier-curves-Intersections b/Lang/Fortran/B-zier-curves-Intersections new file mode 120000 index 0000000000..59ae9a9e9a --- /dev/null +++ b/Lang/Fortran/B-zier-curves-Intersections @@ -0,0 +1 @@ +../../Task/B-zier-curves-Intersections/Fortran \ No newline at end of file diff --git a/Lang/Fortran/Eulers-constant-0.5772... b/Lang/Fortran/Eulers-constant-0.5772... new file mode 120000 index 0000000000..e2642e24fb --- /dev/null +++ b/Lang/Fortran/Eulers-constant-0.5772... @@ -0,0 +1 @@ +../../Task/Eulers-constant-0.5772.../Fortran \ No newline at end of file diff --git a/Lang/Fortran/First-perfect-square-in-base-n-with-n-unique-digits b/Lang/Fortran/First-perfect-square-in-base-n-with-n-unique-digits new file mode 120000 index 0000000000..6f8a8ab270 --- /dev/null +++ b/Lang/Fortran/First-perfect-square-in-base-n-with-n-unique-digits @@ -0,0 +1 @@ +../../Task/First-perfect-square-in-base-n-with-n-unique-digits/Fortran \ No newline at end of file diff --git a/Lang/Fortran/Harmonic-series b/Lang/Fortran/Harmonic-series new file mode 120000 index 0000000000..6a6cd246a2 --- /dev/null +++ b/Lang/Fortran/Harmonic-series @@ -0,0 +1 @@ +../../Task/Harmonic-series/Fortran \ No newline at end of file diff --git a/Lang/Fortran/Knuths-algorithm-S b/Lang/Fortran/Knuths-algorithm-S new file mode 120000 index 0000000000..fe5b21ade9 --- /dev/null +++ b/Lang/Fortran/Knuths-algorithm-S @@ -0,0 +1 @@ +../../Task/Knuths-algorithm-S/Fortran \ No newline at end of file diff --git a/Lang/Fortran/Thieles-interpolation-formula b/Lang/Fortran/Thieles-interpolation-formula new file mode 120000 index 0000000000..f8f82960bc --- /dev/null +++ b/Lang/Fortran/Thieles-interpolation-formula @@ -0,0 +1 @@ +../../Task/Thieles-interpolation-formula/Fortran \ No newline at end of file diff --git a/Lang/Fortran/Vogels-approximation-method b/Lang/Fortran/Vogels-approximation-method new file mode 120000 index 0000000000..3098233175 --- /dev/null +++ b/Lang/Fortran/Vogels-approximation-method @@ -0,0 +1 @@ +../../Task/Vogels-approximation-method/Fortran \ No newline at end of file diff --git a/Lang/Free-Pascal-Lazarus/DNS-query b/Lang/Free-Pascal-Lazarus/DNS-query new file mode 120000 index 0000000000..f7c79b4afe --- /dev/null +++ b/Lang/Free-Pascal-Lazarus/DNS-query @@ -0,0 +1 @@ +../../Task/DNS-query/Free-Pascal-Lazarus \ No newline at end of file diff --git a/Lang/Free-Pascal-Lazarus/Levenshtein-distance b/Lang/Free-Pascal-Lazarus/Levenshtein-distance new file mode 120000 index 0000000000..eebdca8158 --- /dev/null +++ b/Lang/Free-Pascal-Lazarus/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/Free-Pascal-Lazarus \ No newline at end of file diff --git a/Lang/Free-Pascal-Lazarus/Map-range b/Lang/Free-Pascal-Lazarus/Map-range new file mode 120000 index 0000000000..65b07f3cc6 --- /dev/null +++ b/Lang/Free-Pascal-Lazarus/Map-range @@ -0,0 +1 @@ +../../Task/Map-range/Free-Pascal-Lazarus \ No newline at end of file diff --git a/Lang/FreeBASIC/Bioinformatics-Global-alignment b/Lang/FreeBASIC/Bioinformatics-Global-alignment new file mode 120000 index 0000000000..93fb335c5b --- /dev/null +++ b/Lang/FreeBASIC/Bioinformatics-Global-alignment @@ -0,0 +1 @@ +../../Task/Bioinformatics-Global-alignment/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Cistercian-numerals b/Lang/FreeBASIC/Cistercian-numerals new file mode 120000 index 0000000000..ceb56b6604 --- /dev/null +++ b/Lang/FreeBASIC/Cistercian-numerals @@ -0,0 +1 @@ +../../Task/Cistercian-numerals/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Compiler-syntax-analyzer b/Lang/FreeBASIC/Compiler-syntax-analyzer new file mode 120000 index 0000000000..a7d7204b01 --- /dev/null +++ b/Lang/FreeBASIC/Compiler-syntax-analyzer @@ -0,0 +1 @@ +../../Task/Compiler-syntax-analyzer/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Deconvolution-2D+ b/Lang/FreeBASIC/Deconvolution-2D+ new file mode 120000 index 0000000000..2a10e72230 --- /dev/null +++ b/Lang/FreeBASIC/Deconvolution-2D+ @@ -0,0 +1 @@ +../../Task/Deconvolution-2D+/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Distribution-of-0-digits-in-factorial-series b/Lang/FreeBASIC/Distribution-of-0-digits-in-factorial-series new file mode 120000 index 0000000000..caef600e25 --- /dev/null +++ b/Lang/FreeBASIC/Distribution-of-0-digits-in-factorial-series @@ -0,0 +1 @@ +../../Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Elliptic-curve-arithmetic b/Lang/FreeBASIC/Elliptic-curve-arithmetic new file mode 120000 index 0000000000..ab0b3f0aed --- /dev/null +++ b/Lang/FreeBASIC/Elliptic-curve-arithmetic @@ -0,0 +1 @@ +../../Task/Elliptic-curve-arithmetic/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Fermat-numbers b/Lang/FreeBASIC/Fermat-numbers new file mode 120000 index 0000000000..b6ff867057 --- /dev/null +++ b/Lang/FreeBASIC/Fermat-numbers @@ -0,0 +1 @@ +../../Task/Fermat-numbers/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Graph-colouring b/Lang/FreeBASIC/Graph-colouring new file mode 120000 index 0000000000..2b6f6e444d --- /dev/null +++ b/Lang/FreeBASIC/Graph-colouring @@ -0,0 +1 @@ +../../Task/Graph-colouring/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Juggler-sequence b/Lang/FreeBASIC/Juggler-sequence new file mode 120000 index 0000000000..5aaf9a794f --- /dev/null +++ b/Lang/FreeBASIC/Juggler-sequence @@ -0,0 +1 @@ +../../Task/Juggler-sequence/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Knuths-algorithm-S b/Lang/FreeBASIC/Knuths-algorithm-S new file mode 120000 index 0000000000..720a4a3a7e --- /dev/null +++ b/Lang/FreeBASIC/Knuths-algorithm-S @@ -0,0 +1 @@ +../../Task/Knuths-algorithm-S/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Knuths-power-tree b/Lang/FreeBASIC/Knuths-power-tree new file mode 120000 index 0000000000..b6075609dd --- /dev/null +++ b/Lang/FreeBASIC/Knuths-power-tree @@ -0,0 +1 @@ +../../Task/Knuths-power-tree/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Last-letter-first-letter b/Lang/FreeBASIC/Last-letter-first-letter new file mode 120000 index 0000000000..436ebfb8b9 --- /dev/null +++ b/Lang/FreeBASIC/Last-letter-first-letter @@ -0,0 +1 @@ +../../Task/Last-letter-first-letter/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Natural-sorting b/Lang/FreeBASIC/Natural-sorting new file mode 120000 index 0000000000..00267c2e93 --- /dev/null +++ b/Lang/FreeBASIC/Natural-sorting @@ -0,0 +1 @@ +../../Task/Natural-sorting/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Rosetta-Code-Fix-code-tags b/Lang/FreeBASIC/Rosetta-Code-Fix-code-tags new file mode 120000 index 0000000000..53b438e29f --- /dev/null +++ b/Lang/FreeBASIC/Rosetta-Code-Fix-code-tags @@ -0,0 +1 @@ +../../Task/Rosetta-Code-Fix-code-tags/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Rosetta-Code-Rank-languages-by-popularity b/Lang/FreeBASIC/Rosetta-Code-Rank-languages-by-popularity new file mode 120000 index 0000000000..71d538269e --- /dev/null +++ b/Lang/FreeBASIC/Rosetta-Code-Rank-languages-by-popularity @@ -0,0 +1 @@ +../../Task/Rosetta-Code-Rank-languages-by-popularity/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/SQL-based-authentication b/Lang/FreeBASIC/SQL-based-authentication new file mode 120000 index 0000000000..19b09b4fc4 --- /dev/null +++ b/Lang/FreeBASIC/SQL-based-authentication @@ -0,0 +1 @@ +../../Task/SQL-based-authentication/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Simulate-input-Keyboard b/Lang/FreeBASIC/Simulate-input-Keyboard new file mode 120000 index 0000000000..504f3b18d3 --- /dev/null +++ b/Lang/FreeBASIC/Simulate-input-Keyboard @@ -0,0 +1 @@ +../../Task/Simulate-input-Keyboard/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Sorting-algorithms-Strand-sort b/Lang/FreeBASIC/Sorting-algorithms-Strand-sort new file mode 120000 index 0000000000..5305f3c6f7 --- /dev/null +++ b/Lang/FreeBASIC/Sorting-algorithms-Strand-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Strand-sort/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Text-processing-2 b/Lang/FreeBASIC/Text-processing-2 new file mode 120000 index 0000000000..03a524d892 --- /dev/null +++ b/Lang/FreeBASIC/Text-processing-2 @@ -0,0 +1 @@ +../../Task/Text-processing-2/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Ukkonen-s-suffix-tree-construction b/Lang/FreeBASIC/Ukkonen-s-suffix-tree-construction new file mode 120000 index 0000000000..6686d05c91 --- /dev/null +++ b/Lang/FreeBASIC/Ukkonen-s-suffix-tree-construction @@ -0,0 +1 @@ +../../Task/Ukkonen-s-suffix-tree-construction/FreeBASIC \ No newline at end of file diff --git a/Lang/FreeBASIC/Word-ladder b/Lang/FreeBASIC/Word-ladder new file mode 120000 index 0000000000..1390108efe --- /dev/null +++ b/Lang/FreeBASIC/Word-ladder @@ -0,0 +1 @@ +../../Task/Word-ladder/FreeBASIC \ No newline at end of file diff --git a/Lang/GW-BASIC/Levenshtein-distance b/Lang/GW-BASIC/Levenshtein-distance new file mode 120000 index 0000000000..4605e15436 --- /dev/null +++ b/Lang/GW-BASIC/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/GW-BASIC \ No newline at end of file diff --git a/Lang/GW-BASIC/Magic-constant b/Lang/GW-BASIC/Magic-constant new file mode 120000 index 0000000000..4dbe3ee401 --- /dev/null +++ b/Lang/GW-BASIC/Magic-constant @@ -0,0 +1 @@ +../../Task/Magic-constant/GW-BASIC \ No newline at end of file diff --git a/Lang/GW-BASIC/Map-range b/Lang/GW-BASIC/Map-range new file mode 120000 index 0000000000..487538bdd0 --- /dev/null +++ b/Lang/GW-BASIC/Map-range @@ -0,0 +1 @@ +../../Task/Map-range/GW-BASIC \ No newline at end of file diff --git a/Lang/Gambas/Evaluate-binomial-coefficients b/Lang/Gambas/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..d84c9e286a --- /dev/null +++ b/Lang/Gambas/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/Gambas \ No newline at end of file diff --git a/Lang/Gambas/Magic-constant b/Lang/Gambas/Magic-constant new file mode 120000 index 0000000000..3e63290c94 --- /dev/null +++ b/Lang/Gambas/Magic-constant @@ -0,0 +1 @@ +../../Task/Magic-constant/Gambas \ No newline at end of file diff --git a/Lang/Go/Boyer-Moore-string-search b/Lang/Go/Boyer-Moore-string-search new file mode 120000 index 0000000000..0b971fdf3b --- /dev/null +++ b/Lang/Go/Boyer-Moore-string-search @@ -0,0 +1 @@ +../../Task/Boyer-Moore-string-search/Go \ No newline at end of file diff --git a/Lang/Go/Goldbachs-comet b/Lang/Go/Goldbachs-comet new file mode 120000 index 0000000000..e80a90c082 --- /dev/null +++ b/Lang/Go/Goldbachs-comet @@ -0,0 +1 @@ +../../Task/Goldbachs-comet/Go \ No newline at end of file diff --git a/Lang/Go/P-Adic-square-roots b/Lang/Go/P-Adic-square-roots new file mode 120000 index 0000000000..064157bec0 --- /dev/null +++ b/Lang/Go/P-Adic-square-roots @@ -0,0 +1 @@ +../../Task/P-Adic-square-roots/Go \ No newline at end of file diff --git a/Lang/Haskell/Pathological-floating-point-problems b/Lang/Haskell/Pathological-floating-point-problems new file mode 120000 index 0000000000..f17bacf62a --- /dev/null +++ b/Lang/Haskell/Pathological-floating-point-problems @@ -0,0 +1 @@ +../../Task/Pathological-floating-point-problems/Haskell \ No newline at end of file diff --git a/Lang/Icon/Loops-Increment-loop-index-within-loop-body b/Lang/Icon/Loops-Increment-loop-index-within-loop-body new file mode 120000 index 0000000000..19c94ce3da --- /dev/null +++ b/Lang/Icon/Loops-Increment-loop-index-within-loop-body @@ -0,0 +1 @@ +../../Task/Loops-Increment-loop-index-within-loop-body/Icon \ No newline at end of file diff --git a/Lang/Java/Strassens-algorithm b/Lang/Java/Strassens-algorithm new file mode 120000 index 0000000000..1c8b3f279b --- /dev/null +++ b/Lang/Java/Strassens-algorithm @@ -0,0 +1 @@ +../../Task/Strassens-algorithm/Java \ No newline at end of file diff --git a/Lang/JavaScript/15-puzzle-solver b/Lang/JavaScript/15-puzzle-solver new file mode 120000 index 0000000000..34b980cd29 --- /dev/null +++ b/Lang/JavaScript/15-puzzle-solver @@ -0,0 +1 @@ +../../Task/15-puzzle-solver/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/ADFGVX-cipher b/Lang/JavaScript/ADFGVX-cipher new file mode 120000 index 0000000000..eeef4038b2 --- /dev/null +++ b/Lang/JavaScript/ADFGVX-cipher @@ -0,0 +1 @@ +../../Task/ADFGVX-cipher/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Average-loop-length b/Lang/JavaScript/Average-loop-length new file mode 120000 index 0000000000..c1bd894dc5 --- /dev/null +++ b/Lang/JavaScript/Average-loop-length @@ -0,0 +1 @@ +../../Task/Average-loop-length/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Bifid-cipher b/Lang/JavaScript/Bifid-cipher new file mode 120000 index 0000000000..837e122e66 --- /dev/null +++ b/Lang/JavaScript/Bifid-cipher @@ -0,0 +1 @@ +../../Task/Bifid-cipher/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Bitcoin-address-validation b/Lang/JavaScript/Bitcoin-address-validation new file mode 120000 index 0000000000..d09d433cd8 --- /dev/null +++ b/Lang/JavaScript/Bitcoin-address-validation @@ -0,0 +1 @@ +../../Task/Bitcoin-address-validation/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Boyer-Moore-string-search b/Lang/JavaScript/Boyer-Moore-string-search new file mode 120000 index 0000000000..b25016942d --- /dev/null +++ b/Lang/JavaScript/Boyer-Moore-string-search @@ -0,0 +1 @@ +../../Task/Boyer-Moore-string-search/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Burrows-Wheeler-transform b/Lang/JavaScript/Burrows-Wheeler-transform new file mode 120000 index 0000000000..79a79f877d --- /dev/null +++ b/Lang/JavaScript/Burrows-Wheeler-transform @@ -0,0 +1 @@ +../../Task/Burrows-Wheeler-transform/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Camel-case-and-snake-case b/Lang/JavaScript/Camel-case-and-snake-case new file mode 120000 index 0000000000..0e52d396b8 --- /dev/null +++ b/Lang/JavaScript/Camel-case-and-snake-case @@ -0,0 +1 @@ +../../Task/Camel-case-and-snake-case/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Colorful-numbers b/Lang/JavaScript/Colorful-numbers new file mode 120000 index 0000000000..861658de92 --- /dev/null +++ b/Lang/JavaScript/Colorful-numbers @@ -0,0 +1 @@ +../../Task/Colorful-numbers/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Commatizing-numbers b/Lang/JavaScript/Commatizing-numbers new file mode 120000 index 0000000000..dac4a7f279 --- /dev/null +++ b/Lang/JavaScript/Commatizing-numbers @@ -0,0 +1 @@ +../../Task/Commatizing-numbers/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Compiler-code-generator b/Lang/JavaScript/Compiler-code-generator new file mode 120000 index 0000000000..7b6f8e25b0 --- /dev/null +++ b/Lang/JavaScript/Compiler-code-generator @@ -0,0 +1 @@ +../../Task/Compiler-code-generator/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Create-a-file-on-magnetic-tape b/Lang/JavaScript/Create-a-file-on-magnetic-tape new file mode 120000 index 0000000000..0f15206dcf --- /dev/null +++ b/Lang/JavaScript/Create-a-file-on-magnetic-tape @@ -0,0 +1 @@ +../../Task/Create-a-file-on-magnetic-tape/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Cyclotomic-polynomial b/Lang/JavaScript/Cyclotomic-polynomial new file mode 120000 index 0000000000..1407b6559c --- /dev/null +++ b/Lang/JavaScript/Cyclotomic-polynomial @@ -0,0 +1 @@ +../../Task/Cyclotomic-polynomial/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/De-Bruijn-sequences b/Lang/JavaScript/De-Bruijn-sequences new file mode 120000 index 0000000000..d753d9f9d0 --- /dev/null +++ b/Lang/JavaScript/De-Bruijn-sequences @@ -0,0 +1 @@ +../../Task/De-Bruijn-sequences/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Distribution-of-0-digits-in-factorial-series b/Lang/JavaScript/Distribution-of-0-digits-in-factorial-series new file mode 120000 index 0000000000..3fd7f0feb5 --- /dev/null +++ b/Lang/JavaScript/Distribution-of-0-digits-in-factorial-series @@ -0,0 +1 @@ +../../Task/Distribution-of-0-digits-in-factorial-series/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Elliptic-Curve-Digital-Signature-Algorithm b/Lang/JavaScript/Elliptic-Curve-Digital-Signature-Algorithm new file mode 120000 index 0000000000..b9a9906259 --- /dev/null +++ b/Lang/JavaScript/Elliptic-Curve-Digital-Signature-Algorithm @@ -0,0 +1 @@ +../../Task/Elliptic-Curve-Digital-Signature-Algorithm/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Elliptic-curve-arithmetic b/Lang/JavaScript/Elliptic-curve-arithmetic new file mode 120000 index 0000000000..41de6c075f --- /dev/null +++ b/Lang/JavaScript/Elliptic-curve-arithmetic @@ -0,0 +1 @@ +../../Task/Elliptic-curve-arithmetic/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Gauss-Jordan-matrix-inversion b/Lang/JavaScript/Gauss-Jordan-matrix-inversion new file mode 120000 index 0000000000..77acac5de4 --- /dev/null +++ b/Lang/JavaScript/Gauss-Jordan-matrix-inversion @@ -0,0 +1 @@ +../../Task/Gauss-Jordan-matrix-inversion/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Graph-colouring b/Lang/JavaScript/Graph-colouring new file mode 120000 index 0000000000..8c22e6e014 --- /dev/null +++ b/Lang/JavaScript/Graph-colouring @@ -0,0 +1 @@ +../../Task/Graph-colouring/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Greedy-algorithm-for-Egyptian-fractions b/Lang/JavaScript/Greedy-algorithm-for-Egyptian-fractions new file mode 120000 index 0000000000..4b7a0299ee --- /dev/null +++ b/Lang/JavaScript/Greedy-algorithm-for-Egyptian-fractions @@ -0,0 +1 @@ +../../Task/Greedy-algorithm-for-Egyptian-fractions/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Isqrt-integer-square-root-of-X b/Lang/JavaScript/Isqrt-integer-square-root-of-X new file mode 120000 index 0000000000..7c262657f5 --- /dev/null +++ b/Lang/JavaScript/Isqrt-integer-square-root-of-X @@ -0,0 +1 @@ +../../Task/Isqrt-integer-square-root-of-X/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Jacobi-symbol b/Lang/JavaScript/Jacobi-symbol new file mode 120000 index 0000000000..7ca750b7ca --- /dev/null +++ b/Lang/JavaScript/Jacobi-symbol @@ -0,0 +1 @@ +../../Task/Jacobi-symbol/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/K-d-tree b/Lang/JavaScript/K-d-tree new file mode 120000 index 0000000000..f551f8aa55 --- /dev/null +++ b/Lang/JavaScript/K-d-tree @@ -0,0 +1 @@ +../../Task/K-d-tree/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Knuths-algorithm-S b/Lang/JavaScript/Knuths-algorithm-S new file mode 120000 index 0000000000..78ce9e9420 --- /dev/null +++ b/Lang/JavaScript/Knuths-algorithm-S @@ -0,0 +1 @@ +../../Task/Knuths-algorithm-S/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Knuths-power-tree b/Lang/JavaScript/Knuths-power-tree new file mode 120000 index 0000000000..65f212b8ef --- /dev/null +++ b/Lang/JavaScript/Knuths-power-tree @@ -0,0 +1 @@ +../../Task/Knuths-power-tree/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/M-bius-function b/Lang/JavaScript/M-bius-function new file mode 120000 index 0000000000..8b88e437b9 --- /dev/null +++ b/Lang/JavaScript/M-bius-function @@ -0,0 +1 @@ +../../Task/M-bius-function/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/MD5-Implementation b/Lang/JavaScript/MD5-Implementation new file mode 120000 index 0000000000..96da37623c --- /dev/null +++ b/Lang/JavaScript/MD5-Implementation @@ -0,0 +1 @@ +../../Task/MD5-Implementation/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/P-Adic-numbers-basic b/Lang/JavaScript/P-Adic-numbers-basic new file mode 120000 index 0000000000..8430626fe6 --- /dev/null +++ b/Lang/JavaScript/P-Adic-numbers-basic @@ -0,0 +1 @@ +../../Task/P-Adic-numbers-basic/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/P-Adic-square-roots b/Lang/JavaScript/P-Adic-square-roots new file mode 120000 index 0000000000..dc1614d80a --- /dev/null +++ b/Lang/JavaScript/P-Adic-square-roots @@ -0,0 +1 @@ +../../Task/P-Adic-square-roots/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Perlin-noise b/Lang/JavaScript/Perlin-noise new file mode 120000 index 0000000000..d4cfceb70d --- /dev/null +++ b/Lang/JavaScript/Perlin-noise @@ -0,0 +1 @@ +../../Task/Perlin-noise/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Playfair-cipher b/Lang/JavaScript/Playfair-cipher new file mode 120000 index 0000000000..e94d50f327 --- /dev/null +++ b/Lang/JavaScript/Playfair-cipher @@ -0,0 +1 @@ +../../Task/Playfair-cipher/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/SHA-1 b/Lang/JavaScript/SHA-1 new file mode 120000 index 0000000000..2773e9c63c --- /dev/null +++ b/Lang/JavaScript/SHA-1 @@ -0,0 +1 @@ +../../Task/SHA-1/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Set-puzzle b/Lang/JavaScript/Set-puzzle new file mode 120000 index 0000000000..22b0bad552 --- /dev/null +++ b/Lang/JavaScript/Set-puzzle @@ -0,0 +1 @@ +../../Task/Set-puzzle/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Solve-a-Hidato-puzzle b/Lang/JavaScript/Solve-a-Hidato-puzzle new file mode 120000 index 0000000000..3e3c25cd7c --- /dev/null +++ b/Lang/JavaScript/Solve-a-Hidato-puzzle @@ -0,0 +1 @@ +../../Task/Solve-a-Hidato-puzzle/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Solve-a-Numbrix-puzzle b/Lang/JavaScript/Solve-a-Numbrix-puzzle new file mode 120000 index 0000000000..43202401f9 --- /dev/null +++ b/Lang/JavaScript/Solve-a-Numbrix-puzzle @@ -0,0 +1 @@ +../../Task/Solve-a-Numbrix-puzzle/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Sorting-algorithms-Radix-sort b/Lang/JavaScript/Sorting-algorithms-Radix-sort new file mode 120000 index 0000000000..0d4b9cb23d --- /dev/null +++ b/Lang/JavaScript/Sorting-algorithms-Radix-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Radix-sort/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Spelling-of-ordinal-numbers b/Lang/JavaScript/Spelling-of-ordinal-numbers new file mode 120000 index 0000000000..5ed638cc81 --- /dev/null +++ b/Lang/JavaScript/Spelling-of-ordinal-numbers @@ -0,0 +1 @@ +../../Task/Spelling-of-ordinal-numbers/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/State-name-puzzle b/Lang/JavaScript/State-name-puzzle new file mode 120000 index 0000000000..12f667dc4c --- /dev/null +++ b/Lang/JavaScript/State-name-puzzle @@ -0,0 +1 @@ +../../Task/State-name-puzzle/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Strassens-algorithm b/Lang/JavaScript/Strassens-algorithm new file mode 120000 index 0000000000..f4d0497694 --- /dev/null +++ b/Lang/JavaScript/Strassens-algorithm @@ -0,0 +1 @@ +../../Task/Strassens-algorithm/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Substitution-cipher b/Lang/JavaScript/Substitution-cipher new file mode 120000 index 0000000000..e8fd969b4a --- /dev/null +++ b/Lang/JavaScript/Substitution-cipher @@ -0,0 +1 @@ +../../Task/Substitution-cipher/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Tonelli-Shanks-algorithm b/Lang/JavaScript/Tonelli-Shanks-algorithm new file mode 120000 index 0000000000..f646a271d1 --- /dev/null +++ b/Lang/JavaScript/Tonelli-Shanks-algorithm @@ -0,0 +1 @@ +../../Task/Tonelli-Shanks-algorithm/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Ukkonen-s-suffix-tree-construction b/Lang/JavaScript/Ukkonen-s-suffix-tree-construction new file mode 120000 index 0000000000..7a4d0832f5 --- /dev/null +++ b/Lang/JavaScript/Ukkonen-s-suffix-tree-construction @@ -0,0 +1 @@ +../../Task/Ukkonen-s-suffix-tree-construction/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Verhoeff-algorithm b/Lang/JavaScript/Verhoeff-algorithm new file mode 120000 index 0000000000..cd27def09b --- /dev/null +++ b/Lang/JavaScript/Verhoeff-algorithm @@ -0,0 +1 @@ +../../Task/Verhoeff-algorithm/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Vigen-re-cipher-Cryptanalysis b/Lang/JavaScript/Vigen-re-cipher-Cryptanalysis new file mode 120000 index 0000000000..53c004e91c --- /dev/null +++ b/Lang/JavaScript/Vigen-re-cipher-Cryptanalysis @@ -0,0 +1 @@ +../../Task/Vigen-re-cipher-Cryptanalysis/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Vogels-approximation-method b/Lang/JavaScript/Vogels-approximation-method new file mode 120000 index 0000000000..72693f1daa --- /dev/null +++ b/Lang/JavaScript/Vogels-approximation-method @@ -0,0 +1 @@ +../../Task/Vogels-approximation-method/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Wordiff b/Lang/JavaScript/Wordiff new file mode 120000 index 0000000000..18ec352da6 --- /dev/null +++ b/Lang/JavaScript/Wordiff @@ -0,0 +1 @@ +../../Task/Wordiff/JavaScript \ No newline at end of file diff --git a/Lang/JavaScript/Zebra-puzzle b/Lang/JavaScript/Zebra-puzzle new file mode 120000 index 0000000000..5c531004b3 --- /dev/null +++ b/Lang/JavaScript/Zebra-puzzle @@ -0,0 +1 @@ +../../Task/Zebra-puzzle/JavaScript \ No newline at end of file diff --git a/Lang/K/Compare-length-of-two-strings b/Lang/K/Compare-length-of-two-strings new file mode 120000 index 0000000000..9854a6e09b --- /dev/null +++ b/Lang/K/Compare-length-of-two-strings @@ -0,0 +1 @@ +../../Task/Compare-length-of-two-strings/K \ No newline at end of file diff --git a/Lang/K/Euler-method b/Lang/K/Euler-method new file mode 120000 index 0000000000..c1f821dc7c --- /dev/null +++ b/Lang/K/Euler-method @@ -0,0 +1 @@ +../../Task/Euler-method/K \ No newline at end of file diff --git a/Lang/K/M-bius-function b/Lang/K/M-bius-function new file mode 120000 index 0000000000..e4dca86d37 --- /dev/null +++ b/Lang/K/M-bius-function @@ -0,0 +1 @@ +../../Task/M-bius-function/K \ No newline at end of file diff --git a/Lang/K/Substring b/Lang/K/Substring new file mode 120000 index 0000000000..002d50df4f --- /dev/null +++ b/Lang/K/Substring @@ -0,0 +1 @@ +../../Task/Substring/K \ No newline at end of file diff --git a/Lang/K/UTF-8-encode-and-decode b/Lang/K/UTF-8-encode-and-decode new file mode 120000 index 0000000000..f38c9e1894 --- /dev/null +++ b/Lang/K/UTF-8-encode-and-decode @@ -0,0 +1 @@ +../../Task/UTF-8-encode-and-decode/K \ No newline at end of file diff --git a/Lang/K/Write-float-arrays-to-a-text-file b/Lang/K/Write-float-arrays-to-a-text-file new file mode 120000 index 0000000000..2af99671ba --- /dev/null +++ b/Lang/K/Write-float-arrays-to-a-text-file @@ -0,0 +1 @@ +../../Task/Write-float-arrays-to-a-text-file/K \ No newline at end of file diff --git a/Lang/Logo/Merge-and-aggregate-datasets b/Lang/Logo/Merge-and-aggregate-datasets new file mode 120000 index 0000000000..f9a42bcf33 --- /dev/null +++ b/Lang/Logo/Merge-and-aggregate-datasets @@ -0,0 +1 @@ +../../Task/Merge-and-aggregate-datasets/Logo \ No newline at end of file diff --git a/Lang/Lua/Check-input-device-is-a-terminal b/Lang/Lua/Check-input-device-is-a-terminal new file mode 120000 index 0000000000..fdc01bb562 --- /dev/null +++ b/Lang/Lua/Check-input-device-is-a-terminal @@ -0,0 +1 @@ +../../Task/Check-input-device-is-a-terminal/Lua \ No newline at end of file diff --git a/Lang/Lua/Parse-an-IP-Address b/Lang/Lua/Parse-an-IP-Address new file mode 120000 index 0000000000..aa0f24a93c --- /dev/null +++ b/Lang/Lua/Parse-an-IP-Address @@ -0,0 +1 @@ +../../Task/Parse-an-IP-Address/Lua \ No newline at end of file diff --git a/Lang/Lua/Ramer-Douglas-Peucker-line-simplification b/Lang/Lua/Ramer-Douglas-Peucker-line-simplification new file mode 120000 index 0000000000..516d951928 --- /dev/null +++ b/Lang/Lua/Ramer-Douglas-Peucker-line-simplification @@ -0,0 +1 @@ +../../Task/Ramer-Douglas-Peucker-line-simplification/Lua \ No newline at end of file diff --git a/Lang/Lua/Update-a-configuration-file b/Lang/Lua/Update-a-configuration-file new file mode 120000 index 0000000000..75ad1d2a09 --- /dev/null +++ b/Lang/Lua/Update-a-configuration-file @@ -0,0 +1 @@ +../../Task/Update-a-configuration-file/Lua \ No newline at end of file diff --git a/Lang/M2000-Interpreter/00-LANG.txt b/Lang/M2000-Interpreter/00-LANG.txt index feda8eeb04..5e1cdf3a46 100644 --- a/Lang/M2000-Interpreter/00-LANG.txt +++ b/Lang/M2000-Interpreter/00-LANG.txt @@ -9,7 +9,7 @@ |gc=allowed |hopl=no }} -M2000 is an interpreter running on its own Environment written in Visual Basic 6, as an open source project and can be found in GitHub[https://github.com/M2000Interpreter/Version9]. Current version is 12, revision 13. See [[M2000 Interpreter Implementation]] +M2000 is an interpreter running on its own Environment written in Visual Basic 6, as an open source project and can be found in GitHub[https://github.com/M2000Interpreter/Version9]. Current version is 14, revision 4. See [[M2000 Interpreter Implementation]] {{language programming paradigm|Imperative}} {{language programming paradigm|Object-oriented}} {{Language programming paradigm|Event-driven}} @@ -21,12 +21,68 @@ M2000 has two set of vocabularies, one with English identifiers and one with Gre M2000 start as an experimental interpreted language, using a Module in Module idea (like a Procedure in Procedure) where each inner Module is closed for modification, but open for expansion, by replacing code at run time. Source code executed as is, without second interpretation of a simple form, although block of code arranged for execution in a manner of consuming code (code which executed deleted, code in a loop kept as a copy for next iteration). +We can use BASIC type statement's. Although there are some differences. Like the FOR NEXT: + +SET SWITCHES "+FOR" +// WHY ? BECAUSE WHEN STEP IS POSITIVE (+1 HERE) +// WE GET ITERATION IF START VALUE IS LESS OR EQUAL THE LAST VALUE +FOR I=10 TO 0 + PRINT "NEVER PRINT - IS LIKE BASIC" +NEXT +SET SWITCHES "+DIM" +// WHY ? BECAUSE DIM MAKE AN ARRAY FROM 0 TO TOP VALUE (10) +DIM A(10)=1 +PRINT LEN(A())=11, A(0), A(10), "BASIC" + +SET SWITCHES "-FOR" ' THE DEFAULT +// WHY ? BECAUSE EVERY TIME ITERATE FROM START VALUE TO END VALUE +FOR I=10 TO 0 + PRINT "ALWAYS PRINT - IS NOT LIKE BASIC" +NEXT + +SET SWITCHES "-DIM" +// WHY ? BECAUSE DIM MAKE AN ARRAY N (10) ITEMS +DIM A(10)=1 +PRINT LEN(A())=10, A(0), A(9), "M2000" +DIM B(0 TO 10)=1 ' WE CAN DEFINE MIN AND MAX INDEX (CAN BE NEGATIVE) +PRINT LEN(B())=11, B(0), B(10), "M2000" + + Module's may be Global, or local to other modules. We can define global modules in a module, and all these definitions deleted at the end of module execution. Because we have to execute the definition of a module, we can select definition, or load definition before we call the module. Also modules can be part of object's of type Group. A module can't call itself unless we use Call module_name. The standard call is by using only the name of module. So from a module we can call local modules or global, but we can't call parent module (if isn't global). In a group we can call anything like a module plus the modules of the groups. +We can use labels and line numbers (each number is just a label). After a line number we can place statement. Static subs/functions have same scope as the module scope. Here SomethingElse() is like Module as a program, with own scope. + + +MODULE alfa { + FUNCTION SomethingElse(A, ZZ) { + =A/ZZ ' WE CAN'T READ Z HERE + } + 000 READ X + 001 Z=10 + 005 GOSUB alfa + 010 COMPUTE(&X) + 020 PRINT @MUL10(X), SomethingElse(@MUL10(X), Z) + 030 IF X<20 THEN 10 + 040 GOSUB alfa + 050 END + 060 SUB COMPUTE(&A) + 070 A++ + 080 Z++ // SIDE EFFECT + 090 END SUB + 100 FUNCTION MUL10(A) + 110 =A*Z + 120 END FUNCTION +alfa: + 130 PRINT "-------------------------" + 140 RETURN +} +alfa 14 + + We can change a inner module at the calling of a module, see the example: We call inner Beta in two stages. At the second stage we change inner Theta with Theta2. This is the decoration of Beta with Theta as Theta2. This is a temporary decoration because Beta after execution erase any new identifier including Theta. So each time we call Beta, statement Module Theta make this module unless a decoration stop it. ====English Vocabulary==== -Module Beta { +Module Beta { Module Theta (x){ Print "This is Theta, we get x=";x } diff --git a/Lang/M2000-Interpreter/ADFGVX-cipher b/Lang/M2000-Interpreter/ADFGVX-cipher new file mode 120000 index 0000000000..58053e0f2d --- /dev/null +++ b/Lang/M2000-Interpreter/ADFGVX-cipher @@ -0,0 +1 @@ +../../Task/ADFGVX-cipher/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/Apply-a-digital-filter-direct-form-II-transposed- b/Lang/M2000-Interpreter/Apply-a-digital-filter-direct-form-II-transposed- new file mode 120000 index 0000000000..0994290aa3 --- /dev/null +++ b/Lang/M2000-Interpreter/Apply-a-digital-filter-direct-form-II-transposed- @@ -0,0 +1 @@ +../../Task/Apply-a-digital-filter-direct-form-II-transposed-/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/Cartesian-product-of-two-or-more-lists b/Lang/M2000-Interpreter/Cartesian-product-of-two-or-more-lists new file mode 120000 index 0000000000..afa95add18 --- /dev/null +++ b/Lang/M2000-Interpreter/Cartesian-product-of-two-or-more-lists @@ -0,0 +1 @@ +../../Task/Cartesian-product-of-two-or-more-lists/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/Compare-length-of-two-strings b/Lang/M2000-Interpreter/Compare-length-of-two-strings new file mode 120000 index 0000000000..1726357b73 --- /dev/null +++ b/Lang/M2000-Interpreter/Compare-length-of-two-strings @@ -0,0 +1 @@ +../../Task/Compare-length-of-two-strings/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/File-extension-is-in-extensions-list b/Lang/M2000-Interpreter/File-extension-is-in-extensions-list new file mode 120000 index 0000000000..6d12e57411 --- /dev/null +++ b/Lang/M2000-Interpreter/File-extension-is-in-extensions-list @@ -0,0 +1 @@ +../../Task/File-extension-is-in-extensions-list/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/Greatest-subsequential-sum b/Lang/M2000-Interpreter/Greatest-subsequential-sum new file mode 120000 index 0000000000..5470dd7511 --- /dev/null +++ b/Lang/M2000-Interpreter/Greatest-subsequential-sum @@ -0,0 +1 @@ +../../Task/Greatest-subsequential-sum/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/Power-set b/Lang/M2000-Interpreter/Power-set new file mode 120000 index 0000000000..c99b047826 --- /dev/null +++ b/Lang/M2000-Interpreter/Power-set @@ -0,0 +1 @@ +../../Task/Power-set/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/Simple-turtle-graphics b/Lang/M2000-Interpreter/Simple-turtle-graphics new file mode 120000 index 0000000000..8bb4a18e49 --- /dev/null +++ b/Lang/M2000-Interpreter/Simple-turtle-graphics @@ -0,0 +1 @@ +../../Task/Simple-turtle-graphics/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/Sorting-algorithms-Strand-sort b/Lang/M2000-Interpreter/Sorting-algorithms-Strand-sort new file mode 120000 index 0000000000..94b7b8369f --- /dev/null +++ b/Lang/M2000-Interpreter/Sorting-algorithms-Strand-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Strand-sort/M2000-Interpreter \ No newline at end of file diff --git a/Lang/M2000-Interpreter/Strip-a-set-of-characters-from-a-string b/Lang/M2000-Interpreter/Strip-a-set-of-characters-from-a-string new file mode 120000 index 0000000000..ca8f98d606 --- /dev/null +++ b/Lang/M2000-Interpreter/Strip-a-set-of-characters-from-a-string @@ -0,0 +1 @@ +../../Task/Strip-a-set-of-characters-from-a-string/M2000-Interpreter \ No newline at end of file diff --git a/Lang/MACRO-11/Run-length-encoding b/Lang/MACRO-11/Run-length-encoding new file mode 120000 index 0000000000..3f700314e0 --- /dev/null +++ b/Lang/MACRO-11/Run-length-encoding @@ -0,0 +1 @@ +../../Task/Run-length-encoding/MACRO-11 \ No newline at end of file diff --git a/Lang/MAD/Look-and-say-sequence b/Lang/MAD/Look-and-say-sequence new file mode 120000 index 0000000000..dbca6a6456 --- /dev/null +++ b/Lang/MAD/Look-and-say-sequence @@ -0,0 +1 @@ +../../Task/Look-and-say-sequence/MAD \ No newline at end of file diff --git a/Lang/MSX-Basic/Evaluate-binomial-coefficients b/Lang/MSX-Basic/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..806e2bfad2 --- /dev/null +++ b/Lang/MSX-Basic/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/MSX-Basic \ No newline at end of file diff --git a/Lang/MUMPS/00-LANG.txt b/Lang/MUMPS/00-LANG.txt index cfb6ac9800..491ec139a6 100644 --- a/Lang/MUMPS/00-LANG.txt +++ b/Lang/MUMPS/00-LANG.txt @@ -1,14 +1,21 @@ {{language -|untyped=yes}} +|untyped=yes +|gc +|parampass| +}} + {{language programming paradigm|procedural}} -

Visit the Google group comp.lang.mumps for discussions about this language.

+

Visit the Google group/ Usenet newsgroupcomp.lang.mumps for discussions about this language.

Visit [[wp:MUMPS|Wikipedia]] for a general description.

See http://71.174.62.16/Demo/AnnoStd for details about the language.

-

Standard MUMPS has one data types (strings) and some dialects (Cache, MSM) add a second data type (objects). A variable can be unsubscripted or not, and the subscripted variables form a -sparse n-tree. MUMPS doesn't have traditional arrays, but has an array syntax that manipulates trees as if they were arrays, using indexing to access nodes of the tree. You can create a tree that can have unlimited levels of branching, with keys and values associated with each node in the tree. Similarly, while the language doesn't have lists, you can mimic lists by creating strings with a consistent character (or string) as a delimiter separating the entries. -The Cache dialect also supports explicit List operations and data structures. +

Standard MUMPS has one data type (strings) and some dialects (Cache, MSM, IRIS) add a second data type (objects). A variable can be unsubscripted or not, and the subscripted variables form a +sparse n-tree, or associative arrays or sparse multidimensional hierarchical key-value pair with keys as strings and values as strings. + +MUMPS doesn't have traditional arrays, but has an array syntax that manipulates trees as if they were arrays, using indexing to access nodes of the tree. You can create a tree that can have unlimited levels of branching, with keys and values associated with each node in the tree. Similarly, while the language doesn't have lists, you can mimic lists by creating strings with a consistent character (or string) as a delimiter separating the entries. + +The Cache and IRIS dialects also support explicit List operations and data structures as values.

\ No newline at end of file diff --git a/Lang/Maple/Pythagoras-tree b/Lang/Maple/Pythagoras-tree new file mode 120000 index 0000000000..0342fe2180 --- /dev/null +++ b/Lang/Maple/Pythagoras-tree @@ -0,0 +1 @@ +../../Task/Pythagoras-tree/Maple \ No newline at end of file diff --git a/Lang/Mathematica/00-LANG.txt b/Lang/Mathematica/00-LANG.txt index 5daf1eef81..15e81dd703 100644 --- a/Lang/Mathematica/00-LANG.txt +++ b/Lang/Mathematica/00-LANG.txt @@ -11,4 +11,4 @@ It is used in many scientific, engineering, mathematical and computing fields, a [[Category:Mathematical programming languages]] ==Todo== -[[Reports:Tasks_not_implemented_in_Mathematica]] \ No newline at end of file +[[Tasks not implemented in Mathematica]] \ No newline at end of file diff --git a/Lang/Mathematica/15-puzzle-solver b/Lang/Mathematica/15-puzzle-solver new file mode 120000 index 0000000000..c802cd3973 --- /dev/null +++ b/Lang/Mathematica/15-puzzle-solver @@ -0,0 +1 @@ +../../Task/15-puzzle-solver/Mathematica \ No newline at end of file diff --git a/Lang/Mathematica/B-zier-curves-Intersections b/Lang/Mathematica/B-zier-curves-Intersections new file mode 120000 index 0000000000..85dc8fb4ae --- /dev/null +++ b/Lang/Mathematica/B-zier-curves-Intersections @@ -0,0 +1 @@ +../../Task/B-zier-curves-Intersections/Mathematica \ No newline at end of file diff --git a/Lang/Mathematica/Sisyphus-sequence b/Lang/Mathematica/Sisyphus-sequence new file mode 120000 index 0000000000..82e0aee9dd --- /dev/null +++ b/Lang/Mathematica/Sisyphus-sequence @@ -0,0 +1 @@ +../../Task/Sisyphus-sequence/Mathematica \ No newline at end of file diff --git a/Lang/Mathematica/Sphenic-numbers b/Lang/Mathematica/Sphenic-numbers new file mode 120000 index 0000000000..c276d09072 --- /dev/null +++ b/Lang/Mathematica/Sphenic-numbers @@ -0,0 +1 @@ +../../Task/Sphenic-numbers/Mathematica \ No newline at end of file diff --git a/Lang/Mathematica/Wagstaff-primes b/Lang/Mathematica/Wagstaff-primes new file mode 120000 index 0000000000..7e781a92a6 --- /dev/null +++ b/Lang/Mathematica/Wagstaff-primes @@ -0,0 +1 @@ +../../Task/Wagstaff-primes/Mathematica \ No newline at end of file diff --git a/Lang/Minimal-BASIC/Evaluate-binomial-coefficients b/Lang/Minimal-BASIC/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..6ad0769264 --- /dev/null +++ b/Lang/Minimal-BASIC/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/Minimal-BASIC \ No newline at end of file diff --git a/Lang/Miranda/Loops-Infinite b/Lang/Miranda/Loops-Infinite new file mode 120000 index 0000000000..8845df4b78 --- /dev/null +++ b/Lang/Miranda/Loops-Infinite @@ -0,0 +1 @@ +../../Task/Loops-Infinite/Miranda \ No newline at end of file diff --git a/Lang/Miranda/Run-length-encoding b/Lang/Miranda/Run-length-encoding new file mode 120000 index 0000000000..e0fd07015b --- /dev/null +++ b/Lang/Miranda/Run-length-encoding @@ -0,0 +1 @@ +../../Task/Run-length-encoding/Miranda \ No newline at end of file diff --git a/Lang/Modula-2/M-bius-function b/Lang/Modula-2/M-bius-function new file mode 120000 index 0000000000..e2d4a4a9b1 --- /dev/null +++ b/Lang/Modula-2/M-bius-function @@ -0,0 +1 @@ +../../Task/M-bius-function/Modula-2 \ No newline at end of file diff --git a/Lang/Modula-2/Magic-constant b/Lang/Modula-2/Magic-constant new file mode 120000 index 0000000000..d6cf44baf4 --- /dev/null +++ b/Lang/Modula-2/Magic-constant @@ -0,0 +1 @@ +../../Task/Magic-constant/Modula-2 \ No newline at end of file diff --git a/Lang/Modula-2/Map-range b/Lang/Modula-2/Map-range new file mode 120000 index 0000000000..d2da488e09 --- /dev/null +++ b/Lang/Modula-2/Map-range @@ -0,0 +1 @@ +../../Task/Map-range/Modula-2 \ No newline at end of file diff --git a/Lang/Modula-2/Ramer-Douglas-Peucker-line-simplification b/Lang/Modula-2/Ramer-Douglas-Peucker-line-simplification new file mode 120000 index 0000000000..ff583aca48 --- /dev/null +++ b/Lang/Modula-2/Ramer-Douglas-Peucker-line-simplification @@ -0,0 +1 @@ +../../Task/Ramer-Douglas-Peucker-line-simplification/Modula-2 \ No newline at end of file diff --git a/Lang/Nascom-BASIC/Levenshtein-distance b/Lang/Nascom-BASIC/Levenshtein-distance new file mode 120000 index 0000000000..c821e59923 --- /dev/null +++ b/Lang/Nascom-BASIC/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/Nascom-BASIC \ No newline at end of file diff --git a/Lang/Nu/CSV-data-manipulation b/Lang/Nu/CSV-data-manipulation new file mode 120000 index 0000000000..212f9d037c --- /dev/null +++ b/Lang/Nu/CSV-data-manipulation @@ -0,0 +1 @@ +../../Task/CSV-data-manipulation/Nu \ No newline at end of file diff --git a/Lang/Nu/Department-numbers b/Lang/Nu/Department-numbers new file mode 120000 index 0000000000..bb0cfc31a5 --- /dev/null +++ b/Lang/Nu/Department-numbers @@ -0,0 +1 @@ +../../Task/Department-numbers/Nu \ No newline at end of file diff --git a/Lang/Nu/Determine-if-a-string-has-all-the-same-characters b/Lang/Nu/Determine-if-a-string-has-all-the-same-characters new file mode 120000 index 0000000000..1b0a4160eb --- /dev/null +++ b/Lang/Nu/Determine-if-a-string-has-all-the-same-characters @@ -0,0 +1 @@ +../../Task/Determine-if-a-string-has-all-the-same-characters/Nu \ No newline at end of file diff --git a/Lang/Nu/File-extension-is-in-extensions-list b/Lang/Nu/File-extension-is-in-extensions-list new file mode 120000 index 0000000000..ee608b6863 --- /dev/null +++ b/Lang/Nu/File-extension-is-in-extensions-list @@ -0,0 +1 @@ +../../Task/File-extension-is-in-extensions-list/Nu \ No newline at end of file diff --git a/Lang/Nu/File-size-distribution b/Lang/Nu/File-size-distribution new file mode 120000 index 0000000000..2ee98ba338 --- /dev/null +++ b/Lang/Nu/File-size-distribution @@ -0,0 +1 @@ +../../Task/File-size-distribution/Nu \ No newline at end of file diff --git a/Lang/Nu/I-before-E-except-after-C b/Lang/Nu/I-before-E-except-after-C new file mode 120000 index 0000000000..3f6ace8c86 --- /dev/null +++ b/Lang/Nu/I-before-E-except-after-C @@ -0,0 +1 @@ +../../Task/I-before-E-except-after-C/Nu \ No newline at end of file diff --git a/Lang/Nu/Word-frequency b/Lang/Nu/Word-frequency new file mode 120000 index 0000000000..b6ff2592c2 --- /dev/null +++ b/Lang/Nu/Word-frequency @@ -0,0 +1 @@ +../../Task/Word-frequency/Nu \ No newline at end of file diff --git a/Lang/OCaml/Anti-primes b/Lang/OCaml/Anti-primes new file mode 120000 index 0000000000..5c78fd8505 --- /dev/null +++ b/Lang/OCaml/Anti-primes @@ -0,0 +1 @@ +../../Task/Anti-primes/OCaml \ No newline at end of file diff --git a/Lang/OCaml/Attractive-numbers b/Lang/OCaml/Attractive-numbers new file mode 120000 index 0000000000..7813955dbc --- /dev/null +++ b/Lang/OCaml/Attractive-numbers @@ -0,0 +1 @@ +../../Task/Attractive-numbers/OCaml \ No newline at end of file diff --git a/Lang/OCaml/Cuban-primes b/Lang/OCaml/Cuban-primes new file mode 120000 index 0000000000..d69918cc8d --- /dev/null +++ b/Lang/OCaml/Cuban-primes @@ -0,0 +1 @@ +../../Task/Cuban-primes/OCaml \ No newline at end of file diff --git a/Lang/OOC/00-LANG.txt b/Lang/OOC/00-LANG.txt index 6ab39964dc..65c190709f 100644 --- a/Lang/OOC/00-LANG.txt +++ b/Lang/OOC/00-LANG.txt @@ -1,2 +1,2 @@ {{stub}}{{language -|site=http://ooc-lang.org}} \ No newline at end of file +|site=https://ooc-lang.github.io/}} \ No newline at end of file diff --git a/Lang/OPL/00-LANG.txt b/Lang/OPL/00-LANG.txt index 8357c2d27a..5d7f1fba8f 100644 --- a/Lang/OPL/00-LANG.txt +++ b/Lang/OPL/00-LANG.txt @@ -1,3 +1,11 @@ {{stub}} {{language -|site=http://opl-dev.sourceforge.net/}} \ No newline at end of file +|site=http://opl-dev.sourceforge.net/}} + +'''OPL (Open Programming Language'''; formerly '''Organiser Programming Language)''' is a high-level programming language designed primarily for use on mobile devices, particularly those running the Psion Series 3 and Series 5 operating systems. Developed in the early 1990s, '''OPL''' was created to provide a simple yet powerful environment for application development on handheld devices, allowing users to create software that could leverage the unique features of these portable platforms. + +OPL is known for its ease of use, making it accessible to both novice and experienced programmers. The language features a syntax that is similar to [[BASIC]], which helps in rapid application development. It supports structured programming concepts, including variables, control structures, and functions, enabling developers to write clear and maintainable code. + +One of the key strengths of OPL is its ability to interact seamlessly with the underlying operating system, allowing developers to access device-specific features such as file management, user interface elements, and hardware capabilities. This makes OPL particularly suitable for creating productivity applications, games, and utilities tailored for mobile users. + +Despite its niche status, OPL has garnered a dedicated community of enthusiasts and developers who continue to explore its capabilities and create innovative applications. As mobile computing continues to evolve, OPL remains a notable example of early efforts to bring programming to handheld devices, showcasing the potential of portable technology in software development. \ No newline at end of file diff --git a/Lang/OPL/100-doors b/Lang/OPL/100-doors new file mode 120000 index 0000000000..a3b7e045e6 --- /dev/null +++ b/Lang/OPL/100-doors @@ -0,0 +1 @@ +../../Task/100-doors/OPL \ No newline at end of file diff --git a/Lang/OPL/Arithmetic-Integer b/Lang/OPL/Arithmetic-Integer new file mode 120000 index 0000000000..dfcb743d43 --- /dev/null +++ b/Lang/OPL/Arithmetic-Integer @@ -0,0 +1 @@ +../../Task/Arithmetic-Integer/OPL \ No newline at end of file diff --git a/Lang/OPL/Arrays b/Lang/OPL/Arrays new file mode 120000 index 0000000000..f57347887c --- /dev/null +++ b/Lang/OPL/Arrays @@ -0,0 +1 @@ +../../Task/Arrays/OPL \ No newline at end of file diff --git a/Lang/OPL/Character-codes b/Lang/OPL/Character-codes new file mode 120000 index 0000000000..2dac3156b8 --- /dev/null +++ b/Lang/OPL/Character-codes @@ -0,0 +1 @@ +../../Task/Character-codes/OPL \ No newline at end of file diff --git a/Lang/OPL/Comments b/Lang/OPL/Comments new file mode 120000 index 0000000000..8aec78d8aa --- /dev/null +++ b/Lang/OPL/Comments @@ -0,0 +1 @@ +../../Task/Comments/OPL \ No newline at end of file diff --git a/Lang/OPL/Compare-length-of-two-strings b/Lang/OPL/Compare-length-of-two-strings new file mode 120000 index 0000000000..c36f1e31fc --- /dev/null +++ b/Lang/OPL/Compare-length-of-two-strings @@ -0,0 +1 @@ +../../Task/Compare-length-of-two-strings/OPL \ No newline at end of file diff --git a/Lang/OPL/Copy-a-string b/Lang/OPL/Copy-a-string new file mode 120000 index 0000000000..76609905e5 --- /dev/null +++ b/Lang/OPL/Copy-a-string @@ -0,0 +1 @@ +../../Task/Copy-a-string/OPL \ No newline at end of file diff --git a/Lang/OPL/Draw-a-clock b/Lang/OPL/Draw-a-clock new file mode 120000 index 0000000000..438c8aadf3 --- /dev/null +++ b/Lang/OPL/Draw-a-clock @@ -0,0 +1 @@ +../../Task/Draw-a-clock/OPL \ No newline at end of file diff --git a/Lang/OPL/Draw-a-pixel b/Lang/OPL/Draw-a-pixel new file mode 120000 index 0000000000..d5c6ecea21 --- /dev/null +++ b/Lang/OPL/Draw-a-pixel @@ -0,0 +1 @@ +../../Task/Draw-a-pixel/OPL \ No newline at end of file diff --git a/Lang/OPL/Hello-world-Text b/Lang/OPL/Hello-world-Text new file mode 120000 index 0000000000..a870057a16 --- /dev/null +++ b/Lang/OPL/Hello-world-Text @@ -0,0 +1 @@ +../../Task/Hello-world-Text/OPL \ No newline at end of file diff --git a/Lang/OPL/Program-termination b/Lang/OPL/Program-termination new file mode 120000 index 0000000000..8287761646 --- /dev/null +++ b/Lang/OPL/Program-termination @@ -0,0 +1 @@ +../../Task/Program-termination/OPL \ No newline at end of file diff --git a/Lang/OPL/String-prepend b/Lang/OPL/String-prepend new file mode 120000 index 0000000000..78cb69646e --- /dev/null +++ b/Lang/OPL/String-prepend @@ -0,0 +1 @@ +../../Task/String-prepend/OPL \ No newline at end of file diff --git a/Lang/OPL/User-input-Text b/Lang/OPL/User-input-Text new file mode 120000 index 0000000000..ad39694040 --- /dev/null +++ b/Lang/OPL/User-input-Text @@ -0,0 +1 @@ +../../Task/User-input-Text/OPL \ No newline at end of file diff --git a/Lang/Objeck/Copy-stdin-to-stdout b/Lang/Objeck/Copy-stdin-to-stdout new file mode 120000 index 0000000000..b358bbac43 --- /dev/null +++ b/Lang/Objeck/Copy-stdin-to-stdout @@ -0,0 +1 @@ +../../Task/Copy-stdin-to-stdout/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Distributed-programming b/Lang/Objeck/Distributed-programming new file mode 120000 index 0000000000..728f38ee28 --- /dev/null +++ b/Lang/Objeck/Distributed-programming @@ -0,0 +1 @@ +../../Task/Distributed-programming/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Floyds-triangle b/Lang/Objeck/Floyds-triangle new file mode 120000 index 0000000000..743553b677 --- /dev/null +++ b/Lang/Objeck/Floyds-triangle @@ -0,0 +1 @@ +../../Task/Floyds-triangle/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Generate-lower-case-ASCII-alphabet b/Lang/Objeck/Generate-lower-case-ASCII-alphabet new file mode 120000 index 0000000000..92f0212a12 --- /dev/null +++ b/Lang/Objeck/Generate-lower-case-ASCII-alphabet @@ -0,0 +1 @@ +../../Task/Generate-lower-case-ASCII-alphabet/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Hello-world-Standard-error b/Lang/Objeck/Hello-world-Standard-error new file mode 120000 index 0000000000..49d3f16aa6 --- /dev/null +++ b/Lang/Objeck/Hello-world-Standard-error @@ -0,0 +1 @@ +../../Task/Hello-world-Standard-error/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Knuth-shuffle b/Lang/Objeck/Knuth-shuffle new file mode 120000 index 0000000000..a7bb43880d --- /dev/null +++ b/Lang/Objeck/Knuth-shuffle @@ -0,0 +1 @@ +../../Task/Knuth-shuffle/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Mad-Libs b/Lang/Objeck/Mad-Libs new file mode 120000 index 0000000000..39f19ea059 --- /dev/null +++ b/Lang/Objeck/Mad-Libs @@ -0,0 +1 @@ +../../Task/Mad-Libs/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Multiplication-tables b/Lang/Objeck/Multiplication-tables new file mode 120000 index 0000000000..3bad27bce2 --- /dev/null +++ b/Lang/Objeck/Multiplication-tables @@ -0,0 +1 @@ +../../Task/Multiplication-tables/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Roman-numerals-Decode b/Lang/Objeck/Roman-numerals-Decode new file mode 120000 index 0000000000..bd8b56a721 --- /dev/null +++ b/Lang/Objeck/Roman-numerals-Decode @@ -0,0 +1 @@ +../../Task/Roman-numerals-Decode/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Rosetta-Code-Find-unimplemented-tasks b/Lang/Objeck/Rosetta-Code-Find-unimplemented-tasks new file mode 120000 index 0000000000..7e77326aa1 --- /dev/null +++ b/Lang/Objeck/Rosetta-Code-Find-unimplemented-tasks @@ -0,0 +1 @@ +../../Task/Rosetta-Code-Find-unimplemented-tasks/Objeck \ No newline at end of file diff --git a/Lang/Objeck/Strip-a-set-of-characters-from-a-string b/Lang/Objeck/Strip-a-set-of-characters-from-a-string new file mode 120000 index 0000000000..f651f9d55d --- /dev/null +++ b/Lang/Objeck/Strip-a-set-of-characters-from-a-string @@ -0,0 +1 @@ +../../Task/Strip-a-set-of-characters-from-a-string/Objeck \ No newline at end of file diff --git a/Lang/Odin/Euler-method b/Lang/Odin/Euler-method new file mode 120000 index 0000000000..2085f38551 --- /dev/null +++ b/Lang/Odin/Euler-method @@ -0,0 +1 @@ +../../Task/Euler-method/Odin \ No newline at end of file diff --git a/Lang/Odin/Execute-Brain- b/Lang/Odin/Execute-Brain- new file mode 120000 index 0000000000..748dbb9c99 --- /dev/null +++ b/Lang/Odin/Execute-Brain- @@ -0,0 +1 @@ +../../Task/Execute-Brain-/Odin \ No newline at end of file diff --git a/Lang/Odin/Fractran b/Lang/Odin/Fractran new file mode 120000 index 0000000000..5bd1840a6a --- /dev/null +++ b/Lang/Odin/Fractran @@ -0,0 +1 @@ +../../Task/Fractran/Odin \ No newline at end of file diff --git a/Lang/Odin/Hailstone-sequence b/Lang/Odin/Hailstone-sequence new file mode 120000 index 0000000000..678ea867f0 --- /dev/null +++ b/Lang/Odin/Hailstone-sequence @@ -0,0 +1 @@ +../../Task/Hailstone-sequence/Odin \ No newline at end of file diff --git a/Lang/Odin/Hello-world-Graphical b/Lang/Odin/Hello-world-Graphical new file mode 120000 index 0000000000..00108512b1 --- /dev/null +++ b/Lang/Odin/Hello-world-Graphical @@ -0,0 +1 @@ +../../Task/Hello-world-Graphical/Odin \ No newline at end of file diff --git a/Lang/Odin/Primality-by-trial-division b/Lang/Odin/Primality-by-trial-division new file mode 120000 index 0000000000..8e356363dd --- /dev/null +++ b/Lang/Odin/Primality-by-trial-division @@ -0,0 +1 @@ +../../Task/Primality-by-trial-division/Odin \ No newline at end of file diff --git a/Lang/Odin/Runge-Kutta-method b/Lang/Odin/Runge-Kutta-method new file mode 120000 index 0000000000..1b9162c995 --- /dev/null +++ b/Lang/Odin/Runge-Kutta-method @@ -0,0 +1 @@ +../../Task/Runge-Kutta-method/Odin \ No newline at end of file diff --git a/Lang/Odin/Strip-a-set-of-characters-from-a-string b/Lang/Odin/Strip-a-set-of-characters-from-a-string new file mode 120000 index 0000000000..b76ef81d13 --- /dev/null +++ b/Lang/Odin/Strip-a-set-of-characters-from-a-string @@ -0,0 +1 @@ +../../Task/Strip-a-set-of-characters-from-a-string/Odin \ No newline at end of file diff --git a/Lang/Odin/Unicode-variable-names b/Lang/Odin/Unicode-variable-names new file mode 120000 index 0000000000..f070da9637 --- /dev/null +++ b/Lang/Odin/Unicode-variable-names @@ -0,0 +1 @@ +../../Task/Unicode-variable-names/Odin \ No newline at end of file diff --git a/Lang/Odin/Write-entire-file b/Lang/Odin/Write-entire-file new file mode 120000 index 0000000000..53b4243bae --- /dev/null +++ b/Lang/Odin/Write-entire-file @@ -0,0 +1 @@ +../../Task/Write-entire-file/Odin \ No newline at end of file diff --git a/Lang/Ol/Runge-Kutta-method b/Lang/Ol/Runge-Kutta-method new file mode 120000 index 0000000000..55f8d1bf18 --- /dev/null +++ b/Lang/Ol/Runge-Kutta-method @@ -0,0 +1 @@ +../../Task/Runge-Kutta-method/Ol \ No newline at end of file diff --git a/Lang/OxygenBasic/Evaluate-binomial-coefficients b/Lang/OxygenBasic/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..2fc6117dc9 --- /dev/null +++ b/Lang/OxygenBasic/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/OxygenBasic \ No newline at end of file diff --git a/Lang/PARI-GP/Attractive-numbers b/Lang/PARI-GP/Attractive-numbers new file mode 120000 index 0000000000..9c5ab01706 --- /dev/null +++ b/Lang/PARI-GP/Attractive-numbers @@ -0,0 +1 @@ +../../Task/Attractive-numbers/PARI-GP \ No newline at end of file diff --git a/Lang/PARI-GP/Disarium-numbers b/Lang/PARI-GP/Disarium-numbers new file mode 120000 index 0000000000..e21e95674b --- /dev/null +++ b/Lang/PARI-GP/Disarium-numbers @@ -0,0 +1 @@ +../../Task/Disarium-numbers/PARI-GP \ No newline at end of file diff --git a/Lang/PARI-GP/Prime-numbers-whose-neighboring-pairs-are-tetraprimes b/Lang/PARI-GP/Prime-numbers-whose-neighboring-pairs-are-tetraprimes new file mode 120000 index 0000000000..497a956889 --- /dev/null +++ b/Lang/PARI-GP/Prime-numbers-whose-neighboring-pairs-are-tetraprimes @@ -0,0 +1 @@ +../../Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/PARI-GP \ No newline at end of file diff --git a/Lang/PHP/M-bius-function b/Lang/PHP/M-bius-function new file mode 120000 index 0000000000..6f4e3a47bb --- /dev/null +++ b/Lang/PHP/M-bius-function @@ -0,0 +1 @@ +../../Task/M-bius-function/PHP \ No newline at end of file diff --git a/Lang/PHP/Magic-constant b/Lang/PHP/Magic-constant new file mode 120000 index 0000000000..b67d20fb19 --- /dev/null +++ b/Lang/PHP/Magic-constant @@ -0,0 +1 @@ +../../Task/Magic-constant/PHP \ No newline at end of file diff --git a/Lang/PHP/Map-range b/Lang/PHP/Map-range new file mode 120000 index 0000000000..07d5696e85 --- /dev/null +++ b/Lang/PHP/Map-range @@ -0,0 +1 @@ +../../Task/Map-range/PHP \ No newline at end of file diff --git a/Lang/PL-I-80/Additive-primes b/Lang/PL-I-80/Additive-primes new file mode 120000 index 0000000000..a065cd3d8e --- /dev/null +++ b/Lang/PL-I-80/Additive-primes @@ -0,0 +1 @@ +../../Task/Additive-primes/PL-I-80 \ No newline at end of file diff --git a/Lang/Pascal/Date-manipulation b/Lang/Pascal/Date-manipulation new file mode 120000 index 0000000000..9edece533b --- /dev/null +++ b/Lang/Pascal/Date-manipulation @@ -0,0 +1 @@ +../../Task/Date-manipulation/Pascal \ No newline at end of file diff --git a/Lang/Pascal/FizzBuzz b/Lang/Pascal/FizzBuzz deleted file mode 120000 index 786dae3647..0000000000 --- a/Lang/Pascal/FizzBuzz +++ /dev/null @@ -1 +0,0 @@ -../../Task/FizzBuzz/Pascal \ No newline at end of file diff --git a/Lang/Pascal/Levenshtein-distance b/Lang/Pascal/Levenshtein-distance deleted file mode 120000 index aa9f13dc0f..0000000000 --- a/Lang/Pascal/Levenshtein-distance +++ /dev/null @@ -1 +0,0 @@ -../../Task/Levenshtein-distance/Pascal \ No newline at end of file diff --git a/Lang/Pascal/Map-range b/Lang/Pascal/Map-range deleted file mode 120000 index 71c05c40ec..0000000000 --- a/Lang/Pascal/Map-range +++ /dev/null @@ -1 +0,0 @@ -../../Task/Map-range/Pascal \ No newline at end of file diff --git a/Lang/PascalABC.NET/Additive-primes b/Lang/PascalABC.NET/Additive-primes new file mode 120000 index 0000000000..0022732e2e --- /dev/null +++ b/Lang/PascalABC.NET/Additive-primes @@ -0,0 +1 @@ +../../Task/Additive-primes/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Amicable-pairs b/Lang/PascalABC.NET/Amicable-pairs new file mode 120000 index 0000000000..e8f5a09925 --- /dev/null +++ b/Lang/PascalABC.NET/Amicable-pairs @@ -0,0 +1 @@ +../../Task/Amicable-pairs/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Pancake-numbers b/Lang/PascalABC.NET/Pancake-numbers new file mode 120000 index 0000000000..b4faf1b68d --- /dev/null +++ b/Lang/PascalABC.NET/Pancake-numbers @@ -0,0 +1 @@ +../../Task/Pancake-numbers/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Pangram-checker b/Lang/PascalABC.NET/Pangram-checker new file mode 120000 index 0000000000..114e870600 --- /dev/null +++ b/Lang/PascalABC.NET/Pangram-checker @@ -0,0 +1 @@ +../../Task/Pangram-checker/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Paraffins b/Lang/PascalABC.NET/Paraffins new file mode 120000 index 0000000000..bafd6e0939 --- /dev/null +++ b/Lang/PascalABC.NET/Paraffins @@ -0,0 +1 @@ +../../Task/Paraffins/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Parallel-calculations b/Lang/PascalABC.NET/Parallel-calculations new file mode 120000 index 0000000000..e88e92c1df --- /dev/null +++ b/Lang/PascalABC.NET/Parallel-calculations @@ -0,0 +1 @@ +../../Task/Parallel-calculations/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Parsing-RPN-calculator-algorithm b/Lang/PascalABC.NET/Parsing-RPN-calculator-algorithm new file mode 120000 index 0000000000..c4ae7949cd --- /dev/null +++ b/Lang/PascalABC.NET/Parsing-RPN-calculator-algorithm @@ -0,0 +1 @@ +../../Task/Parsing-RPN-calculator-algorithm/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Partition-an-integer-x-into-n-primes b/Lang/PascalABC.NET/Partition-an-integer-x-into-n-primes new file mode 120000 index 0000000000..eb7a5e97f7 --- /dev/null +++ b/Lang/PascalABC.NET/Partition-an-integer-x-into-n-primes @@ -0,0 +1 @@ +../../Task/Partition-an-integer-x-into-n-primes/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Pascal-matrix-generation b/Lang/PascalABC.NET/Pascal-matrix-generation new file mode 120000 index 0000000000..c8097eca88 --- /dev/null +++ b/Lang/PascalABC.NET/Pascal-matrix-generation @@ -0,0 +1 @@ +../../Task/Pascal-matrix-generation/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Pascals-triangle-Puzzle b/Lang/PascalABC.NET/Pascals-triangle-Puzzle new file mode 120000 index 0000000000..8106a5db3a --- /dev/null +++ b/Lang/PascalABC.NET/Pascals-triangle-Puzzle @@ -0,0 +1 @@ +../../Task/Pascals-triangle-Puzzle/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Pathological-floating-point-problems b/Lang/PascalABC.NET/Pathological-floating-point-problems new file mode 120000 index 0000000000..7eaa34e4a8 --- /dev/null +++ b/Lang/PascalABC.NET/Pathological-floating-point-problems @@ -0,0 +1 @@ +../../Task/Pathological-floating-point-problems/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Pells-equation b/Lang/PascalABC.NET/Pells-equation new file mode 120000 index 0000000000..1729f4ebb8 --- /dev/null +++ b/Lang/PascalABC.NET/Pells-equation @@ -0,0 +1 @@ +../../Task/Pells-equation/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Perfect-shuffle b/Lang/PascalABC.NET/Perfect-shuffle new file mode 120000 index 0000000000..5ea5d5cf28 --- /dev/null +++ b/Lang/PascalABC.NET/Perfect-shuffle @@ -0,0 +1 @@ +../../Task/Perfect-shuffle/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Perfect-totient-numbers b/Lang/PascalABC.NET/Perfect-totient-numbers new file mode 120000 index 0000000000..8aae312612 --- /dev/null +++ b/Lang/PascalABC.NET/Perfect-totient-numbers @@ -0,0 +1 @@ +../../Task/Perfect-totient-numbers/PascalABC.NET \ No newline at end of file diff --git a/Lang/PascalABC.NET/Permutation-test b/Lang/PascalABC.NET/Permutation-test new file mode 120000 index 0000000000..38efc59733 --- /dev/null +++ b/Lang/PascalABC.NET/Permutation-test @@ -0,0 +1 @@ +../../Task/Permutation-test/PascalABC.NET \ No newline at end of file diff --git a/Lang/Perl/Execute-Computer-Zero b/Lang/Perl/Execute-Computer-Zero new file mode 120000 index 0000000000..f5f02da865 --- /dev/null +++ b/Lang/Perl/Execute-Computer-Zero @@ -0,0 +1 @@ +../../Task/Execute-Computer-Zero/Perl \ No newline at end of file diff --git a/Lang/Prolog/Evaluate-binomial-coefficients b/Lang/Prolog/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..15602e690b --- /dev/null +++ b/Lang/Prolog/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/Prolog \ No newline at end of file diff --git a/Lang/Python/Im-a-software-engineer-get-me-out-of-here b/Lang/Python/Im-a-software-engineer-get-me-out-of-here new file mode 120000 index 0000000000..d238ff00d2 --- /dev/null +++ b/Lang/Python/Im-a-software-engineer-get-me-out-of-here @@ -0,0 +1 @@ +../../Task/Im-a-software-engineer-get-me-out-of-here/Python \ No newline at end of file diff --git a/Lang/Python/Prime-numbers-whose-neighboring-pairs-are-tetraprimes b/Lang/Python/Prime-numbers-whose-neighboring-pairs-are-tetraprimes new file mode 120000 index 0000000000..9997b73880 --- /dev/null +++ b/Lang/Python/Prime-numbers-whose-neighboring-pairs-are-tetraprimes @@ -0,0 +1 @@ +../../Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/Python \ No newline at end of file diff --git a/Lang/Python/Square-form-factorization b/Lang/Python/Square-form-factorization new file mode 120000 index 0000000000..38da301a59 --- /dev/null +++ b/Lang/Python/Square-form-factorization @@ -0,0 +1 @@ +../../Task/Square-form-factorization/Python \ No newline at end of file diff --git a/Lang/Python/Wasteful-equidigital-and-frugal-numbers b/Lang/Python/Wasteful-equidigital-and-frugal-numbers new file mode 120000 index 0000000000..c89de12312 --- /dev/null +++ b/Lang/Python/Wasteful-equidigital-and-frugal-numbers @@ -0,0 +1 @@ +../../Task/Wasteful-equidigital-and-frugal-numbers/Python \ No newline at end of file diff --git a/Lang/Q/Euler-method b/Lang/Q/Euler-method new file mode 120000 index 0000000000..093ad80e13 --- /dev/null +++ b/Lang/Q/Euler-method @@ -0,0 +1 @@ +../../Task/Euler-method/Q \ No newline at end of file diff --git a/Lang/QBasic/Evaluate-binomial-coefficients b/Lang/QBasic/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..86b00c5e75 --- /dev/null +++ b/Lang/QBasic/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/QBasic \ No newline at end of file diff --git a/Lang/QBasic/Map-range b/Lang/QBasic/Map-range new file mode 120000 index 0000000000..be9705365d --- /dev/null +++ b/Lang/QBasic/Map-range @@ -0,0 +1 @@ +../../Task/Map-range/QBasic \ No newline at end of file diff --git a/Lang/Quackery/00-LANG.txt b/Lang/Quackery/00-LANG.txt index c6437e7156..7eab14d4c5 100644 --- a/Lang/Quackery/00-LANG.txt +++ b/Lang/Quackery/00-LANG.txt @@ -29,4 +29,26 @@ Conceptually, the Quackery engine is a stack based processor which does not have Quackery is not intended to be a super-fast enterprise-level language; it is intended as an exploration of a novel architecture, and a fun programming project straight out of a textbook. (The textbook is included in the download.) -Why not try your hand at one of the [[Tasks not implemented in Quackery]]. \ No newline at end of file +Why not try your hand at one of the [[Tasks not implemented in Quackery]]. + +== Selected Quackery Examples == + +Rosetta Code has hundreds of Quackery examples. Here’s a curated set that showcases some of Quackery's strengths: + +* [[99 bottles of beer#Quackery|99 bottles of beer]] Shows simple, readable control flow and output. +* [[Gosper's hack#Quackery|Gosper's hack]] A nifty one-liner. +* [[Temperature conversion#Quackery|Temperature conversion]] Co-operative brevity. +* [[Balanced brackets#Quackery|Balanced brackets]] Demonstrates natural stack use for classic problems. +* [[Loops/Increment loop index within loop body#Quackery|Increment loop index within loop body]] You want a loop that's indexed ''and'' indefinite? Here's how. +* [[Quine#Quackery|Quine]] Illustrates code-as-data and quotation handling. +* [[Bacon cipher#Quackery|Bacon cipher]] Highlights clear text manipulation with minimal code. +* [[Permutations#Quackery|Permutations]] Uses recursion and stack shuffling expressively. +* [[Sorting algorithms/Insertion sort#Quackery|Insertion sort]] Demonstrates some built-in higher-order functions. +* [[Higher-order functions#Quackery|Higher-order functions]] Defining and using fold, map, and filter. +* [[Conway's Game of Life#Quackery|Conway's Game of Life]] Handles structured simulation with clarity. +* [[Execute Brain****#Quackery|Brainf*** interpreter]] Demonstrates interpreter-building and extensibility. +* [[Dinesman's multiple-dwelling problem#Quackery|Dinesman's multiple-dwelling problem]] Crafting a Domain Specific Language. + +== The Task that Nearly Broke the Author == + +* [[Zeckendorf arithmetic#Quackery|Zeckendorf arithmetic]] Forget everything you thought you knew about arithmetic… \ No newline at end of file diff --git a/Lang/Quackery/Dice-game-probabilities b/Lang/Quackery/Dice-game-probabilities new file mode 120000 index 0000000000..87d28dc799 --- /dev/null +++ b/Lang/Quackery/Dice-game-probabilities @@ -0,0 +1 @@ +../../Task/Dice-game-probabilities/Quackery \ No newline at end of file diff --git a/Lang/Quackery/Sum-of-elements-below-main-diagonal-of-matrix b/Lang/Quackery/Sum-of-elements-below-main-diagonal-of-matrix new file mode 120000 index 0000000000..1f9736ed88 --- /dev/null +++ b/Lang/Quackery/Sum-of-elements-below-main-diagonal-of-matrix @@ -0,0 +1 @@ +../../Task/Sum-of-elements-below-main-diagonal-of-matrix/Quackery \ No newline at end of file diff --git a/Lang/Quackery/Two-bullet-roulette b/Lang/Quackery/Two-bullet-roulette new file mode 120000 index 0000000000..24f00326c1 --- /dev/null +++ b/Lang/Quackery/Two-bullet-roulette @@ -0,0 +1 @@ +../../Task/Two-bullet-roulette/Quackery \ No newline at end of file diff --git a/Lang/R/Camel-case-and-snake-case b/Lang/R/Camel-case-and-snake-case new file mode 120000 index 0000000000..e76dd2d66a --- /dev/null +++ b/Lang/R/Camel-case-and-snake-case @@ -0,0 +1 @@ +../../Task/Camel-case-and-snake-case/R \ No newline at end of file diff --git a/Lang/R/Determine-sentence-type b/Lang/R/Determine-sentence-type new file mode 120000 index 0000000000..b5e3ac4763 --- /dev/null +++ b/Lang/R/Determine-sentence-type @@ -0,0 +1 @@ +../../Task/Determine-sentence-type/R \ No newline at end of file diff --git a/Lang/R/Disarium-numbers b/Lang/R/Disarium-numbers new file mode 120000 index 0000000000..233dce846c --- /dev/null +++ b/Lang/R/Disarium-numbers @@ -0,0 +1 @@ +../../Task/Disarium-numbers/R \ No newline at end of file diff --git a/Lang/R/Display-a-linear-combination b/Lang/R/Display-a-linear-combination new file mode 120000 index 0000000000..c292ce3aec --- /dev/null +++ b/Lang/R/Display-a-linear-combination @@ -0,0 +1 @@ +../../Task/Display-a-linear-combination/R \ No newline at end of file diff --git a/Lang/R/Draw-a-cuboid b/Lang/R/Draw-a-cuboid new file mode 120000 index 0000000000..b0d15ca88e --- /dev/null +++ b/Lang/R/Draw-a-cuboid @@ -0,0 +1 @@ +../../Task/Draw-a-cuboid/R \ No newline at end of file diff --git a/Lang/R/Dutch-national-flag-problem b/Lang/R/Dutch-national-flag-problem new file mode 120000 index 0000000000..422342365f --- /dev/null +++ b/Lang/R/Dutch-national-flag-problem @@ -0,0 +1 @@ +../../Task/Dutch-national-flag-problem/R \ No newline at end of file diff --git a/Lang/R/Factorions b/Lang/R/Factorions new file mode 120000 index 0000000000..351fcd0d06 --- /dev/null +++ b/Lang/R/Factorions @@ -0,0 +1 @@ +../../Task/Factorions/R \ No newline at end of file diff --git a/Lang/R/Find-palindromic-numbers-in-both-binary-and-ternary-bases b/Lang/R/Find-palindromic-numbers-in-both-binary-and-ternary-bases new file mode 120000 index 0000000000..1adf6989fe --- /dev/null +++ b/Lang/R/Find-palindromic-numbers-in-both-binary-and-ternary-bases @@ -0,0 +1 @@ +../../Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/R \ No newline at end of file diff --git a/Lang/R/Halt-and-catch-fire b/Lang/R/Halt-and-catch-fire new file mode 120000 index 0000000000..f754df332d --- /dev/null +++ b/Lang/R/Halt-and-catch-fire @@ -0,0 +1 @@ +../../Task/Halt-and-catch-fire/R \ No newline at end of file diff --git a/Lang/R/Hex-words b/Lang/R/Hex-words new file mode 120000 index 0000000000..f38acbfb8b --- /dev/null +++ b/Lang/R/Hex-words @@ -0,0 +1 @@ +../../Task/Hex-words/R \ No newline at end of file diff --git a/Lang/R/Kernighans-large-earthquake-problem b/Lang/R/Kernighans-large-earthquake-problem new file mode 120000 index 0000000000..e4a703f050 --- /dev/null +++ b/Lang/R/Kernighans-large-earthquake-problem @@ -0,0 +1 @@ +../../Task/Kernighans-large-earthquake-problem/R \ No newline at end of file diff --git a/Lang/R/Munchausen-numbers b/Lang/R/Munchausen-numbers new file mode 120000 index 0000000000..aa4d45945f --- /dev/null +++ b/Lang/R/Munchausen-numbers @@ -0,0 +1 @@ +../../Task/Munchausen-numbers/R \ No newline at end of file diff --git a/Lang/R/Old-Russian-measure-of-length b/Lang/R/Old-Russian-measure-of-length new file mode 120000 index 0000000000..10e03acc09 --- /dev/null +++ b/Lang/R/Old-Russian-measure-of-length @@ -0,0 +1 @@ +../../Task/Old-Russian-measure-of-length/R \ No newline at end of file diff --git a/Lang/R/Semordnilap b/Lang/R/Semordnilap new file mode 120000 index 0000000000..8ef388caef --- /dev/null +++ b/Lang/R/Semordnilap @@ -0,0 +1 @@ +../../Task/Semordnilap/R \ No newline at end of file diff --git a/Lang/R/Sort-numbers-lexicographically b/Lang/R/Sort-numbers-lexicographically new file mode 120000 index 0000000000..77a76317d2 --- /dev/null +++ b/Lang/R/Sort-numbers-lexicographically @@ -0,0 +1 @@ +../../Task/Sort-numbers-lexicographically/R \ No newline at end of file diff --git a/Lang/R/Strip-a-set-of-characters-from-a-string b/Lang/R/Strip-a-set-of-characters-from-a-string new file mode 120000 index 0000000000..b83d60c994 --- /dev/null +++ b/Lang/R/Strip-a-set-of-characters-from-a-string @@ -0,0 +1 @@ +../../Task/Strip-a-set-of-characters-from-a-string/R \ No newline at end of file diff --git a/Lang/REXX/00-LANG.txt b/Lang/REXX/00-LANG.txt index a1abf9f554..fd028fe2bc 100644 --- a/Lang/REXX/00-LANG.txt +++ b/Lang/REXX/00-LANG.txt @@ -28,12 +28,17 @@ The '''REXX''' language was influenced by the computer programming languages: &n Using Classic REXX closely resembles pseudo code and many languages like Basic or Julia. Experienced programmers should have no problem reading REXX code and translating it to other languages.
Some items that might differ from what you are familiar with.
-* No data types, no declarations, everything is string. +* Caseless, fully free format. +* Code blocks delimited by do...end, no brackets (){}. +* Usual control structures present: do...by...to, do while/until, select, leave, iterate. +* No data types, no declarations, everything is string. String functions such as Left() or Substr() may be applied on numbers. +* All arithmetic is decimal based, not binary. So stuff like bit shifting or multiply/divide by 2 using exponent add/subtract does not apply. * Exponentiation is designated by '**' thus x^2 = x**2. * Integer division is designated by '%' thus 13%3 = 4. * Modulo division (remainder) is designated by '//' thus 13//3 = 1 ('13 mod 3'). * Arrays (here called 'stems') are designated by something like 'stem.a.b. etc' (stem = name array; a, b etc any value; 'associative arrays'). * Precision is unlimited (default 9 digits), but you have to specify it yourself ('numeric digits nn'). +* Parameter passing always by value. Stems cannot be passed, but must be made available with 'expose'. Versions of REXX: * '''[[wp:ARexx|ARexx]]'''   is a classic REXX implementation (with extensions) for the AmigaOS,   given in bundle since AmigaOS 2.   (Regina REXX has specific support for the extended functions that were introduced in ARexx.)   ARexx was written in 1987 by William S. Hawes. @@ -45,7 +50,7 @@ Some items that might differ from what you are familiar with.
* '''[[CRX REXX]]'''   (Compact REXX) is a classic REXX first written by Dr. Brian Marks. -* '''[[CTC REXX]]'''   is a classic REXX that is bundled with PC/SPF and written by Command Technology Corporation,   a license is required to use this product.   This version of REXX can only be used under PC/SPF and it's panels.   PC/SPF resembles the IBM program product SPF (which has other names and versions). The last version was published in 1996. CTC doesn't exist anymore. +* '''[[REXX/2]]'''   is a classic REXX that is bundled with PC/SPF and written by Command Technology Corporation,   a license is required to use this product.   This version of REXX can only be used under PC/SPF and it's panels.   PC/SPF resembles the IBM program product SPF (which has other names and versions). The last version was published in 1996. Company CTC doesn't exist anymore. * '''[[KEXX]]'''   is a subset of REXX that is bundled with KEDIT and written by Keven J. Kearney of Mansfield Software Group, Inc., a license is required to use this product.   KEXX only executes under the KEDIT licensed product.   KEDIT is an XEDIT clone (an editor from IBM for VM/CMS program products). @@ -121,16 +126,7 @@ Some items that might differ from what you are familiar with.
* [http://www.rexxla.org The Rexx Language Association - www.rexxla.org] * [http://regina-rexx.sourceforge.net/index.html Regina Rexx Interpreter] * [http://www.kedit.com/ Mansfield Software Group, Inc. (KEDIT)] -* [http://www.quercus-sys.com/ Personal REXX, Quercus Systems] -* [http://www.commandtechnology.com/ CTC Command Technology] * [http://www.rexxla.org/ CRX Open Source (right column side)] -* [http://www.kilowattsoftware.com/r4Page.htm R4, Kilowatt Software] -* [http://www.kilowattsoftware.com/rooPage.htm ROO, Kilowatt Software] -* [http://publib.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/HCSE2C00/CCONTENTS?SHELF=hcsh2ab0&DN=SC24-6221-00&DT=20090724140455 z/VM V6R1 REXX/VM Reference] -* [http://publib.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/HCSB3C00/CCONTENTS?SHELF=hcsh2ab0&DN=SC24-6222-00&DT=20090724131829 z/VM V6R1 REXX/VM User's Guide] -* [http://www.rexxinfo.org/html/rexxinfo1.html#Rexx-Manuals {many references to REXX manuals}] - - == Rosetta Code tasks not implemented in REXX == [[Reports:Tasks_not_implemented_in_REXX]] \ No newline at end of file diff --git a/Lang/REXX/Magic-constant b/Lang/REXX/Magic-constant new file mode 120000 index 0000000000..13d81a62dd --- /dev/null +++ b/Lang/REXX/Magic-constant @@ -0,0 +1 @@ +../../Task/Magic-constant/REXX \ No newline at end of file diff --git a/Lang/REXX/Primes---allocate-descendants-to-their-ancestors b/Lang/REXX/Primes---allocate-descendants-to-their-ancestors new file mode 120000 index 0000000000..e6293c9090 --- /dev/null +++ b/Lang/REXX/Primes---allocate-descendants-to-their-ancestors @@ -0,0 +1 @@ +../../Task/Primes---allocate-descendants-to-their-ancestors/REXX \ No newline at end of file diff --git a/Lang/REXX/Ramanujan-primes-twins b/Lang/REXX/Ramanujan-primes-twins new file mode 120000 index 0000000000..09da3d7f76 --- /dev/null +++ b/Lang/REXX/Ramanujan-primes-twins @@ -0,0 +1 @@ +../../Task/Ramanujan-primes-twins/REXX \ No newline at end of file diff --git a/Lang/REXX/Sequence-of-primorial-primes b/Lang/REXX/Sequence-of-primorial-primes new file mode 120000 index 0000000000..cd4ebe8c73 --- /dev/null +++ b/Lang/REXX/Sequence-of-primorial-primes @@ -0,0 +1 @@ +../../Task/Sequence-of-primorial-primes/REXX \ No newline at end of file diff --git a/Lang/REXX/Sieve-of-Pritchard b/Lang/REXX/Sieve-of-Pritchard new file mode 120000 index 0000000000..601b18d906 --- /dev/null +++ b/Lang/REXX/Sieve-of-Pritchard @@ -0,0 +1 @@ +../../Task/Sieve-of-Pritchard/REXX \ No newline at end of file diff --git a/Lang/Raku/Simple-turtle-graphics b/Lang/Raku/Simple-turtle-graphics new file mode 120000 index 0000000000..496cec69f4 --- /dev/null +++ b/Lang/Raku/Simple-turtle-graphics @@ -0,0 +1 @@ +../../Task/Simple-turtle-graphics/Raku \ No newline at end of file diff --git a/Lang/RapidQ/Levenshtein-distance b/Lang/RapidQ/Levenshtein-distance new file mode 120000 index 0000000000..43ee94415c --- /dev/null +++ b/Lang/RapidQ/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/RapidQ \ No newline at end of file diff --git a/Lang/RapidQ/M-bius-function b/Lang/RapidQ/M-bius-function new file mode 120000 index 0000000000..72bc6192fb --- /dev/null +++ b/Lang/RapidQ/M-bius-function @@ -0,0 +1 @@ +../../Task/M-bius-function/RapidQ \ No newline at end of file diff --git a/Lang/RapidQ/Map-range b/Lang/RapidQ/Map-range new file mode 120000 index 0000000000..a3da155381 --- /dev/null +++ b/Lang/RapidQ/Map-range @@ -0,0 +1 @@ +../../Task/Map-range/RapidQ \ No newline at end of file diff --git a/Lang/Refal/Loops-Infinite b/Lang/Refal/Loops-Infinite new file mode 120000 index 0000000000..536c01c9bd --- /dev/null +++ b/Lang/Refal/Loops-Infinite @@ -0,0 +1 @@ +../../Task/Loops-Infinite/Refal \ No newline at end of file diff --git a/Lang/Refal/Power-set b/Lang/Refal/Power-set new file mode 120000 index 0000000000..f50da086ad --- /dev/null +++ b/Lang/Refal/Power-set @@ -0,0 +1 @@ +../../Task/Power-set/Refal \ No newline at end of file diff --git a/Lang/Refal/Run-length-encoding b/Lang/Refal/Run-length-encoding new file mode 120000 index 0000000000..afeb7091c3 --- /dev/null +++ b/Lang/Refal/Run-length-encoding @@ -0,0 +1 @@ +../../Task/Run-length-encoding/Refal \ No newline at end of file diff --git a/Lang/Refal/Strip-comments-from-a-string b/Lang/Refal/Strip-comments-from-a-string new file mode 120000 index 0000000000..6f86213c31 --- /dev/null +++ b/Lang/Refal/Strip-comments-from-a-string @@ -0,0 +1 @@ +../../Task/Strip-comments-from-a-string/Refal \ No newline at end of file diff --git a/Lang/Rust/Ascending-primes b/Lang/Rust/Ascending-primes new file mode 120000 index 0000000000..84fdafe351 --- /dev/null +++ b/Lang/Rust/Ascending-primes @@ -0,0 +1 @@ +../../Task/Ascending-primes/Rust \ No newline at end of file diff --git a/Lang/Rust/B-zier-curves-Intersections b/Lang/Rust/B-zier-curves-Intersections new file mode 120000 index 0000000000..732ede6e4e --- /dev/null +++ b/Lang/Rust/B-zier-curves-Intersections @@ -0,0 +1 @@ +../../Task/B-zier-curves-Intersections/Rust \ No newline at end of file diff --git a/Lang/Rust/Bifid-cipher b/Lang/Rust/Bifid-cipher new file mode 120000 index 0000000000..8ddce2026b --- /dev/null +++ b/Lang/Rust/Bifid-cipher @@ -0,0 +1 @@ +../../Task/Bifid-cipher/Rust \ No newline at end of file diff --git a/Lang/Rust/Bioinformatics-Global-alignment b/Lang/Rust/Bioinformatics-Global-alignment new file mode 120000 index 0000000000..3bbbc3b358 --- /dev/null +++ b/Lang/Rust/Bioinformatics-Global-alignment @@ -0,0 +1 @@ +../../Task/Bioinformatics-Global-alignment/Rust \ No newline at end of file diff --git a/Lang/Rust/Blum-integer b/Lang/Rust/Blum-integer new file mode 120000 index 0000000000..7a0e8a69ae --- /dev/null +++ b/Lang/Rust/Blum-integer @@ -0,0 +1 @@ +../../Task/Blum-integer/Rust \ No newline at end of file diff --git a/Lang/Rust/Boyer-Moore-string-search b/Lang/Rust/Boyer-Moore-string-search new file mode 120000 index 0000000000..b70383335b --- /dev/null +++ b/Lang/Rust/Boyer-Moore-string-search @@ -0,0 +1 @@ +../../Task/Boyer-Moore-string-search/Rust \ No newline at end of file diff --git a/Lang/Rust/Calendar---for-REAL-programmers b/Lang/Rust/Calendar---for-REAL-programmers new file mode 120000 index 0000000000..5bd1cebf14 --- /dev/null +++ b/Lang/Rust/Calendar---for-REAL-programmers @@ -0,0 +1 @@ +../../Task/Calendar---for-REAL-programmers/Rust \ No newline at end of file diff --git a/Lang/Rust/Compare-sorting-algorithms-performance b/Lang/Rust/Compare-sorting-algorithms-performance new file mode 120000 index 0000000000..7676ca3dd8 --- /dev/null +++ b/Lang/Rust/Compare-sorting-algorithms-performance @@ -0,0 +1 @@ +../../Task/Compare-sorting-algorithms-performance/Rust \ No newline at end of file diff --git a/Lang/Rust/Compiler-AST-interpreter b/Lang/Rust/Compiler-AST-interpreter new file mode 120000 index 0000000000..2028e35209 --- /dev/null +++ b/Lang/Rust/Compiler-AST-interpreter @@ -0,0 +1 @@ +../../Task/Compiler-AST-interpreter/Rust \ No newline at end of file diff --git a/Lang/Rust/Compiler-code-generator b/Lang/Rust/Compiler-code-generator new file mode 120000 index 0000000000..fa460708f3 --- /dev/null +++ b/Lang/Rust/Compiler-code-generator @@ -0,0 +1 @@ +../../Task/Compiler-code-generator/Rust \ No newline at end of file diff --git a/Lang/Rust/Compiler-lexical-analyzer b/Lang/Rust/Compiler-lexical-analyzer new file mode 120000 index 0000000000..b603fdc69a --- /dev/null +++ b/Lang/Rust/Compiler-lexical-analyzer @@ -0,0 +1 @@ +../../Task/Compiler-lexical-analyzer/Rust \ No newline at end of file diff --git a/Lang/Rust/Compiler-syntax-analyzer b/Lang/Rust/Compiler-syntax-analyzer new file mode 120000 index 0000000000..4fa6fc40a8 --- /dev/null +++ b/Lang/Rust/Compiler-syntax-analyzer @@ -0,0 +1 @@ +../../Task/Compiler-syntax-analyzer/Rust \ No newline at end of file diff --git a/Lang/Rust/Cyclotomic-polynomial b/Lang/Rust/Cyclotomic-polynomial new file mode 120000 index 0000000000..8ff16fabbb --- /dev/null +++ b/Lang/Rust/Cyclotomic-polynomial @@ -0,0 +1 @@ +../../Task/Cyclotomic-polynomial/Rust \ No newline at end of file diff --git a/Lang/Rust/Descending-primes b/Lang/Rust/Descending-primes new file mode 120000 index 0000000000..fc953fbf4e --- /dev/null +++ b/Lang/Rust/Descending-primes @@ -0,0 +1 @@ +../../Task/Descending-primes/Rust \ No newline at end of file diff --git a/Lang/Rust/Doubly-linked-list-Definition b/Lang/Rust/Doubly-linked-list-Definition new file mode 120000 index 0000000000..9eb9054258 --- /dev/null +++ b/Lang/Rust/Doubly-linked-list-Definition @@ -0,0 +1 @@ +../../Task/Doubly-linked-list-Definition/Rust \ No newline at end of file diff --git a/Lang/Rust/Doubly-linked-list-Traversal b/Lang/Rust/Doubly-linked-list-Traversal new file mode 120000 index 0000000000..b44bd60c3c --- /dev/null +++ b/Lang/Rust/Doubly-linked-list-Traversal @@ -0,0 +1 @@ +../../Task/Doubly-linked-list-Traversal/Rust \ No newline at end of file diff --git a/Lang/Rust/Elliptic-Curve-Digital-Signature-Algorithm b/Lang/Rust/Elliptic-Curve-Digital-Signature-Algorithm new file mode 120000 index 0000000000..f6d4ecb90e --- /dev/null +++ b/Lang/Rust/Elliptic-Curve-Digital-Signature-Algorithm @@ -0,0 +1 @@ +../../Task/Elliptic-Curve-Digital-Signature-Algorithm/Rust \ No newline at end of file diff --git a/Lang/Rust/Faulhabers-formula b/Lang/Rust/Faulhabers-formula new file mode 120000 index 0000000000..f7691b3566 --- /dev/null +++ b/Lang/Rust/Faulhabers-formula @@ -0,0 +1 @@ +../../Task/Faulhabers-formula/Rust \ No newline at end of file diff --git a/Lang/Rust/Graph-colouring b/Lang/Rust/Graph-colouring new file mode 120000 index 0000000000..acb44a12b7 --- /dev/null +++ b/Lang/Rust/Graph-colouring @@ -0,0 +1 @@ +../../Task/Graph-colouring/Rust \ No newline at end of file diff --git a/Lang/Rust/Hex-words b/Lang/Rust/Hex-words new file mode 120000 index 0000000000..9322882ab9 --- /dev/null +++ b/Lang/Rust/Hex-words @@ -0,0 +1 @@ +../../Task/Hex-words/Rust \ No newline at end of file diff --git a/Lang/Rust/Kosaraju b/Lang/Rust/Kosaraju new file mode 120000 index 0000000000..69a0c5ef3e --- /dev/null +++ b/Lang/Rust/Kosaraju @@ -0,0 +1 @@ +../../Task/Kosaraju/Rust \ No newline at end of file diff --git a/Lang/Rust/Latin-Squares-in-reduced-form b/Lang/Rust/Latin-Squares-in-reduced-form new file mode 120000 index 0000000000..17d284a00f --- /dev/null +++ b/Lang/Rust/Latin-Squares-in-reduced-form @@ -0,0 +1 @@ +../../Task/Latin-Squares-in-reduced-form/Rust \ No newline at end of file diff --git a/Lang/Rust/Median-filter b/Lang/Rust/Median-filter new file mode 120000 index 0000000000..1cdae0e790 --- /dev/null +++ b/Lang/Rust/Median-filter @@ -0,0 +1 @@ +../../Task/Median-filter/Rust \ No newline at end of file diff --git a/Lang/Rust/Natural-sorting b/Lang/Rust/Natural-sorting new file mode 120000 index 0000000000..77b1a7de05 --- /dev/null +++ b/Lang/Rust/Natural-sorting @@ -0,0 +1 @@ +../../Task/Natural-sorting/Rust \ No newline at end of file diff --git a/Lang/Rust/Nonogram-solver b/Lang/Rust/Nonogram-solver new file mode 120000 index 0000000000..670a3f0f6a --- /dev/null +++ b/Lang/Rust/Nonogram-solver @@ -0,0 +1 @@ +../../Task/Nonogram-solver/Rust \ No newline at end of file diff --git a/Lang/Rust/OpenWebNet-password b/Lang/Rust/OpenWebNet-password new file mode 120000 index 0000000000..24be1f8b4a --- /dev/null +++ b/Lang/Rust/OpenWebNet-password @@ -0,0 +1 @@ +../../Task/OpenWebNet-password/Rust \ No newline at end of file diff --git a/Lang/Rust/P-Adic-numbers-basic b/Lang/Rust/P-Adic-numbers-basic new file mode 120000 index 0000000000..2ccd34b2fd --- /dev/null +++ b/Lang/Rust/P-Adic-numbers-basic @@ -0,0 +1 @@ +../../Task/P-Adic-numbers-basic/Rust \ No newline at end of file diff --git a/Lang/Rust/P-Adic-square-roots b/Lang/Rust/P-Adic-square-roots new file mode 120000 index 0000000000..ed4fb995e0 --- /dev/null +++ b/Lang/Rust/P-Adic-square-roots @@ -0,0 +1 @@ +../../Task/P-Adic-square-roots/Rust \ No newline at end of file diff --git a/Lang/Rust/Playfair-cipher b/Lang/Rust/Playfair-cipher new file mode 120000 index 0000000000..f3e93df373 --- /dev/null +++ b/Lang/Rust/Playfair-cipher @@ -0,0 +1 @@ +../../Task/Playfair-cipher/Rust \ No newline at end of file diff --git a/Lang/Rust/Polynomial-regression b/Lang/Rust/Polynomial-regression new file mode 120000 index 0000000000..cdb9cdc8ff --- /dev/null +++ b/Lang/Rust/Polynomial-regression @@ -0,0 +1 @@ +../../Task/Polynomial-regression/Rust \ No newline at end of file diff --git a/Lang/Rust/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a b/Lang/Rust/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a new file mode 120000 index 0000000000..a557952f5e --- /dev/null +++ b/Lang/Rust/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a @@ -0,0 +1 @@ +../../Task/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a/Rust \ No newline at end of file diff --git a/Lang/Rust/Pseudo-random-numbers-Middle-square-method b/Lang/Rust/Pseudo-random-numbers-Middle-square-method new file mode 120000 index 0000000000..07d7dfdf71 --- /dev/null +++ b/Lang/Rust/Pseudo-random-numbers-Middle-square-method @@ -0,0 +1 @@ +../../Task/Pseudo-random-numbers-Middle-square-method/Rust \ No newline at end of file diff --git a/Lang/Rust/Pseudo-random-numbers-Splitmix64 b/Lang/Rust/Pseudo-random-numbers-Splitmix64 new file mode 120000 index 0000000000..af868efefa --- /dev/null +++ b/Lang/Rust/Pseudo-random-numbers-Splitmix64 @@ -0,0 +1 @@ +../../Task/Pseudo-random-numbers-Splitmix64/Rust \ No newline at end of file diff --git a/Lang/Rust/QR-decomposition b/Lang/Rust/QR-decomposition new file mode 120000 index 0000000000..b6ec08cee6 --- /dev/null +++ b/Lang/Rust/QR-decomposition @@ -0,0 +1 @@ +../../Task/QR-decomposition/Rust \ No newline at end of file diff --git a/Lang/Rust/Rendezvous b/Lang/Rust/Rendezvous new file mode 120000 index 0000000000..2ae4407138 --- /dev/null +++ b/Lang/Rust/Rendezvous @@ -0,0 +1 @@ +../../Task/Rendezvous/Rust \ No newline at end of file diff --git a/Lang/Rust/Resistor-mesh b/Lang/Rust/Resistor-mesh new file mode 120000 index 0000000000..245eca7f06 --- /dev/null +++ b/Lang/Rust/Resistor-mesh @@ -0,0 +1 @@ +../../Task/Resistor-mesh/Rust \ No newline at end of file diff --git a/Lang/Rust/Shoelace-formula-for-polygonal-area b/Lang/Rust/Shoelace-formula-for-polygonal-area new file mode 120000 index 0000000000..4ce5ca075a --- /dev/null +++ b/Lang/Rust/Shoelace-formula-for-polygonal-area @@ -0,0 +1 @@ +../../Task/Shoelace-formula-for-polygonal-area/Rust \ No newline at end of file diff --git a/Lang/Rust/Solve-a-Holy-Knights-tour b/Lang/Rust/Solve-a-Holy-Knights-tour new file mode 120000 index 0000000000..7d376bff89 --- /dev/null +++ b/Lang/Rust/Solve-a-Holy-Knights-tour @@ -0,0 +1 @@ +../../Task/Solve-a-Holy-Knights-tour/Rust \ No newline at end of file diff --git a/Lang/Rust/Solve-a-Hopido-puzzle b/Lang/Rust/Solve-a-Hopido-puzzle new file mode 120000 index 0000000000..13eae5b688 --- /dev/null +++ b/Lang/Rust/Solve-a-Hopido-puzzle @@ -0,0 +1 @@ +../../Task/Solve-a-Hopido-puzzle/Rust \ No newline at end of file diff --git a/Lang/Rust/Solve-a-Numbrix-puzzle b/Lang/Rust/Solve-a-Numbrix-puzzle new file mode 120000 index 0000000000..6da0fac9a0 --- /dev/null +++ b/Lang/Rust/Solve-a-Numbrix-puzzle @@ -0,0 +1 @@ +../../Task/Solve-a-Numbrix-puzzle/Rust \ No newline at end of file diff --git a/Lang/Rust/Sorting-algorithms-Bead-sort b/Lang/Rust/Sorting-algorithms-Bead-sort new file mode 120000 index 0000000000..1096740d47 --- /dev/null +++ b/Lang/Rust/Sorting-algorithms-Bead-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Bead-sort/Rust \ No newline at end of file diff --git a/Lang/Rust/Sorting-algorithms-Patience-sort b/Lang/Rust/Sorting-algorithms-Patience-sort new file mode 120000 index 0000000000..98bfba78ce --- /dev/null +++ b/Lang/Rust/Sorting-algorithms-Patience-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Patience-sort/Rust \ No newline at end of file diff --git a/Lang/Rust/Sorting-algorithms-Strand-sort b/Lang/Rust/Sorting-algorithms-Strand-sort new file mode 120000 index 0000000000..c01a273a80 --- /dev/null +++ b/Lang/Rust/Sorting-algorithms-Strand-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Strand-sort/Rust \ No newline at end of file diff --git a/Lang/Rust/Steffensens-method b/Lang/Rust/Steffensens-method new file mode 120000 index 0000000000..4aa426ad52 --- /dev/null +++ b/Lang/Rust/Steffensens-method @@ -0,0 +1 @@ +../../Task/Steffensens-method/Rust \ No newline at end of file diff --git a/Lang/Rust/Strassens-algorithm b/Lang/Rust/Strassens-algorithm new file mode 120000 index 0000000000..059089e819 --- /dev/null +++ b/Lang/Rust/Strassens-algorithm @@ -0,0 +1 @@ +../../Task/Strassens-algorithm/Rust \ No newline at end of file diff --git a/Lang/Rust/Stream-merge b/Lang/Rust/Stream-merge new file mode 120000 index 0000000000..101f42c85a --- /dev/null +++ b/Lang/Rust/Stream-merge @@ -0,0 +1 @@ +../../Task/Stream-merge/Rust \ No newline at end of file diff --git a/Lang/Rust/Sudan-function b/Lang/Rust/Sudan-function new file mode 120000 index 0000000000..29cdeee99f --- /dev/null +++ b/Lang/Rust/Sudan-function @@ -0,0 +1 @@ +../../Task/Sudan-function/Rust \ No newline at end of file diff --git a/Lang/Rust/Tonelli-Shanks-algorithm b/Lang/Rust/Tonelli-Shanks-algorithm new file mode 120000 index 0000000000..b90bd71718 --- /dev/null +++ b/Lang/Rust/Tonelli-Shanks-algorithm @@ -0,0 +1 @@ +../../Task/Tonelli-Shanks-algorithm/Rust \ No newline at end of file diff --git a/Lang/Rust/Ukkonen-s-suffix-tree-construction b/Lang/Rust/Ukkonen-s-suffix-tree-construction new file mode 120000 index 0000000000..684e412fed --- /dev/null +++ b/Lang/Rust/Ukkonen-s-suffix-tree-construction @@ -0,0 +1 @@ +../../Task/Ukkonen-s-suffix-tree-construction/Rust \ No newline at end of file diff --git a/Lang/Rust/Verhoeff-algorithm b/Lang/Rust/Verhoeff-algorithm new file mode 120000 index 0000000000..fd5322e5ec --- /dev/null +++ b/Lang/Rust/Verhoeff-algorithm @@ -0,0 +1 @@ +../../Task/Verhoeff-algorithm/Rust \ No newline at end of file diff --git a/Lang/Rust/Xiaolin-Wus-line-algorithm b/Lang/Rust/Xiaolin-Wus-line-algorithm new file mode 120000 index 0000000000..68352a1cb5 --- /dev/null +++ b/Lang/Rust/Xiaolin-Wus-line-algorithm @@ -0,0 +1 @@ +../../Task/Xiaolin-Wus-line-algorithm/Rust \ No newline at end of file diff --git a/Lang/S-BASIC/Additive-primes b/Lang/S-BASIC/Additive-primes new file mode 120000 index 0000000000..b90d39a158 --- /dev/null +++ b/Lang/S-BASIC/Additive-primes @@ -0,0 +1 @@ +../../Task/Additive-primes/S-BASIC \ No newline at end of file diff --git a/Lang/S-BASIC/Character-codes b/Lang/S-BASIC/Character-codes new file mode 120000 index 0000000000..f408189f94 --- /dev/null +++ b/Lang/S-BASIC/Character-codes @@ -0,0 +1 @@ +../../Task/Character-codes/S-BASIC \ No newline at end of file diff --git a/Lang/S-BASIC/Loops-Increment-loop-index-within-loop-body b/Lang/S-BASIC/Loops-Increment-loop-index-within-loop-body new file mode 120000 index 0000000000..0b105df636 --- /dev/null +++ b/Lang/S-BASIC/Loops-Increment-loop-index-within-loop-body @@ -0,0 +1 @@ +../../Task/Loops-Increment-loop-index-within-loop-body/S-BASIC \ No newline at end of file diff --git a/Lang/S-BASIC/Sum-of-a-series b/Lang/S-BASIC/Sum-of-a-series new file mode 120000 index 0000000000..1396d4d958 --- /dev/null +++ b/Lang/S-BASIC/Sum-of-a-series @@ -0,0 +1 @@ +../../Task/Sum-of-a-series/S-BASIC \ No newline at end of file diff --git a/Lang/SETL/Gray-code b/Lang/SETL/Gray-code new file mode 120000 index 0000000000..a07e0b4e7b --- /dev/null +++ b/Lang/SETL/Gray-code @@ -0,0 +1 @@ +../../Task/Gray-code/SETL \ No newline at end of file diff --git a/Lang/SETL/Loops-Do-while b/Lang/SETL/Loops-Do-while new file mode 120000 index 0000000000..8e0329f189 --- /dev/null +++ b/Lang/SETL/Loops-Do-while @@ -0,0 +1 @@ +../../Task/Loops-Do-while/SETL \ No newline at end of file diff --git a/Lang/SETL/Loops-Increment-loop-index-within-loop-body b/Lang/SETL/Loops-Increment-loop-index-within-loop-body new file mode 120000 index 0000000000..21b3e5953d --- /dev/null +++ b/Lang/SETL/Loops-Increment-loop-index-within-loop-body @@ -0,0 +1 @@ +../../Task/Loops-Increment-loop-index-within-loop-body/SETL \ No newline at end of file diff --git a/Lang/SETL/Loops-Infinite b/Lang/SETL/Loops-Infinite new file mode 120000 index 0000000000..582c03e313 --- /dev/null +++ b/Lang/SETL/Loops-Infinite @@ -0,0 +1 @@ +../../Task/Loops-Infinite/SETL \ No newline at end of file diff --git a/Lang/SETL/Radical-of-an-integer b/Lang/SETL/Radical-of-an-integer new file mode 120000 index 0000000000..7020a7b45c --- /dev/null +++ b/Lang/SETL/Radical-of-an-integer @@ -0,0 +1 @@ +../../Task/Radical-of-an-integer/SETL \ No newline at end of file diff --git a/Lang/SETL/Strip-comments-from-a-string b/Lang/SETL/Strip-comments-from-a-string new file mode 120000 index 0000000000..6397b858bf --- /dev/null +++ b/Lang/SETL/Strip-comments-from-a-string @@ -0,0 +1 @@ +../../Task/Strip-comments-from-a-string/SETL \ No newline at end of file diff --git a/Lang/SQL/Factorial b/Lang/SQL/Factorial new file mode 120000 index 0000000000..c6f45973cd --- /dev/null +++ b/Lang/SQL/Factorial @@ -0,0 +1 @@ +../../Task/Factorial/SQL \ No newline at end of file diff --git a/Lang/Scala/Boyer-Moore-string-search b/Lang/Scala/Boyer-Moore-string-search new file mode 120000 index 0000000000..58b64a7997 --- /dev/null +++ b/Lang/Scala/Boyer-Moore-string-search @@ -0,0 +1 @@ +../../Task/Boyer-Moore-string-search/Scala \ No newline at end of file diff --git a/Lang/Scheme/Circular-primes b/Lang/Scheme/Circular-primes new file mode 120000 index 0000000000..9f4430f520 --- /dev/null +++ b/Lang/Scheme/Circular-primes @@ -0,0 +1 @@ +../../Task/Circular-primes/Scheme \ No newline at end of file diff --git a/Lang/Scheme/Compare-length-of-two-strings b/Lang/Scheme/Compare-length-of-two-strings new file mode 120000 index 0000000000..d6e6006fa7 --- /dev/null +++ b/Lang/Scheme/Compare-length-of-two-strings @@ -0,0 +1 @@ +../../Task/Compare-length-of-two-strings/Scheme \ No newline at end of file diff --git a/Lang/Scheme/Runge-Kutta-method b/Lang/Scheme/Runge-Kutta-method new file mode 120000 index 0000000000..55b6f782a6 --- /dev/null +++ b/Lang/Scheme/Runge-Kutta-method @@ -0,0 +1 @@ +../../Task/Runge-Kutta-method/Scheme \ No newline at end of file diff --git a/Lang/Scheme/Unicode-variable-names b/Lang/Scheme/Unicode-variable-names new file mode 120000 index 0000000000..e5f49b3fae --- /dev/null +++ b/Lang/Scheme/Unicode-variable-names @@ -0,0 +1 @@ +../../Task/Unicode-variable-names/Scheme \ No newline at end of file diff --git a/Lang/Standard-ML/Box-the-compass b/Lang/Standard-ML/Box-the-compass new file mode 120000 index 0000000000..bdb5283192 --- /dev/null +++ b/Lang/Standard-ML/Box-the-compass @@ -0,0 +1 @@ +../../Task/Box-the-compass/Standard-ML \ No newline at end of file diff --git a/Lang/Tcl/Unicode-strings b/Lang/Tcl/Unicode-strings new file mode 120000 index 0000000000..5d3bbc0431 --- /dev/null +++ b/Lang/Tcl/Unicode-strings @@ -0,0 +1 @@ +../../Task/Unicode-strings/Tcl \ No newline at end of file diff --git a/Lang/Tiny-BASIC/Magic-constant b/Lang/Tiny-BASIC/Magic-constant new file mode 120000 index 0000000000..e64a075712 --- /dev/null +++ b/Lang/Tiny-BASIC/Magic-constant @@ -0,0 +1 @@ +../../Task/Magic-constant/Tiny-BASIC \ No newline at end of file diff --git a/Lang/True-BASIC/Evaluate-binomial-coefficients b/Lang/True-BASIC/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..8a2a036883 --- /dev/null +++ b/Lang/True-BASIC/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/True-BASIC \ No newline at end of file diff --git a/Lang/TypeScript/Additive-primes b/Lang/TypeScript/Additive-primes new file mode 120000 index 0000000000..698823ecab --- /dev/null +++ b/Lang/TypeScript/Additive-primes @@ -0,0 +1 @@ +../../Task/Additive-primes/TypeScript \ No newline at end of file diff --git a/Lang/TypeScript/Arithmetic-numbers b/Lang/TypeScript/Arithmetic-numbers new file mode 120000 index 0000000000..0a37af8cff --- /dev/null +++ b/Lang/TypeScript/Arithmetic-numbers @@ -0,0 +1 @@ +../../Task/Arithmetic-numbers/TypeScript \ No newline at end of file diff --git a/Lang/TypeScript/Map-range b/Lang/TypeScript/Map-range new file mode 120000 index 0000000000..50eeda25cd --- /dev/null +++ b/Lang/TypeScript/Map-range @@ -0,0 +1 @@ +../../Task/Map-range/TypeScript \ No newline at end of file diff --git a/Lang/TypeScript/Sum-of-a-series b/Lang/TypeScript/Sum-of-a-series new file mode 120000 index 0000000000..810faf05f3 --- /dev/null +++ b/Lang/TypeScript/Sum-of-a-series @@ -0,0 +1 @@ +../../Task/Sum-of-a-series/TypeScript \ No newline at end of file diff --git a/Lang/UNIX-Shell/Color-of-a-screen-pixel b/Lang/UNIX-Shell/Color-of-a-screen-pixel new file mode 120000 index 0000000000..8344bcd2f2 --- /dev/null +++ b/Lang/UNIX-Shell/Color-of-a-screen-pixel @@ -0,0 +1 @@ +../../Task/Color-of-a-screen-pixel/UNIX-Shell \ No newline at end of file diff --git a/Lang/UNIX-Shell/Color-quantization b/Lang/UNIX-Shell/Color-quantization new file mode 120000 index 0000000000..6c518f1af5 --- /dev/null +++ b/Lang/UNIX-Shell/Color-quantization @@ -0,0 +1 @@ +../../Task/Color-quantization/UNIX-Shell \ No newline at end of file diff --git a/Lang/Uiua/Create-a-two-dimensional-array-at-runtime b/Lang/Uiua/Create-a-two-dimensional-array-at-runtime new file mode 120000 index 0000000000..4ef285f54f --- /dev/null +++ b/Lang/Uiua/Create-a-two-dimensional-array-at-runtime @@ -0,0 +1 @@ +../../Task/Create-a-two-dimensional-array-at-runtime/Uiua \ No newline at end of file diff --git a/Lang/Uiua/Damm-algorithm b/Lang/Uiua/Damm-algorithm new file mode 120000 index 0000000000..af8244172d --- /dev/null +++ b/Lang/Uiua/Damm-algorithm @@ -0,0 +1 @@ +../../Task/Damm-algorithm/Uiua \ No newline at end of file diff --git a/Lang/Uiua/Ethiopian-multiplication b/Lang/Uiua/Ethiopian-multiplication new file mode 120000 index 0000000000..4091de8f8e --- /dev/null +++ b/Lang/Uiua/Ethiopian-multiplication @@ -0,0 +1 @@ +../../Task/Ethiopian-multiplication/Uiua \ No newline at end of file diff --git a/Lang/Uiua/Matrix-transposition b/Lang/Uiua/Matrix-transposition new file mode 120000 index 0000000000..877ca2d6ea --- /dev/null +++ b/Lang/Uiua/Matrix-transposition @@ -0,0 +1 @@ +../../Task/Matrix-transposition/Uiua \ No newline at end of file diff --git a/Lang/Uiua/Munching-squares b/Lang/Uiua/Munching-squares new file mode 120000 index 0000000000..65b5e765bd --- /dev/null +++ b/Lang/Uiua/Munching-squares @@ -0,0 +1 @@ +../../Task/Munching-squares/Uiua \ No newline at end of file diff --git a/Lang/Uiua/Pangram-checker b/Lang/Uiua/Pangram-checker new file mode 120000 index 0000000000..f48b39bf42 --- /dev/null +++ b/Lang/Uiua/Pangram-checker @@ -0,0 +1 @@ +../../Task/Pangram-checker/Uiua \ No newline at end of file diff --git a/Lang/Uiua/Spiral-matrix b/Lang/Uiua/Spiral-matrix new file mode 120000 index 0000000000..58fe68a534 --- /dev/null +++ b/Lang/Uiua/Spiral-matrix @@ -0,0 +1 @@ +../../Task/Spiral-matrix/Uiua \ No newline at end of file diff --git a/Lang/Uiua/Zig-zag-matrix b/Lang/Uiua/Zig-zag-matrix new file mode 120000 index 0000000000..3d79e2a814 --- /dev/null +++ b/Lang/Uiua/Zig-zag-matrix @@ -0,0 +1 @@ +../../Task/Zig-zag-matrix/Uiua \ No newline at end of file diff --git a/Lang/Uxntal/00-LANG.txt b/Lang/Uxntal/00-LANG.txt index d0204e9b73..29f2256564 100644 --- a/Lang/Uxntal/00-LANG.txt +++ b/Lang/Uxntal/00-LANG.txt @@ -1,5 +1,7 @@ {{language|Uxntal}} +''For unimplemented tasks see: [https://rosettacode.org/wiki/Tasks_not_implemented_in_Uxntal Uxntal Unimplemened]'' + '''Uxntal''' is the assembly language for the Uxn virtual machine. The VM has 64KiB of addressable memory, two 256-byte stacks (data and return), and a 256-byte block of I/O ports, divided into 16 devices with 16 ports each. The Uxntal assembler features sub-labels, simple lambdas, user-defined macros, and shorthands for common immediate operations. == Uxn VM == @@ -12,10 +14,23 @@ The 256 opcodes are divided into 8 special instructions, and 31 regular instruct == Syntax == +
+In concatenative programming, there are no precedence rules, the calculations are merely performed in the sequence in which they are presented. The order with which elements come off a stack is known as last in, first out. '''''— [https://wiki.xxiivv.com/site/uxntal_syntax.html Uxntal Syntax]''''' +
+ Instructions are written in uppercase, followed by any combination of the three flags 2kr. Hex values are written with lowercase a-f. Code can be placed at specific addresses with the | rune, which is especially important for assembling the reset vector at address 0x100 (|0100) and for defining devices and zero-page variables. Padding can be inserted with the $ rune. Labels are created with @ and &. The difference is that @ creates a label with the given name, while & creates a sub-label by prefixing the most recent @label and a slash. -For further details on Uxntal syntax, see the [https://wiki.xxiivv.com/site/uxntal_syntax.html syntax page] on the XXIIVV wiki. \ No newline at end of file +For further details on Uxntal syntax, see the [https://wiki.xxiivv.com/site/uxntal_syntax.html syntax page] on the XXIIVV wiki. + +[[Category:Assembler_language]] +[[Category:Assembly]] +[[Category:Esoteric_Languages]] +[[Category:Execution_method/Compiled/Bytecode]] +[[Category:Programming_paradigm/Object-oriented]] +[[Category:Programming_paradigm/Concatenative]] +[[Category:Typing/Unsafe]] +[[Category:Typing/Untyped]] \ No newline at end of file diff --git a/Lang/Uxntal/Array-length b/Lang/Uxntal/Array-length new file mode 120000 index 0000000000..438c43e439 --- /dev/null +++ b/Lang/Uxntal/Array-length @@ -0,0 +1 @@ +../../Task/Array-length/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Bioinformatics-base-count b/Lang/Uxntal/Bioinformatics-base-count new file mode 120000 index 0000000000..f9af105afe --- /dev/null +++ b/Lang/Uxntal/Bioinformatics-base-count @@ -0,0 +1 @@ +../../Task/Bioinformatics-base-count/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Comments b/Lang/Uxntal/Comments new file mode 120000 index 0000000000..b23db936ba --- /dev/null +++ b/Lang/Uxntal/Comments @@ -0,0 +1 @@ +../../Task/Comments/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Conditional-structures b/Lang/Uxntal/Conditional-structures new file mode 120000 index 0000000000..75d2f67746 --- /dev/null +++ b/Lang/Uxntal/Conditional-structures @@ -0,0 +1 @@ +../../Task/Conditional-structures/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Copy-a-string b/Lang/Uxntal/Copy-a-string new file mode 120000 index 0000000000..00610fac74 --- /dev/null +++ b/Lang/Uxntal/Copy-a-string @@ -0,0 +1 @@ +../../Task/Copy-a-string/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Draw-a-pixel b/Lang/Uxntal/Draw-a-pixel deleted file mode 120000 index 68f5f2e311..0000000000 --- a/Lang/Uxntal/Draw-a-pixel +++ /dev/null @@ -1 +0,0 @@ -../../Task/Draw-a-pixel/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Fibonacci-sequence b/Lang/Uxntal/Fibonacci-sequence new file mode 120000 index 0000000000..7795c4564a --- /dev/null +++ b/Lang/Uxntal/Fibonacci-sequence @@ -0,0 +1 @@ +../../Task/Fibonacci-sequence/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Flow-control-structures b/Lang/Uxntal/Flow-control-structures new file mode 120000 index 0000000000..db95ed817d --- /dev/null +++ b/Lang/Uxntal/Flow-control-structures @@ -0,0 +1 @@ +../../Task/Flow-control-structures/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Hello-world-Graphical b/Lang/Uxntal/Hello-world-Graphical new file mode 120000 index 0000000000..2a5fadb101 --- /dev/null +++ b/Lang/Uxntal/Hello-world-Graphical @@ -0,0 +1 @@ +../../Task/Hello-world-Graphical/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Hello-world-Standard-error b/Lang/Uxntal/Hello-world-Standard-error new file mode 120000 index 0000000000..be0ab3efa0 --- /dev/null +++ b/Lang/Uxntal/Hello-world-Standard-error @@ -0,0 +1 @@ +../../Task/Hello-world-Standard-error/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Hello-world-Text b/Lang/Uxntal/Hello-world-Text deleted file mode 120000 index 9024a6cde4..0000000000 --- a/Lang/Uxntal/Hello-world-Text +++ /dev/null @@ -1 +0,0 @@ -../../Task/Hello-world-Text/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Integer-sequence b/Lang/Uxntal/Integer-sequence new file mode 120000 index 0000000000..6d76150081 --- /dev/null +++ b/Lang/Uxntal/Integer-sequence @@ -0,0 +1 @@ +../../Task/Integer-sequence/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Loops-Break b/Lang/Uxntal/Loops-Break new file mode 120000 index 0000000000..5d6d57196c --- /dev/null +++ b/Lang/Uxntal/Loops-Break @@ -0,0 +1 @@ +../../Task/Loops-Break/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Loops-Continue b/Lang/Uxntal/Loops-Continue new file mode 120000 index 0000000000..88d5768874 --- /dev/null +++ b/Lang/Uxntal/Loops-Continue @@ -0,0 +1 @@ +../../Task/Loops-Continue/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Loops-Do-while b/Lang/Uxntal/Loops-Do-while new file mode 120000 index 0000000000..a3d655278d --- /dev/null +++ b/Lang/Uxntal/Loops-Do-while @@ -0,0 +1 @@ +../../Task/Loops-Do-while/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Loops-For-with-a-specified-step b/Lang/Uxntal/Loops-For-with-a-specified-step new file mode 120000 index 0000000000..4f79f37c9f --- /dev/null +++ b/Lang/Uxntal/Loops-For-with-a-specified-step @@ -0,0 +1 @@ +../../Task/Loops-For-with-a-specified-step/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Loops-Foreach b/Lang/Uxntal/Loops-Foreach new file mode 120000 index 0000000000..f8f61da6a7 --- /dev/null +++ b/Lang/Uxntal/Loops-Foreach @@ -0,0 +1 @@ +../../Task/Loops-Foreach/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Loops-N-plus-one-half b/Lang/Uxntal/Loops-N-plus-one-half new file mode 120000 index 0000000000..f7ee606c95 --- /dev/null +++ b/Lang/Uxntal/Loops-N-plus-one-half @@ -0,0 +1 @@ +../../Task/Loops-N-plus-one-half/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Loops-While b/Lang/Uxntal/Loops-While new file mode 120000 index 0000000000..f8307c2951 --- /dev/null +++ b/Lang/Uxntal/Loops-While @@ -0,0 +1 @@ +../../Task/Loops-While/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/Stack-traces b/Lang/Uxntal/Stack-traces new file mode 120000 index 0000000000..0b9cf24839 --- /dev/null +++ b/Lang/Uxntal/Stack-traces @@ -0,0 +1 @@ +../../Task/Stack-traces/Uxntal \ No newline at end of file diff --git a/Lang/Uxntal/String-length b/Lang/Uxntal/String-length new file mode 120000 index 0000000000..8dd88d3b90 --- /dev/null +++ b/Lang/Uxntal/String-length @@ -0,0 +1 @@ +../../Task/String-length/Uxntal \ No newline at end of file diff --git a/Lang/V-(Vlang)/Quine b/Lang/V-(Vlang)/Quine new file mode 120000 index 0000000000..a258f08a53 --- /dev/null +++ b/Lang/V-(Vlang)/Quine @@ -0,0 +1 @@ +../../Task/Quine/V-(Vlang) \ No newline at end of file diff --git a/Lang/Wisp/Knuth-shuffle b/Lang/Wisp/Knuth-shuffle new file mode 120000 index 0000000000..14993ebaba --- /dev/null +++ b/Lang/Wisp/Knuth-shuffle @@ -0,0 +1 @@ +../../Task/Knuth-shuffle/Wisp \ No newline at end of file diff --git a/Lang/X86-64-Assembly/Terminal-control-Clear-the-screen b/Lang/X86-64-Assembly/Terminal-control-Clear-the-screen new file mode 120000 index 0000000000..8974ae4cd4 --- /dev/null +++ b/Lang/X86-64-Assembly/Terminal-control-Clear-the-screen @@ -0,0 +1 @@ +../../Task/Terminal-control-Clear-the-screen/X86-64-Assembly \ No newline at end of file diff --git a/Lang/XBasic/Levenshtein-distance b/Lang/XBasic/Levenshtein-distance new file mode 120000 index 0000000000..57fd900b58 --- /dev/null +++ b/Lang/XBasic/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/XBasic \ No newline at end of file diff --git a/Lang/XPL0/Bin-given-limits b/Lang/XPL0/Bin-given-limits new file mode 120000 index 0000000000..d093bfd306 --- /dev/null +++ b/Lang/XPL0/Bin-given-limits @@ -0,0 +1 @@ +../../Task/Bin-given-limits/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Create-an-object-at-a-given-address b/Lang/XPL0/Create-an-object-at-a-given-address new file mode 120000 index 0000000000..10ca5e5926 --- /dev/null +++ b/Lang/XPL0/Create-an-object-at-a-given-address @@ -0,0 +1 @@ +../../Task/Create-an-object-at-a-given-address/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Floyd-Warshall-algorithm b/Lang/XPL0/Floyd-Warshall-algorithm new file mode 120000 index 0000000000..ffd21f6111 --- /dev/null +++ b/Lang/XPL0/Floyd-Warshall-algorithm @@ -0,0 +1 @@ +../../Task/Floyd-Warshall-algorithm/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Largest-int-from-concatenated-ints b/Lang/XPL0/Largest-int-from-concatenated-ints new file mode 120000 index 0000000000..c906e77c82 --- /dev/null +++ b/Lang/XPL0/Largest-int-from-concatenated-ints @@ -0,0 +1 @@ +../../Task/Largest-int-from-concatenated-ints/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Last-letter-first-letter b/Lang/XPL0/Last-letter-first-letter new file mode 120000 index 0000000000..f77624cd59 --- /dev/null +++ b/Lang/XPL0/Last-letter-first-letter @@ -0,0 +1 @@ +../../Task/Last-letter-first-letter/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Levenshtein-distance b/Lang/XPL0/Levenshtein-distance new file mode 120000 index 0000000000..0172b975ff --- /dev/null +++ b/Lang/XPL0/Levenshtein-distance @@ -0,0 +1 @@ +../../Task/Levenshtein-distance/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Polynomial-regression b/Lang/XPL0/Polynomial-regression new file mode 120000 index 0000000000..01f5c8d75a --- /dev/null +++ b/Lang/XPL0/Polynomial-regression @@ -0,0 +1 @@ +../../Task/Polynomial-regression/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Read-a-configuration-file b/Lang/XPL0/Read-a-configuration-file new file mode 120000 index 0000000000..338d315c72 --- /dev/null +++ b/Lang/XPL0/Read-a-configuration-file @@ -0,0 +1 @@ +../../Task/Read-a-configuration-file/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Sort-three-variables b/Lang/XPL0/Sort-three-variables new file mode 120000 index 0000000000..6a041ebc3e --- /dev/null +++ b/Lang/XPL0/Sort-three-variables @@ -0,0 +1 @@ +../../Task/Sort-three-variables/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Text-processing-1 b/Lang/XPL0/Text-processing-1 new file mode 120000 index 0000000000..395543f260 --- /dev/null +++ b/Lang/XPL0/Text-processing-1 @@ -0,0 +1 @@ +../../Task/Text-processing-1/XPL0 \ No newline at end of file diff --git a/Lang/XPL0/Text-processing-2 b/Lang/XPL0/Text-processing-2 new file mode 120000 index 0000000000..8d2b9925ef --- /dev/null +++ b/Lang/XPL0/Text-processing-2 @@ -0,0 +1 @@ +../../Task/Text-processing-2/XPL0 \ No newline at end of file diff --git a/Lang/Yabasic/Evaluate-binomial-coefficients b/Lang/Yabasic/Evaluate-binomial-coefficients new file mode 120000 index 0000000000..2d010b1897 --- /dev/null +++ b/Lang/Yabasic/Evaluate-binomial-coefficients @@ -0,0 +1 @@ +../../Task/Evaluate-binomial-coefficients/Yabasic \ No newline at end of file diff --git a/Lang/ZED/00-LANG.txt b/Lang/ZED/00-LANG.txt index 467ecdad02..5b0358bc17 100644 --- a/Lang/ZED/00-LANG.txt +++ b/Lang/ZED/00-LANG.txt @@ -12,6 +12,9 @@ Development of ZEDc is also happening on GitHub: https://github.com/zelah/ZEDc ZED can be seen compiling itself here: http://ideone.com/ARpMCM +(begin (define (ZED* ZEDnumber1 ZEDnumber2) (cond (#t (* ZEDnumber1 ZEDnumber2)) (else err))) (define (ZED+ ZEDnumber1 ZEDnumber2) (cond (#t (+ ZEDnumber1 ZEDnumber2)) (else err))) (define (ZED- ZEDnumber1 ZEDnumber2) (cond (#t (- ZEDnumber1 ZEDnumber2)) (else err))) (define (ZED/ ZEDnumber1 ZEDnumber2) (cond (#t (/ ZEDnumber1 ZEDnumber2)) (else err))) (define (ZED= value1 value2) (cond (#t (eqv? value1 value2)) (else err))) (define (ZEDadd-between! item list collect) (cond ((null? list) collect) ((null? (cdr list)) (cons (car list) collect)) (#t (ZEDadd-between! item (cdr list) (cons item (cons (car list) collect)))) (else err))) (define (ZEDadd-between item list) (cond (#t (reverse (ZEDadd-between! item list (quote ())))) (else err))) (define (ZEDadd-between-ra list item) (cond (#t (reverse (ZEDadd-between! item list (quote ())))) (else err))) (define (ZEDalpha) (cond (#t (ZEDwrite-all (ZEDrd (quote ()) append (ZEDrd (quote ()) append (ZEDnewlines (ZEDby-four (ZEDfunction-sort (ZEDsentences (ZEDleading-newline (ZEDspace-newline (ZEDtab-replace (ZEDnewline-space-tab-repeats (ZEDnewline-space (ZEDfilter ZEDnot-return? (ZEDreplace-trailing-white-space (ZEDread-all)))))))))))))))) (else err))) (define (ZEDapplication? expression) (cond (#t (and (not (null? expression)) (pair? (car expression)) (null? (cdar expression)))) (else err))) (define (ZEDarity arity-hash function) (cond (#t (cdr (assoc function arity-hash))) (else err))) (define (ZEDarity-hash! clause) (cond (#t (cons (ZEDclause-name clause) (ZEDclause-arity clause))) (else err))) (define (ZEDarity-hash program) (cond (#t (append (map ZEDarity-hash! program) (append (list (cons (quote ZED1) 1) (cons (quote ZED!) 1) (cons (quote ZED001) 1) (cons (quote or) 2) (cons (quote and) 2) (cons (quote begin) 2) (cons (quote ZEDc) 2) (cons (quote quote) 1)) (list (cons (quote ZED002) 2) (cons (quote ZED003) 3) (cons (quote ZED004) 4) (cons (quote ZED005) 5) (cons (quote ZED006) 6) (cons (quote ZED007) 7) (cons (quote ZED008) 8) (cons (quote ZED009) 9) (cons (quote ZED010) 10) (cons (quote ZED011) 11) (cons (quote ZED012) 12) (cons (quote ZED013) 13) (cons (quote ZED014) 14) (cons (quote ZED015) 15) (cons (quote ZED016) 16) (cons (quote ZED017) 17) (cons (quote ZED018) 18) (cons (quote ZED019) 19) (cons (quote ZED020) 20) (cons (quote ZED021) 21) (cons (quote ZED022) 22) (cons (quote ZED023) 23) (cons (quote ZED024) 24) (cons (quote ZED025) 25) (cons (quote ZED026) 26) (cons (quote ZED027) 27) (cons (quote ZED028) 28) (cons (quote ZED029) 29) (cons (quote ZED030) 30) (cons (quote ZED031) 31) (cons (quote ZED032) 32) (cons (quote ZED033) 33) (cons (quote ZED034) 34) (cons (quote ZED035) 35) (cons (quote ZED036) 36) (cons (quote ZED037) 37) (cons (quote ZED038) 38) (cons (quote ZED039) 39) (cons (quote ZED040) 40) (cons (quote ZED041) 41) (cons (quote ZED042) 42) (cons (quote ZED043) 43) (cons (quote ZED044) 44) (cons (quote ZED045) 45) (cons (quote ZED046) 46) (cons (quote ZED047) 47) (cons (quote ZED048) 48) (cons (quote ZED049) 49) (cons (quote ZED050) 50) (cons (quote ZED051) 51) (cons (quote ZED052) 52) (cons (quote ZED053) 53) (cons (quote ZED054) 54) (cons (quote ZED055) 55) (cons (quote ZED056) 56) (cons (quote ZED057) 57) (cons (quote ZED058) 58) (cons (quote ZED059) 59) (cons (quote ZED060) 60) (cons (quote ZED061) 61) (cons (quote ZED062) 62) (cons (quote ZED063) 63) (cons (quote ZED064) 64) (cons (quote ZED065) 65) (cons (quote ZED066) 66) (cons (quote ZED067) 67) (cons (quote ZED068) 68) (cons (quote ZED069) 69) (cons (quote ZED070) 70) (cons (quote ZED071) 71) (cons (quote ZED072) 72) (cons (quote ZED073) 73) (cons (quote ZED074) 74) (cons (quote ZED075) 75) (cons (quote ZED076) 76) (cons (quote ZED077) 77) (cons (quote ZED078) 78) (cons (quote ZED079) 79) (cons (quote ZED080) 80) (cons (quote ZED081) 81) (cons (quote ZED082) 82) (cons (quote ZED083) 83) (cons (quote ZED084) 84) (cons (quote ZED085) 85) (cons (quote ZED086) 86) (cons (quote ZED087) 87) (cons (quote ZED088) 88) (cons (quote ZED089) 89) (cons (quote ZED090) 90) (cons (quote ZED091) 91) (cons (quote ZED092) 92) (cons (quote ZED093) 93) (cons (quote ZED094) 94) (cons (quote ZED095) 95) (cons (quote ZED096) 96) (cons (quote ZED097) 97) (cons (quote ZED098) 98) (cons (quote ZED099) 99))))) (else err))) (define (ZEDby-four! sentences collect) (cond ((null? sentences) collect) (#t (ZEDby-four! (cddddr sentences) (cons (list (car sentences) (cadr sentences) (caddr sentences) (cadddr sentences)) collect))) (else err))) (define (ZEDby-four sentences) (cond (#t (reverse (ZEDby-four! sentences (quote ())))) (else err))) (define (ZEDby-three! sentences collect) (cond ((null? sentences) collect) (#t (ZEDby-three! (cdddr sentences) (cons (list (car sentences) (cadr sentences) (caddr sentences)) collect))) (else err))) (define (ZEDby-three sentences) (cond (#t (reverse (ZEDby-three! sentences (quote ())))) (else err))) (define (ZEDcharacter-less? character1 character2) (cond (#t (< (char->integer character1) (char->integer character2))) (else err))) (define (ZEDclause-arguments clause) (cond (#t (cadr clause)) (else err))) (define (ZEDclause-arguments-agree clause1 clause2) (cond ((equal? (ZEDclause-arguments clause1) (ZEDclause-arguments clause2)) (ZEDclause-arguments clause1)) (else err))) (define (ZEDclause-arity clause) (cond (#t (length (ZEDclause-arguments clause))) (else err))) (define (ZEDclause-body clause) (cond (#t (cddr clause)) (else err))) (define (ZEDclause-less? clause1 clause2) (cond (#t (ZEDsentence-less? (car clause1) (car clause2))) (else err))) (define (ZEDclause-name clause) (cond (#t (car clause)) (else err))) (define (ZEDclause-name-agree clause1 clause2) (cond ((eq? (ZEDclause-name clause1) (ZEDclause-name clause2)) (ZEDclause-name clause1)) (else err))) (define (ZEDcombine-all! program collect) (cond ((null? program) collect) ((null? (cdr program)) (cons (car program) collect)) ((eq? (ZEDclause-name (car program)) (ZEDclause-name (cadr program))) (ZEDcombine-all! (ZEDcombine-head-clauses program) collect)) (#t (ZEDcombine-all! (cdr program) (cons (car program) collect))) (else err))) (define (ZEDcombine-all program) (cond (#t (reverse (ZEDcombine-all! program (quote ())))) (else err))) (define (ZEDcombine-clauses clause1 clause2) (cond (#t (cons (ZEDclause-name-agree clause1 clause2) (cons (ZEDclause-arguments-agree clause1 clause2) (append (ZEDclause-body clause1) (ZEDclause-body clause2))))) (else err))) (define (ZEDcombine-head-clauses program) (cond (#t (cons (ZEDcombine-clauses (car program) (cadr program)) (cddr program))) (else err))) (define (ZEDcombine-program-clauses program) (cond (#t (ZEDcombine-all (ZEDready-program program))) (else err))) (define (ZEDcomp!) (cond (#t (ZEDcomp!a (ZEDcombine-program-clauses (ZEDby-three (ZEDread-sentences (ZEDdiscard-comments (ZEDfunction-sort (ZEDsentences (ZEDleading-newline (ZEDspace-newline (ZEDtab-replace (ZEDnewline-space-tab-repeats (ZEDnewline-space (ZEDfilter ZEDnot-return? (ZEDreplace-trailing-white-space (ZEDread-all)))))))))))))))) (else err))) (define (ZEDcomp!a combined) (cond (#t (ZEDcomp!aa (ZEDprogramize combined (ZEDarity-hash combined)))) (else err))) (define (ZEDcomp!aa programized) (cond (#t (write programized)) (else err))) (define (ZEDcomp) (cond (#t (ZEDcomp!)) (else err))) (define (ZEDcondefy! expressions collect) (cond ((null? expressions) collect) (#t (ZEDcondefy! (cddr expressions) (cons (append (car expressions) (cadr expressions)) collect))) (else err))) (define (ZEDcondefy expressions) (cond (#t (reverse (ZEDcondefy! expressions (quote ())))) (else err))) (define (ZEDcons ZEDvalue1 ZEDvalue2) (cond (#t (cons ZEDvalue1 ZEDvalue2)) (else err))) (define (ZEDcount ZEDnumber) (cond (#t (cons (delay ZEDnumber) (delay (ZEDcount (ZED+ ZEDnumber 1))))) (else err))) (define (ZEDcount-by ZEDstep ZEDnumber) (cond (#t (cons (delay ZEDnumber) (delay (ZEDcount-by ZEDstep (ZED+ ZEDnumber ZEDstep))))) (else err))) (define (ZEDdelay-wrap expression) (cond (#t (list (quote delay) expression)) (else err))) (define (ZEDdigit? character) (cond (#t (or (eqv? #\0 character) (eqv? #\1 character) (eqv? #\2 character) (eqv? #\3 character) (eqv? #\4 character) (eqv? #\5 character) (eqv? #\6 character) (eqv? #\7 character) (eqv? #\8 character) (eqv? #\9 character))) (else err))) (define (ZEDdiscard-comments! program collect) (cond ((null? program) collect) (#t (ZEDdiscard-comments! (cddddr program) (cons (cadddr program) (cons (caddr program) (cons (car program) collect))))) (else err))) (define (ZEDdiscard-comments program) (cond (#t (reverse (ZEDdiscard-comments! program (quote ())))) (else err))) (define (ZEDdr! value) (cond ((pair? value) (ZEDmp ZEDdr! (ZEDfirst 64 value))) (#t value) (else err))) (define (ZEDdr value) (cond (#t (begin (display (ZEDpr (ZEDdr! value))) (newline) (newline) value)) (else err))) (define (ZEDdrr value) (cond (#t (begin (display (ZEDpr value)) (newline) (newline) value)) (else err))) (define (ZEDfalse? noun-list) (cond (#t (equal? noun-list (list ## #\f #\a #\l #\s #\e))) (else err))) (define (ZEDfi function list) (cond ((null? list) (quote ())) ((function (if (promise? (car list)) (force (car list)) (car list))) (cons (delay (if (promise? (car list)) (force (car list)) (car list))) (delay (ZEDfi function (if (promise? (cdr list)) (force (cdr list)) (cdr list)))))) (#t (ZEDfi function (if (promise? (cdr list)) (force (cdr list)) (cdr list)))) (else err))) (define (ZEDfilter! predicate list collect) (cond ((null? list) collect) ((predicate (car list)) (ZEDfilter! predicate (cdr list) (cons (car list) collect))) (#t (ZEDfilter! predicate (cdr list) collect)) (else err))) (define (ZEDfilter predicate list) (cond (#t (reverse (ZEDfilter! predicate list (quote ())))) (else err))) (define (ZEDfirst! integer list collect) (cond ((or (zero? integer) (null? list)) (reverse collect)) ((not (pair? list)) (reverse (cons list collect))) ((> integer 0) (ZEDfirst! (- integer 1) (if (promise? (cdr list)) (force (cdr list)) (cdr list)) (cons (if (promise? (car list)) (force (car list)) (car list)) collect))) (else err))) (define (ZEDfirst integer list) (cond ((not (pair? list)) list) (#t (ZEDfirst! integer list (quote ()))) (else err))) (define (ZEDflatten! ZEDlist ZEDsub-list-found? ZEDcollect) (cond ((and (ZEDnull? ZEDlist) (ZEDnot ZEDsub-list-found?)) (ZEDreverse ZEDcollect)) ((ZEDnull? ZEDlist) (ZEDflatten! (ZEDreverse ZEDcollect) #f (quote ()))) ((ZEDnot (ZEDpair? ZEDlist)) (ZEDflatten! (quote ()) ZEDsub-list-found? (ZEDcons ZEDlist ZEDcollect))) ((ZEDpair? (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist))) (ZEDflatten! (if (promise? (cdr ZEDlist)) (force (cdr ZEDlist)) (cdr ZEDlist)) #t (ZEDcons (if (promise? (cdr (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist)))) (force (cdr (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist)))) (cdr (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist)))) (ZEDcons (if (promise? (car (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist)))) (force (car (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist)))) (car (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist)))) ZEDcollect)))) ((ZEDnull? (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist))) (ZEDflatten! (if (promise? (cdr ZEDlist)) (force (cdr ZEDlist)) (cdr ZEDlist)) ZEDsub-list-found? ZEDcollect)) (#t (ZEDflatten! (if (promise? (cdr ZEDlist)) (force (cdr ZEDlist)) (cdr ZEDlist)) ZEDsub-list-found? (ZEDcons (if (promise? (car ZEDlist)) (force (car ZEDlist)) (car ZEDlist)) ZEDcollect))) (else err))) (define (ZEDflatten ZEDlist) (cond (#t (ZEDflatten! ZEDlist #f (quote ()))) (else err))) (define (ZEDfor-each ZEDeffect ZEDlist) (cond (#t (for-each ZEDeffect ZEDlist)) (else err))) (define (ZEDfunction expression) (cond (#t (caar expression)) (else err))) (define (ZEDfunction-sort sentences) (cond (#t (ZEDrd (quote ()) append (ZEDsort ZEDclause-less? (ZEDby-four sentences)))) (else err))) (define (ZEDfunctionize clause arity-hash) (cond (#t (list (quote define) (cons (ZEDclause-name clause) (ZEDclause-arguments clause)) (cons (quote cond) (append (ZEDcondefy (ZEDmap-with ZEDschemefy (ZEDclause-body clause) arity-hash)) (list (list (quote else) (quote err))))))) (else err))) (define (ZEDgather-count?! candidate) (cond (#t (and (= 6 (length candidate)) (eqv? #\Z (car candidate)) (eqv? #\E (cadr candidate)) (eqv? #\D (caddr candidate)) (eqv? #\0 (cadddr candidate)) (ZEDdigit? (car (cddddr candidate))) (ZEDdigit? (cadr (cddddr candidate))))) (else err))) (define (ZEDgather-count? symbol) (cond (#t (ZEDgather-count?! (string->list (symbol->string symbol)))) (else err))) (define (ZEDgather-noun sentence) (cond ((null? sentence) (quote ())) ((eqv? #\space (car sentence)) (quote ())) (#t (cons (car sentence) (ZEDgather-noun (cdr sentence)))) (else err))) (define (ZEDgather-verb sentence) (cond ((eqv? #) (car sentence)) (quote ())) (#t (cons (car sentence) (ZEDgather-verb (cdr sentence)))) (else err))) (define (ZEDgr garbage value) (cond (#t (begin (ZEDdr garbage) value)) (else err))) (define (ZEDgrr garbage value) (cond (#t (begin (ZEDdrr garbage) value)) (else err))) (define (ZEDleading-newline program) (cond ((null? program) (quote ())) ((eqv? #\newline (car program)) (cdr program)) (#t program) (else err))) (define (ZEDliteral? literal-list) (cond (#t (eqv? #" (car literal-list))) (else err))) (define (ZEDmake-ZED ZED-list) (cond ((equal? ZED-list (list #\e #\r #\r)) "'err") ((equal? ZED-list (list #\n #\i #\l)) "'()") ((equal? ZED-list (list #\a #\n #\d)) "and") ((equal? ZED-list (list #\o #\r)) "or") ((equal? ZED-list (list #\q #\u #\o #\t #\e)) "quote") ((equal? ZED-list (list #\s #\e)) "begin") (#t (list->string (append (list #\Z #\E #\D) ZED-list))) (else err))) (define (ZEDmake-character noun-list) (cond (#t (list->string (cons ## (cons # +(cdr noun-list))))) (else err))) (define (ZEDmake-exact exact-list) (cond (#t (list->string (append (list ## #\e) exact-list))) (else err))) (define (ZEDmake-literal literal-list) (cond (#t (list->string (cdr (reverse (cdr (reverse literal-list)))))) (else err))) (define (ZEDmake-number-character noun-list) (cond (#t (list->string (list ## # +(integer->char (string->number (list->string (cddr noun-list))))))) (else err))) (define (ZEDmap-with! function list extra collect) (cond ((null? list) collect) (#t (ZEDmap-with! function (cdr list) extra (cons (function (car list) extra) collect))) (else err))) (define (ZEDmap-with function list extra) (cond (#t (reverse (ZEDmap-with! function list extra (quote ())))) (else err))) (define (ZEDmerge! comparator list1 list2 collect) (cond ((null? list2) (append (reverse collect) list1)) ((null? list1) (append (reverse collect) list2)) ((comparator (car list2) (car list1)) (ZEDmerge! comparator list1 (cdr list2) (cons (car list2) collect))) (#t (ZEDmerge! comparator (cdr list1) list2 (cons (car list1) collect))) (else err))) (define (ZEDmerge comparator list1 list2) (cond (#t (ZEDmerge! comparator list1 list2 (quote ()))) (else err))) (define (ZEDmp function list) (cond ((null? list) (quote ())) ((pair? list) (cons (delay (function (if (promise? (car list)) (force (car list)) (car list)))) (delay (ZEDmp function (if (promise? (cdr list)) (force (cdr list)) (cdr list)))))) (#t (function list)) (else err))) (define (ZEDnewline-space! program) (cond (#t (cons #\newline (ZEDnewline-space!a program))) (else err))) (define (ZEDnewline-space!a program) (cond (#t (ZEDnewline-space!aa program (reverse (ZEDnewline-space!ab program (quote ()))))) (else err))) (define (ZEDnewline-space!aa program transformed) (cond ((equal? program transformed) program) (#t (ZEDnewline-space!a transformed)) (else err))) (define (ZEDnewline-space!ab program collect) (cond ((null? program) collect) ((null? (cdr program)) (cons (car program) collect)) ((and (eqv? #\newline (car program)) (or (eqv? #\space (cadr program)) (eqv? #\ht (cadr program)))) (ZEDnewline-space!ab (cdr program) collect)) (#t (ZEDnewline-space!ab (cdr program) (cons (car program) collect))) (else err))) (define (ZEDnewline-space program) (cond (#t (ZEDnewline-space! program)) (else err))) (define (ZEDnewline-space-tab-repeats! program collect) (cond ((or (null? program) (null? (cdr program))) (append program collect)) ((and (eqv? #\newline (car program)) (eqv? #\newline (cadr program))) (ZEDnewline-space-tab-repeats! (cdr program) collect)) ((and (or (eqv? #\space (car program)) (eqv? #\ht (car program))) (or (eqv? #\space (cadr program)) (eqv? #\ht (cadr program)))) (ZEDnewline-space-tab-repeats! (cdr program) collect)) (#t (ZEDnewline-space-tab-repeats! (cdr program) (cons (car program) collect))) (else err))) (define (ZEDnewline-space-tab-repeats program) (cond (#t (reverse (ZEDnewline-space-tab-repeats! program (quote ())))) (else err))) (define (ZEDnewlines clauses) (cond (#t (ZEDadd-between-ra (ZEDmap-with ZEDadd-between-ra clauses (list #\newline)) (list (list #\newline #\newline)))) (else err))) (define (ZEDnormal-character? noun-list) (cond (#t (eqv? (car noun-list) ##)) (else err))) (define (ZEDnot ZEDvalue) (cond (#t (not ZEDvalue)) (else err))) (define (ZEDnot-return? character) (cond (#t (not (eqv? #\cr character))) (else err))) (define (ZEDnoun! noun-list number?) (cond (number? (ZEDmake-exact noun-list)) ((ZEDliteral? noun-list) (ZEDmake-literal noun-list)) ((ZEDtrue? noun-list) "#t") ((ZEDfalse? noun-list) "#f") ((ZEDnumber-character? noun-list) (ZEDmake-number-character noun-list)) ((ZEDnormal-character? noun-list) (ZEDmake-character noun-list)) (#t (ZEDmake-ZED noun-list)) (else err))) (define (ZEDnoun noun-list) (cond (#t (ZEDnoun! noun-list (string->number (list->string noun-list)))) (else err))) (define (ZEDnull? ZEDvalue) (cond (#t (null? ZEDvalue)) (else err))) (define (ZEDnumber-character? noun-list) (cond (#t (and (eqv? (car noun-list) ##) (eqv? (cadr noun-list) #\0) (not (null? (cddr noun-list))))) (else err))) (define (ZEDpair? ZEDvalue) (cond (#t (pair? ZEDvalue)) (else err))) (define (ZEDpop stack) (cond (#t (cdr stack)) (else err))) (define (ZEDpr! value output-string) (cond (#t (begin (display (ZEDpr!a value (quote ())) output-string) (ZEDpr!b output-string (get-output-string output-string)))) (else err))) (define (ZEDpr!a value collect) (cond ((char? value) (ZEDpr!aa (list->string (list ## value)) collect)) ((string? value) (ZEDpr!aa (string-append """ value """) collect)) ((symbol? value) (ZEDpr!aa (symbol->string value) collect)) ((number? value) (ZEDpr!aa (number->string value) collect)) ((and (boolean? value) value) (ZEDpr!aa "#true" collect)) ((boolean? value) (ZEDpr!aa "#false" collect)) ((null? value) (reverse collect)) (#t (ZEDpr!a (if (promise? (cdr value)) (force (cdr value)) (cdr value)) (cons (ZEDpr!a (if (promise? (car value)) (force (car value)) (car value)) (quote ())) collect))) (else err))) (define (ZEDpr!aa string collect) (cond ((null? collect) string) (#t (reverse (cons string (cons "." collect)))) (else err))) (define (ZEDpr!b output-string value) (cond (#t (begin (close-output-port output-string) value)) (else err))) (define (ZEDpr value) (cond (#t (ZEDpr! value (open-output-string))) (else err))) (define (ZEDprogramize program arity-hash) (cond (#t (cons (quote begin) (ZEDmap-with ZEDfunctionize program arity-hash))) (else err))) (define (ZEDpush object stack) (cond (#t (cons object stack)) (else err))) (define (ZEDrd! function list) (cond ((null? (if (promise? (cdr list)) (force (cdr list)) (cdr list))) (if (promise? (car list)) (force (car list)) (car list))) (#t (ZEDrd! function (cons (function (if (promise? (car (if (promise? (cdr list)) (force (cdr list)) (cdr list)))) (force (car (if (promise? (cdr list)) (force (cdr list)) (cdr list)))) (car (if (promise? (cdr list)) (force (cdr list)) (cdr list)))) (if (promise? (car list)) (force (car list)) (car list))) (if (promise? (cdr (if (promise? (cdr list)) (force (cdr list)) (cdr list)))) (force (cdr (if (promise? (cdr list)) (force (cdr list)) (cdr list)))) (cdr (if (promise? (cdr list)) (force (cdr list)) (cdr list))))))) (else err))) (define (ZEDrd final function list) (cond (#t (ZEDrd! function (cons final (reverse list)))) (else err))) (define (ZEDread-all! collect) (cond (#t (ZEDread-all!a (read-char) collect)) (else err))) (define (ZEDread-all!a character collect) (cond ((eof-object? character) collect) (#t (ZEDread-all! (cons character collect))) (else err))) (define (ZEDread-all) (cond (#t (reverse (ZEDread-all! (quote ())))) (else err))) (define (ZEDread-sentence!a sentence collect) (cond ((null? sentence) collect) ((eqv? #\space (car sentence)) (ZEDread-sentence!a (cdr sentence) collect)) ((eqv? #( (car sentence)) (ZEDread-sentence!aa sentence (ZEDgather-verb (cdr sentence)) collect)) (#t (ZEDread-sentence!ab sentence (ZEDgather-noun sentence) collect)) (else err))) (define (ZEDread-sentence!aa sentence gather-verb collect) (cond (#t (ZEDread-sentence!a (ZEDtails (+ 2 (length gather-verb)) sentence) (cons (ZEDverb gather-verb) collect))) (else err))) (define (ZEDread-sentence!ab sentence gather-noun collect) (cond (#t (ZEDread-sentence!a (ZEDtails (length gather-noun) sentence) (cons (ZEDnoun gather-noun) collect))) (else err))) (define (ZEDread-sentence!b list output-string) (cond (#t (begin (display list output-string) (ZEDread-sentence!ba output-string (get-output-string output-string)))) (else err))) (define (ZEDread-sentence!ba output-string get-output-string) (cond (#t (begin (close-output-port output-string) (ZEDread-sentence!baa (open-input-string get-output-string)))) (else err))) (define (ZEDread-sentence!baa input-string) (cond (#t (ZEDread-sentence!baaa input-string (read input-string))) (else err))) (define (ZEDread-sentence!baaa input-string answer) (cond (#t (begin (close-input-port input-string) answer)) (else err))) (define (ZEDread-sentence sentence) (cond (#t (ZEDread-sentence!b (reverse (ZEDread-sentence!a sentence (quote ()))) (open-output-string))) (else err))) (define (ZEDread-sentences sentences) (cond (#t (map ZEDread-sentence sentences)) (else err))) (define (ZEDready-clause clause) (cond (#t (cons (caaar clause) (cons (cdar clause) (cdr clause)))) (else err))) (define (ZEDready-program program) (cond (#t (map ZEDready-clause program)) (else err))) (define (ZEDreplace-trailing-white-space! program) (cond ((null? program) (quote ())) ((or (eqv? (car program) #\space) (eqv? (car program) #\ht) (eqv? (car program) #\cr) (eqv? (car program) #\newline)) (ZEDreplace-trailing-white-space! (cdr program))) (#t (cons #\newline program)) (else err))) (define (ZEDreplace-trailing-white-space program) (cond (#t (reverse (ZEDreplace-trailing-white-space! (reverse program)))) (else err))) (define (ZEDreverse ZEDlist) (cond (#t (reverse ZEDlist)) (else err))) (define (ZEDschemefy! expression arity-hash stack) (cond ((null? expression) (ZEDtop stack)) ((ZEDapplication? expression) (ZEDschemefy!a expression arity-hash stack (ZEDfunction expression))) (#t (ZEDschemefy! (cdr expression) arity-hash (ZEDpush (car expression) stack))) (else err))) (define (ZEDschemefy!a expression arity-hash stack function) (cond (#t (ZEDschemefy!aa expression arity-hash stack function (ZEDarity arity-hash function))) (else err))) (define (ZEDschemefy!aa expression arity-hash stack function arity) (cond ((ZEDgather-count? function) (ZEDschemefy! (cdr expression) arity-hash (ZEDpush (ZEDfirst arity stack) (ZEDtails arity stack)))) ((eq? function (quote ZED1)) (ZEDschemefy! (cdr expression) arity-hash (ZEDpush (list (quote if) (list (quote promise?) (cons (quote car) (ZEDfirst arity stack))) (list (quote force) (cons (quote car) (ZEDfirst arity stack))) (cons (quote car) (ZEDfirst arity stack))) (ZEDtails arity stack)))) ((eq? function (quote ZED!)) (ZEDschemefy! (cdr expression) arity-hash (ZEDpush (list (quote if) (list (quote promise?) (cons (quote cdr) (ZEDfirst arity stack))) (list (quote force) (cons (quote cdr) (ZEDfirst arity stack))) (cons (quote cdr) (ZEDfirst arity stack))) (ZEDtails arity stack)))) ((eq? function (quote ZEDc)) (ZEDschemefy! (cdr expression) arity-hash (ZEDpush (cons (quote cons) (map ZEDdelay-wrap (ZEDfirst arity stack))) (ZEDtails arity stack)))) (#t (ZEDschemefy! (cdr expression) arity-hash (ZEDpush (cons function (ZEDfirst arity stack)) (ZEDtails arity stack)))) (else err))) (define (ZEDschemefy expression arity-hash) (cond (#t (list (ZEDschemefy! (reverse expression) arity-hash (ZEDstack)))) (else err))) (define (ZEDsentence-less? sentence1 sentence2) (cond ((null? sentence2) #f) ((null? sentence1) #t) ((ZEDcharacter-less? (car sentence1) (car sentence2)) #t) ((ZEDcharacter-less? (car sentence2) (car sentence1)) #f) (#t (ZEDsentence-less? (cdr sentence1) (cdr sentence2))) (else err))) (define (ZEDsentences! program collect1 collect2) (cond ((null? program) collect2) ((eqv? #\newline (car program)) (ZEDsentences! (cdr program) (quote ()) (cons (reverse collect1) collect2))) (#t (ZEDsentences! (cdr program) (cons (car program) collect1) collect2)) (else err))) (define (ZEDsentences program) (cond (#t (reverse (ZEDsentences! program (quote ()) (quote ())))) (else err))) (define (ZEDsort!a jumble) (cond (#t (map list jumble)) (else err))) (define (ZEDsort!b comparator jumble) (cond ((null? jumble) (quote ())) ((null? (cdr jumble)) jumble) (#t (ZEDsort!b comparator (cons (ZEDmerge comparator (car jumble) (cadr jumble)) (ZEDsort!b comparator (cddr jumble))))) (else err))) (define (ZEDsort comparator jumble) (cond (#t (car (ZEDsort!b comparator (ZEDsort!a jumble)))) (else err))) (define (ZEDspace-newline! program collect) (cond ((or (null? program) (null? (cdr program))) (append program collect)) ((and (eqv? #\space (car program)) (eqv? #\newline (cadr program))) (ZEDspace-newline! (cdr program) collect)) (#t (ZEDspace-newline! (cdr program) (cons (car program) collect))) (else err))) (define (ZEDspace-newline program) (cond (#t (reverse (ZEDspace-newline! program (quote ())))) (else err))) (define (ZEDstack) (cond (#t (quote ())) (else err))) (define (ZEDtab-replace! program collect) (cond ((null? program) collect) ((eqv? #\ht (car program)) (ZEDtab-replace! (cdr program) (cons #\space collect))) (#t (ZEDtab-replace! (cdr program) (cons (car program) collect))) (else err))) (define (ZEDtab-replace program) (cond (#t (reverse (ZEDtab-replace! program (quote ())))) (else err))) (define (ZEDtails number list) (cond ((null? list) (quote ())) ((zero? number) list) ((> number 0) (ZEDtails (- number 1) (cdr list))) (else err))) (define (ZEDtop stack) (cond (#t (car stack)) (else err))) (define (ZEDtrue? noun-list) (cond (#t (equal? noun-list (list ## #\t #\r #\u #\e))) (else err))) (define (ZEDverb verb-list) (cond ((ZEDliteral? verb-list) (list (ZEDmake-literal verb-list))) (#t (list (ZEDmake-ZED verb-list))) (else err))) (define (ZEDwrite-all program) (cond ((null? program) (quote err)) (#t (ZEDwrite-all (begin (write-char (car program)) (cdr program)))) (else err))) (define (ZEDzed->scheme! value collect) (cond ((null? value) (reverse collect)) (#t (ZEDzed->scheme! (if (promise? (cdr value)) (force (cdr value)) (cdr value)) (cons (ZEDzed->scheme (if (promise? (car value)) (force (car value)) (car value))) collect))) (else err))) (define (ZEDzed->scheme value) (cond ((not (pair? value)) value) (#t (ZEDzed->scheme! value (quote ()))) (else err)))) (ZEDcomp) Language author on RC: [[User:Zelah|Zelah]] ([[User_talk:Zelah|talk]] | [[Special:Contributions/Zelah|contribs]]) . \ No newline at end of file diff --git a/Lang/Zig/15-puzzle-solver b/Lang/Zig/15-puzzle-solver new file mode 120000 index 0000000000..31e2e98f6a --- /dev/null +++ b/Lang/Zig/15-puzzle-solver @@ -0,0 +1 @@ +../../Task/15-puzzle-solver/Zig \ No newline at end of file diff --git a/Lang/Zig/2048 b/Lang/Zig/2048 new file mode 120000 index 0000000000..d2ac81be16 --- /dev/null +++ b/Lang/Zig/2048 @@ -0,0 +1 @@ +../../Task/2048/Zig \ No newline at end of file diff --git a/Lang/Zig/24-game b/Lang/Zig/24-game new file mode 120000 index 0000000000..7b40225753 --- /dev/null +++ b/Lang/Zig/24-game @@ -0,0 +1 @@ +../../Task/24-game/Zig \ No newline at end of file diff --git a/Lang/Zig/Anti-primes b/Lang/Zig/Anti-primes new file mode 120000 index 0000000000..bde3882591 --- /dev/null +++ b/Lang/Zig/Anti-primes @@ -0,0 +1 @@ +../../Task/Anti-primes/Zig \ No newline at end of file diff --git a/Lang/Zig/Canonicalize-CIDR b/Lang/Zig/Canonicalize-CIDR new file mode 120000 index 0000000000..792c271f68 --- /dev/null +++ b/Lang/Zig/Canonicalize-CIDR @@ -0,0 +1 @@ +../../Task/Canonicalize-CIDR/Zig \ No newline at end of file diff --git a/Lang/Zig/Convex-hull b/Lang/Zig/Convex-hull new file mode 120000 index 0000000000..bb63712423 --- /dev/null +++ b/Lang/Zig/Convex-hull @@ -0,0 +1 @@ +../../Task/Convex-hull/Zig \ No newline at end of file diff --git a/Lang/Zig/De-Bruijn-sequences b/Lang/Zig/De-Bruijn-sequences new file mode 120000 index 0000000000..1e82ee12c7 --- /dev/null +++ b/Lang/Zig/De-Bruijn-sequences @@ -0,0 +1 @@ +../../Task/De-Bruijn-sequences/Zig \ No newline at end of file diff --git a/Lang/Zig/Dijkstras-algorithm b/Lang/Zig/Dijkstras-algorithm new file mode 120000 index 0000000000..e85779f749 --- /dev/null +++ b/Lang/Zig/Dijkstras-algorithm @@ -0,0 +1 @@ +../../Task/Dijkstras-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Execute-a-Markov-algorithm b/Lang/Zig/Execute-a-Markov-algorithm new file mode 120000 index 0000000000..5b70cd7b50 --- /dev/null +++ b/Lang/Zig/Execute-a-Markov-algorithm @@ -0,0 +1 @@ +../../Task/Execute-a-Markov-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Fibonacci-sequence b/Lang/Zig/Fibonacci-sequence new file mode 120000 index 0000000000..8c7ee19f72 --- /dev/null +++ b/Lang/Zig/Fibonacci-sequence @@ -0,0 +1 @@ +../../Task/Fibonacci-sequence/Zig \ No newline at end of file diff --git a/Lang/Zig/Find-the-missing-permutation b/Lang/Zig/Find-the-missing-permutation new file mode 120000 index 0000000000..720e08365d --- /dev/null +++ b/Lang/Zig/Find-the-missing-permutation @@ -0,0 +1 @@ +../../Task/Find-the-missing-permutation/Zig \ No newline at end of file diff --git a/Lang/Zig/Floyd-Warshall-algorithm b/Lang/Zig/Floyd-Warshall-algorithm new file mode 120000 index 0000000000..e20cfd03e2 --- /dev/null +++ b/Lang/Zig/Floyd-Warshall-algorithm @@ -0,0 +1 @@ +../../Task/Floyd-Warshall-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Latin-Squares-in-reduced-form b/Lang/Zig/Latin-Squares-in-reduced-form new file mode 120000 index 0000000000..4ae8de3ec8 --- /dev/null +++ b/Lang/Zig/Latin-Squares-in-reduced-form @@ -0,0 +1 @@ +../../Task/Latin-Squares-in-reduced-form/Zig \ No newline at end of file diff --git a/Lang/Zig/Move-to-front-algorithm b/Lang/Zig/Move-to-front-algorithm new file mode 120000 index 0000000000..820f21fe3e --- /dev/null +++ b/Lang/Zig/Move-to-front-algorithm @@ -0,0 +1 @@ +../../Task/Move-to-front-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Natural-sorting b/Lang/Zig/Natural-sorting new file mode 120000 index 0000000000..ce3fd8d2e1 --- /dev/null +++ b/Lang/Zig/Natural-sorting @@ -0,0 +1 @@ +../../Task/Natural-sorting/Zig \ No newline at end of file diff --git a/Lang/Zig/P-Adic-numbers-basic b/Lang/Zig/P-Adic-numbers-basic new file mode 120000 index 0000000000..7be77909db --- /dev/null +++ b/Lang/Zig/P-Adic-numbers-basic @@ -0,0 +1 @@ +../../Task/P-Adic-numbers-basic/Zig \ No newline at end of file diff --git a/Lang/Zig/P-Adic-square-roots b/Lang/Zig/P-Adic-square-roots new file mode 120000 index 0000000000..bf2f9425e2 --- /dev/null +++ b/Lang/Zig/P-Adic-square-roots @@ -0,0 +1 @@ +../../Task/P-Adic-square-roots/Zig \ No newline at end of file diff --git a/Lang/Zig/Parsing-RPN-calculator-algorithm b/Lang/Zig/Parsing-RPN-calculator-algorithm new file mode 120000 index 0000000000..64d52e74e9 --- /dev/null +++ b/Lang/Zig/Parsing-RPN-calculator-algorithm @@ -0,0 +1 @@ +../../Task/Parsing-RPN-calculator-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Parsing-Shunting-yard-algorithm b/Lang/Zig/Parsing-Shunting-yard-algorithm new file mode 120000 index 0000000000..36cb3a3892 --- /dev/null +++ b/Lang/Zig/Parsing-Shunting-yard-algorithm @@ -0,0 +1 @@ +../../Task/Parsing-Shunting-yard-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Quickselect-algorithm b/Lang/Zig/Quickselect-algorithm new file mode 120000 index 0000000000..7dbb81ef78 --- /dev/null +++ b/Lang/Zig/Quickselect-algorithm @@ -0,0 +1 @@ +../../Task/Quickselect-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Quine b/Lang/Zig/Quine new file mode 120000 index 0000000000..20f1f12898 --- /dev/null +++ b/Lang/Zig/Quine @@ -0,0 +1 @@ +../../Task/Quine/Zig \ No newline at end of file diff --git a/Lang/Zig/SHA-1 b/Lang/Zig/SHA-1 new file mode 120000 index 0000000000..374af24054 --- /dev/null +++ b/Lang/Zig/SHA-1 @@ -0,0 +1 @@ +../../Task/SHA-1/Zig \ No newline at end of file diff --git a/Lang/Zig/Solve-a-Holy-Knights-tour b/Lang/Zig/Solve-a-Holy-Knights-tour new file mode 120000 index 0000000000..b0fe3fcb9a --- /dev/null +++ b/Lang/Zig/Solve-a-Holy-Knights-tour @@ -0,0 +1 @@ +../../Task/Solve-a-Holy-Knights-tour/Zig \ No newline at end of file diff --git a/Lang/Zig/Sorting-algorithms-Patience-sort b/Lang/Zig/Sorting-algorithms-Patience-sort new file mode 120000 index 0000000000..a696e81abf --- /dev/null +++ b/Lang/Zig/Sorting-algorithms-Patience-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Patience-sort/Zig \ No newline at end of file diff --git a/Lang/Zig/Sorting-algorithms-Strand-sort b/Lang/Zig/Sorting-algorithms-Strand-sort new file mode 120000 index 0000000000..67361c524c --- /dev/null +++ b/Lang/Zig/Sorting-algorithms-Strand-sort @@ -0,0 +1 @@ +../../Task/Sorting-algorithms-Strand-sort/Zig \ No newline at end of file diff --git a/Lang/Zig/Strassens-algorithm b/Lang/Zig/Strassens-algorithm new file mode 120000 index 0000000000..f02a6cb05a --- /dev/null +++ b/Lang/Zig/Strassens-algorithm @@ -0,0 +1 @@ +../../Task/Strassens-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Sutherland-Hodgman-polygon-clipping b/Lang/Zig/Sutherland-Hodgman-polygon-clipping new file mode 120000 index 0000000000..2e08ab9fc7 --- /dev/null +++ b/Lang/Zig/Sutherland-Hodgman-polygon-clipping @@ -0,0 +1 @@ +../../Task/Sutherland-Hodgman-polygon-clipping/Zig \ No newline at end of file diff --git a/Lang/Zig/Thue-Morse b/Lang/Zig/Thue-Morse new file mode 120000 index 0000000000..514eeceeed --- /dev/null +++ b/Lang/Zig/Thue-Morse @@ -0,0 +1 @@ +../../Task/Thue-Morse/Zig \ No newline at end of file diff --git a/Lang/Zig/Tonelli-Shanks-algorithm b/Lang/Zig/Tonelli-Shanks-algorithm new file mode 120000 index 0000000000..364e6278fd --- /dev/null +++ b/Lang/Zig/Tonelli-Shanks-algorithm @@ -0,0 +1 @@ +../../Task/Tonelli-Shanks-algorithm/Zig \ No newline at end of file diff --git a/Lang/Zig/Y-combinator b/Lang/Zig/Y-combinator new file mode 120000 index 0000000000..1478dbbdb7 --- /dev/null +++ b/Lang/Zig/Y-combinator @@ -0,0 +1 @@ +../../Task/Y-combinator/Zig \ No newline at end of file diff --git a/Task/100-doors/BQN/100-doors-4.bqn b/Task/100-doors/BQN/100-doors-4.bqn new file mode 100644 index 0000000000..cfab61e191 --- /dev/null +++ b/Task/100-doors/BQN/100-doors-4.bqn @@ -0,0 +1,3 @@ +F ← {1+ / 2| +˝ 0= |⌜˜ 1+↕𝕩} +F 100 +# ⟨ 1 4 9 16 25 36 49 64 81 100 ⟩ diff --git a/Task/100-doors/BQN/100-doors-5.bqn b/Task/100-doors/BQN/100-doors-5.bqn new file mode 100644 index 0000000000..b78e4f3de6 --- /dev/null +++ b/Task/100-doors/BQN/100-doors-5.bqn @@ -0,0 +1,3 @@ +F ← {ט1+↕⌊√𝕩} +F 100 +# ⟨ 1 4 9 16 25 36 49 64 81 100 ⟩ diff --git a/Task/100-doors/EasyLang/100-doors.easy b/Task/100-doors/EasyLang/100-doors.easy index c34fdbedc2..ba261e6f52 100644 --- a/Task/100-doors/EasyLang/100-doors.easy +++ b/Task/100-doors/EasyLang/100-doors.easy @@ -7,7 +7,5 @@ for p = 1 to 100 . . for i = 1 to 100 - if d[i] = 1 - print i - . + if d[i] = 1 : write i & " " . diff --git a/Task/100-doors/Elena/100-doors.elena b/Task/100-doors/Elena/100-doors.elena index 6e1a619ede..dd7db1e5c7 100644 --- a/Task/100-doors/Elena/100-doors.elena +++ b/Task/100-doors/Elena/100-doors.elena @@ -14,8 +14,8 @@ public program() for(int i := 0; i < 100; i++) { - console.printLine("Door #",i + 1," :",Doors[i].iif("Open","Closed")) + Console.printLine("Door #",i + 1," :",Doors[i].iif("Open","Closed")) }; - console.readChar() + Console.readChar() } diff --git a/Task/100-doors/Excel/100-doors-4.excel b/Task/100-doors/Excel/100-doors-4.excel new file mode 100644 index 0000000000..619e31a91c --- /dev/null +++ b/Task/100-doors/Excel/100-doors-4.excel @@ -0,0 +1 @@ +=LET(i, SEQUENCE(100), root, SQRT(i), "Door " & i & ": " & IF(root = INT(root), "open", "close")) diff --git a/Task/100-doors/OPL/100-doors.opl b/Task/100-doors/OPL/100-doors.opl new file mode 100644 index 0000000000..e5026a3076 --- /dev/null +++ b/Task/100-doors/OPL/100-doors.opl @@ -0,0 +1,32 @@ +REM Author.....: Eva Broccoli +REM Date.......: 23 May 2025 +REM Description: OPL solution for "100 doors" task on https://rosettacode.org +REM Tested with: Psion Series 3a & Series 5 +REM Contact....: eva.klassen@kittymail.com + +PROC main: + LOCAL door%(100),i%,j% + i%=1 + j%=1 + WHILE j%<101 + WHILE i%<101 + IF door%(i%)=0 + door%(i%)=1 + ELSE + door%(i%)=0 + ENDIF + i%=i%+j% + ENDWH + j%=j%+1 + i%=0+j% + ENDWH + PRINT "Open doors:", + i%=1 + WHILE i%<101 + IF door%(i%)=1 + PRINT i%, + ENDIF + i%=i%+1 + ENDWH + GET +ENDP diff --git a/Task/100-doors/Quackery/100-doors-1.quackery b/Task/100-doors/Quackery/100-doors-1.quackery new file mode 100644 index 0000000000..e3d105d0cd --- /dev/null +++ b/Task/100-doors/Quackery/100-doors-1.quackery @@ -0,0 +1,17 @@ + [ bit ^ ] is toggle ( f n --> f ) + + [ 0 + 100 times + [ i^ 1+ swap + 101 times + [ i^ toggle over step ] + nip ] ] is toggledoors ( --> f ) + + [ 100 times + [ 1 >> dup 1 & + if [ i^ 1+ echo sp ] ] + drop ] is echodoors ( f --> ) + + toggledoors + say " These doors are open: " echodoors cr + say " The rest are closed." cr diff --git a/Task/100-doors/Quackery/100-doors-2.quackery b/Task/100-doors/Quackery/100-doors-2.quackery new file mode 100644 index 0000000000..85074cd60f --- /dev/null +++ b/Task/100-doors/Quackery/100-doors-2.quackery @@ -0,0 +1 @@ + 10 times [ i^ 1+ 2 ** echo sp ] diff --git a/Task/100-doors/Quackery/100-doors.quackery b/Task/100-doors/Quackery/100-doors.quackery deleted file mode 100644 index 5577d1c6c4..0000000000 --- a/Task/100-doors/Quackery/100-doors.quackery +++ /dev/null @@ -1,22 +0,0 @@ -/O> [ bit ^ ] is toggle ( f n --> f ) -... -... [ 0 -... 100 times -... [ i^ 1+ swap -... 101 times -... [ i^ toggle over step ] -... nip ] ] is toggledoors ( --> f ) -... -... [ 100 times -... [ 1 >> dup 1 & -... if [ i^ 1+ echo sp ] ] -... drop ] is echodoors ( f --> ) -... -... toggledoors -... say " These doors are open: " echodoors cr -... say " The rest are closed." cr -... - These doors are open: 1 4 9 16 25 36 49 64 81 100 - The rest are closed. - -Stack empty. diff --git a/Task/100-doors/Tcl/100-doors-1.tcl b/Task/100-doors/Tcl/100-doors-1.tcl index 43badf3380..71a614db6d 100644 --- a/Task/100-doors/Tcl/100-doors-1.tcl +++ b/Task/100-doors/Tcl/100-doors-1.tcl @@ -1,11 +1,85 @@ -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]}] +#!/usr/bin/env tclsh + +# 100 doors + +proc seq { m n } { + set r {} + for {set i $m} {$i <= $n} {incr i} { + lappend r $i + } + return $r +} + +proc toggle {val a b} { + # expr has ternary operators + return [expr { + ${val} == ${a}? ${b} : + ${val} == ${b}? ${a} : + [error "bad value: ${val}"] + }] +} + +proc multiples {n max} { + set ret {} + set x $n + + # maximum multiple + set mid [expr $max / 2] + + if {$x>=$mid && $x<$max} { return $x } + + # calculate multiples + if {[expr $x <= $mid]} { + for {set i 1} {$i <= $max } {incr i} { + + set x [expr $i * $n] + + if {$x > $max} { break } + + lappend ret $x + } + } + + return $ret +} + +# states +array set state { + open "open" + closed "closed" + unknown "?" +} + +# ============================== +# start program + +# 100 doors +variable MAX 100 + +variable mid [expr int($MAX / 2)] + +variable Seq_100 [seq 1 $MAX] + +# initialize doors closed +foreach n $Seq_100 { + set door($n) $state(closed) +} + +# do for 1 .. 100 +foreach m $Seq_100 { + + set mults [multiples $m $MAX] + + foreach d $mults { + set door($d) [toggle $door($d) $state(open) $state(closed)] } } -for {set i 1} {$i <= $n} {incr i} { - puts [format "door %d is %s" $i [expr {[lindex $doors $i] ? "open" : "closed"}]] + +# output +foreach n $Seq_100 { + if { $door($n) eq $state(open) } { + puts stdout "$n: $door($n)" + } } + +# end diff --git a/Task/100-doors/Tcl/100-doors-2.tcl b/Task/100-doors/Tcl/100-doors-2.tcl index df7078d750..43badf3380 100644 --- a/Task/100-doors/Tcl/100-doors-2.tcl +++ b/Task/100-doors/Tcl/100-doors-2.tcl @@ -1,8 +1,11 @@ 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 +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 [lindex $doors $i]] + puts [format "door %d is %s" $i [expr {[lindex $doors $i] ? "open" : "closed"}]] } diff --git a/Task/100-doors/Tcl/100-doors-3.tcl b/Task/100-doors/Tcl/100-doors-3.tcl index 8e3db5488e..df7078d750 100644 --- a/Task/100-doors/Tcl/100-doors-3.tcl +++ b/Task/100-doors/Tcl/100-doors-3.tcl @@ -1,46 +1,8 @@ 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 - } +set doors [lrepeat [expr {$n + 1}] closed] +for {set i 1} {$i <= sqrt($n)} {incr i} { + lset doors [expr {$i ** 2}] open } - -# 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 - } - } - } +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-4.tcl b/Task/100-doors/Tcl/100-doors-4.tcl new file mode 100644 index 0000000000..8e3db5488e --- /dev/null +++ b/Task/100-doors/Tcl/100-doors-4.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/100-prisoners/EasyLang/100-prisoners.easy b/Task/100-prisoners/EasyLang/100-prisoners.easy index 3435445f04..3acb599a3c 100644 --- a/Task/100-prisoners/EasyLang/100-prisoners.easy +++ b/Task/100-prisoners/EasyLang/100-prisoners.easy @@ -1,60 +1,51 @@ -for i = 1 to 100 - drawer[] &= i - sampler[] &= i +global drawer[] sampler[] . +proc init . + for i = 1 to 100 + drawer[] &= i + sampler[] &= i + . . -subr shuffle_drawer +init +proc shuffle_drawer . for i = len drawer[] downto 2 r = random i swap drawer[r] drawer[i] . . -subr play_random +func play_random . shuffle_drawer for prisoner = 1 to 100 - found = 0 for i = 1 to 50 - r = random (100 - i) + r = random (100 - i + 1) card = drawer[sampler[r]] - swap sampler[r] sampler[100 - i - 1] - if card = prisoner - found = 1 - break 1 - . - . - if found = 0 - break 1 + swap sampler[r] sampler[100 - i + 1] + if card = prisoner : break 1 . + if i > 50 : return 0 . + return 1 . -subr play_optimal +func play_optimal . shuffle_drawer for prisoner = 1 to 100 reveal = prisoner - found = 0 for i = 1 to 50 card = drawer[reveal] - if card = prisoner - found = 1 - break 1 - . + if card = prisoner : break 1 reveal = card . - if found = 0 - break 1 - . + if i > 50 : return 0 . + return 1 . -n = 10000 -win = 0 -for _ = 1 to n - play_random - win += found +n = 100000 +for i to n + win += play_random . print "random: " & 100.0 * win / n & "%" # win = 0 -for _ = 1 to n - play_optimal - win += found +for i to n + win += play_optimal . print "optimal: " & 100.0 * win / n & "%" diff --git a/Task/15-puzzle-game/EasyLang/15-puzzle-game.easy b/Task/15-puzzle-game/EasyLang/15-puzzle-game.easy index 2b4fba7059..cce8901658 100644 --- a/Task/15-puzzle-game/EasyLang/15-puzzle-game.easy +++ b/Task/15-puzzle-game/EasyLang/15-puzzle-game.easy @@ -1,47 +1,38 @@ sysconf topleft -background 432 -textsize 13 +gbackground 432 +gtextsize 13 len f[] 16 -proc draw . . - clear +proc draw . + gclear for i = 1 to 16 - h = f[i] - if h < 16 + v = f[i] + if v < 16 x = (i - 1) mod 4 * 24 + 3 y = (i - 1) div 4 * 24 + 3 - color 210 - move x y - rect 22 22 - move x + 4 y + 6 - if h < 10 - move x + 6 y + 6 - . - color 885 - text h + gcolor 210 + grect x y 22 22 + if v < 10 : x += 2 + gcolor 885 + gtext x + 4 y + 6 v . . . -global done . -proc smiley . . +proc smiley . s = 3.5 x = 86 y = 86 - move x y - color 983 - circle 2.8 * s - color 000 - move x - s y - s - circle s / 3 - move x + 3.5 y - 3.5 - circle s / 3 - linewidth s / 3 - curve [ x - s y + s x y + 2 * s x + s y + s ] + gcolor 983 + gcircle x y 2.8 * s + gcolor 000 + gcircle (x - s) (y - s) (s / 3) + gcircle x + 3.5 y - 3.5 s / 3 + glinewidth s / 3 + gcurve [ x - s y + s x y + 2 * s x + s y + s ] . -proc init . . +global done . +proc init . done = 0 - for i = 1 to 16 - f[i] = i - . + for i = 1 to 16 : f[i] = i # shuffle for i = 15 downto 2 r = random i @@ -49,20 +40,14 @@ proc init . . . # make it solvable inv = 0 - for i = 1 to 15 - for j = 1 to i - 1 - if f[j] > f[i] - inv += 1 - . - . + for i = 1 to 15 : for j = 1 to i - 1 + if f[j] > f[i] : inv += 1 . - if inv mod 2 <> 0 - swap f[1] f[2] - . - textsize 12 + if inv mod 2 <> 0 : swap f[1] f[2] + gtextsize 12 draw . -proc move_tile . . +proc move_tile . c = mouse_x div 25 r = mouse_y div 25 i = r * 4 + c + 1 @@ -77,9 +62,7 @@ proc move_tile . . . draw for i = 1 to 15 - if f[i] > f[i + 1] - return - . + if f[i] > f[i + 1] : return . done = 1 timer 0.5 @@ -87,7 +70,7 @@ proc move_tile . . on mouse_down if done = 0 move_tile - elif done = 3 + elif done = 3 and mouse_x > 75 and mouse_y > 75 init . . diff --git a/Task/15-puzzle-solver/C-sharp/15-puzzle-solver.cs b/Task/15-puzzle-solver/C-sharp/15-puzzle-solver.cs index 16d2c2a882..591dbc1385 100644 --- a/Task/15-puzzle-solver/C-sharp/15-puzzle-solver.cs +++ b/Task/15-puzzle-solver/C-sharp/15-puzzle-solver.cs @@ -1,1466 +1,97 @@ -using System; -using System.IO; -using System.IO.Compression; -using System.Runtime.InteropServices; -using System.Text; +// Translated from C++ by Nigel Galloway -public static class Program +new FifteenSolver(8, 0xFE169B4C0A73D852).Solve(); + +class FifteenSolver { - public static void Main(string[] args) + readonly int[] RowIndex = [3, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3]; + readonly int[] ColIndex = [3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2]; + int n = 0, maxCost = 0; + readonly int[] Hole = new int[100]; + readonly char[] Move = new char[100]; + readonly int[] Cost = new int[100]; + readonly ulong[] State = new ulong[100]; + + bool Scan() { - byte[] t = new byte[] + if (Cost[n] < maxCost) + return Explore(); + + if (State[n] == 0x123456789ABCDEF0) { - 15, 14, 1, 6, - 9, 11, 4, 12, - 0, 10, 7, 3, - 13, 8, 5, 2, - }; + Console.WriteLine($"Solution found in {n} moves :"); - Ultimate.SolvePuzzle15(t); - } -} + for (var g = 1; g <= n; ++g) + Console.Write(Move[g]); -public static class NativeLibraryHelper -{ - [DllImport("kernel32.dll")] - public static extern IntPtr LoadLibrary(string DllToLoad); - - [DllImport("kernel32.dll")] - public static extern IntPtr GetProcAddress(IntPtr DllHandle, string ProcedureName); - - [DllImport("kernel32.dll")] - public static extern bool FreeLibrary(IntPtr DllHandle); - - public static T GetMethod(IntPtr DllHandle, string MethodName) where T : class - { - T Method = null; - - IntPtr MethodHandle = NativeLibraryHelper.GetProcAddress(DllHandle, MethodName); - if (MethodHandle != IntPtr.Zero) - { - Method = (T)((Object)Marshal.GetDelegateForFunctionPointer(MethodHandle, typeof(T))); - } - - return Method; - } -} - -public static class Ultimate -{ - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - [return: MarshalAs(UnmanagedType.LPWStr)] - private delegate string GetSolverName(); - - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - [return: MarshalAs(UnmanagedType.LPWStr)] - private delegate string CallSolver([In] [Out] byte[] Array, int Len); - - public static void SolvePuzzle15(byte[] t) - { - string LibPath = "Solver.dll"; - - byte[] ZipedData = Convert.FromBase64String(Data.ToString()); - byte[] UnzipedData = DecompressGZipArhive(new MemoryStream(ZipedData)); - File.WriteAllBytes(LibPath, UnzipedData); - - IntPtr DllHandle = NativeLibraryHelper.LoadLibrary(LibPath); - - GetSolverName GetSolverName = NativeLibraryHelper.GetMethod(DllHandle, "GetSolverName"); - Console.WriteLine("Hi! My name is {0}.", GetSolverName()); - Console.WriteLine(); - - Console.WriteLine("And I try solve puzzle15 with board:"); - for (int i = 0; i < t.Length; i += 4) Console.WriteLine("{0} {1} {2} {3}", t[i], t[i + 1], t[i + 2], t[i + 3]); - Console.WriteLine(); - - CallSolver SolveThis = NativeLibraryHelper.GetMethod(DllHandle, "SolvePuzzle15"); - - DateTime StartTime = DateTime.Now; - string Path = SolveThis(t, t.Length); - - if (!String.IsNullOrEmpty(Path)) - { - Path = Path.Trim(); - Console.WriteLine("Ready! Solution path is : {0}", Path); - Console.WriteLine("Moves {0} and Time: {1}", Path.Length, (DateTime.Now - StartTime).ToString()); Console.WriteLine(); - Console.WriteLine("Bye bye :)"); - } - else - { - Console.WriteLine("Sorry! I do know a solution :("); + return true; } - NativeLibraryHelper.FreeLibrary(DllHandle); - File.Delete(LibPath); + if (Cost[n] == maxCost) + return Explore(); - Console.ReadKey(); + return false; } - private static byte[] DecompressGZipArhive(Stream FStream) + bool Explore() { - if (FStream == null) return new byte[0]; - - FStream.Seek(0, SeekOrigin.Begin); - MemoryStream OutStream = new MemoryStream(); - - using (GZipStream DecompressedStream = new GZipStream(FStream, CompressionMode.Decompress)) - { - byte[] Buffer = new byte[1024]; - int CountReadingBytes = 0; - - while ((CountReadingBytes = DecompressedStream.Read(Buffer, 0, Buffer.Length)) > 0) - { - OutStream.Write(Buffer, 0, CountReadingBytes); - } - } - return OutStream.ToArray(); + if (Move[n] != 'u' && Hole[n] / 4 < 3) { Down(); ++n; if (Scan()) return true; --n; } + if (Move[n] != 'd' && Hole[n] / 4 > 0) { Up(); ++n; if (Scan()) return true; --n; } + if (Move[n] != 'l' && Hole[n] % 4 < 3) { Right(); ++n; if (Scan()) return true; --n; } + if (Move[n] != 'r' && Hole[n] % 4 > 0) { Left(); ++n; if (Scan()) return true; --n; } + return false; } - // no way make normal long string literal - private delegate StringBuilder AppendDelegate(string v); - private static StringBuilder Data = new StringBuilder(100000); - static Ultimate() + void Down() { - AppendDelegate a = Data.Append; - a("H4sICB6/w2MCAFBhc2NhbFNvbHZlci54ODYtNjQuZGxsAOxaZ3QbRRC+kyVHFg7nBAdCaDYYiKg21ab6ggR7cKL3HgJHDcWRqK"); - a("5RDDof4on26I/OAx79QTDVkmwcOTTboTgxxYQm+yimOcYU8c2eZORLaP/xi253dmdnZmdnZmd3EzgxJhQIguDEL5MRhHbB+qsV"); - a("/vmvGb/1t3hxfeHZojfL20X1zfKjzzl3UdnFdRedXTd/YdmC+RdeeFGw7IyzyupCF5ade2GZ77CjyhZedOZZO02f7qnI0jjcLw"); - a("hnXl00he6osNOW6zkKNozf7hC6thGE448RhJINBXzww1cUsnWHJTfBztzgIWcO4PPi3Tn8/AqKKS1POYVzqLzHKRw+RZgC4avd"); - a("8uC4Uzh9tvCf/8653ynMLvjr/p2CZ10eRIk5WwLdSZObilMmCKfvdOb84HzUoRfIDJy5JLNjCl4tyOxUR4jg6xGhE/QXo0ythV"); - a("e708UcD3O05irsgfIdlHa8MxYtQpWvhVDpXLc9EN8Djjya6m76xIBHLD0o7fKda/HdfTrXOQwJZfE68M7KzoOvUZbeHJR2+erO"); - a("uuCiBQLWhq8RcFBuuhbePOH/vyl/ma3PuNE5BT7RBh9pgw+2wfNs8F42eBcbvJ0N3tIGz7HBM22wxwY7bPDEDVPh723wiA1ebY"); - a("NX2eB+G7zcBidt8Is2+Bkb/KgNvs8G326Db7DBbTZ4sQ2+0gbX2eDzbPAZNvhEG3ykDT7YBs+zwXvZ4F1s8HY2eEsbPMcGz7TB"); - a("HhvssMET19vW3waP2ODVNniVDe63wcttcNIGv2iDn7HBj9rg+2zw7Tb4BhvcZoMX2+ArbXCdDT7PBp9hg0+0wUfa4INt8DwbvJ"); - a("cN3sUGb2eDt7TBc2zwTBvsscEOGzwRs62/DR6xwatt8Cob3G+Dl/8DnLTBL/4D/IwNftQG32eDb7fBN9jgNhu82AZfOQVuc213"); - a("h0OIuHZD3tEJmEXPrBhgeqrb1YIMRGS6a9XGTkGfVbqTU1B112Yo0qlMJsOi0/tucwhp9S1s8zRoLkbz8a6Nl4NUjv4xTH+Tuo"); - a("dYdFYZOlg0MJ5+/qrsoLJTcoh5+J9TT5zpp6SZHhpl+us+vZst84/zjEKNulb2ZMnEThOEqvjZ0WMzrf31e8ntGfzJ4bioGoFx"); - a("ZUHKLy0tLQosSCmJTxwv7IPBqrdHWbE6oK9Q9ZWsKIFZ+mqSTW/GGEA9KbdT2pVe7ytRQMtweh7N0oAQBoSIniVA1KnzgQSbVw"); - a("okymh6llVJp+9keVOzzWdI1ntzE0E5mi3TKIjlck7yl9+J7THjnOyFmkMAMMpJlx8sAPCnWWs8NA16TuzgFJjeyYU9i4TVByDv"); - a("0J+yCrn1TD/Ukr9K+X8s/NXcTH+MhbusrrPYve5sF8FgMDRlCDOcFfkNqh5n3j5pyfWoLypiYkpavBCZphIed0vXLkDjWHJacM"); - a("+xpBgsbnPOUDKpiIOFk+JY0hGUNAMt4bRD06nNMZZ0BqdbTU7e4gzoCSUx7ApVW5WC4KwYAwLjvW4l0xMaVcJD0wKt8cZSaYtm"); - a("kgdMwCGTBKfQD51Ky8+UNdcVMVRKIOGuGFjGDN+MIdU4egYMbN6Qqh+ZBilqHKXGcTSOonE8tALEtzDD7aAgSFsswRflbOcMab"); - a("ZvRi1rSRJDsPmKtYwQ8fZawKBfqxrqjDiRSqlS58FxfI5MUVsvtQ1QWy+1DWSoNSsJtQ5RaxptWUGobRQfiPKw0pImHkrLOBVS"); - a("+GwsuPTE6PBKmIsqJknf9fNJ13uQrtdjmeU5dXNVs/CII0/dXNVoc06qO6fqfXOqLkW3m7QN3UDhf2p6jqZpOW1osTxGdn2PZj"); - a("J1u4EK1/dsmlEJVDsbqi3J6tutGqUz0OZW9Zmhd0nbww2YF1d4dj2h2+Z8tVv6Tubpe4Tru5roV5LGqkljldQ2l9rKqG0utZVx"); - a("fWclodbZ1FqCNksQanLjMzP0qF3b52W1/R603WnznwkYep1AyEMZKl4Qs38B6cnEWGJasGosgRXxRUQWTuA3Io4lHMFizadTg4"); - a("NWZizhBAKHnbQqDHEivHp/lkgXhra3gGkACoLTYyrHcjPo4UfW2t/I6WYSWIbQT51sX9L+or3zVgjItaoux/FL4deL3wAGoxjC"); - a("L43fKH7joffNW6QtfBY+dIAB+KToQ7ZKYzgwRJ80fcgwMe5tUssJmUm1aLJ0YUrRU5p0eg8LfzIKGakanAfCJZp0cY+gSRdhsD"); - a("ehSUH83o+vGNqarh5WpM1Z0hY0/iKnm5Bz/Yh2Hlaz/LLPWTiV6ZRejrOoTxxlNclLv+nM5zc/x49zCR5BNHK85LG4GDpak0JT"); - a("OfYNm+U5XXGTq7X4M1IxsNfNvy9NEoyTBF91alLTck265Ds3Pv34mIBs82Jiv7+q39yE9Gubn5wYKSHcviFfUa+sJ/vSvvLerY"); - a("/BGdvi2bf2nFnfeL4FKmsGgptghqo3yenPk5Y6xXl7OR0hxMd4aLQq3ommYgfzpviw8L7n3oQjdNA1mikyHZki6aZ4Pjn0K7y/"); - a("cJQBoYDZMNDvnewXqV+0+YOeepH2YXbDqJRwZDhTe7+IMtsft/dfM0PvzW9j1/QB0aODUBaewfIxpCfSBOTBozbYUpc9vxhd2T"); - a("CuGf7xrenSy9oyp/ZLT5wyjn6rK1/+jZl+LgLW/BJVPxfB7JIyVb9iLtMvqWX6FQzrVOFmulxJ+yTK6h+kpksOx+eK03/wSU3y"); - a("xfTVKaJR5fpYtnLbPdnKvU9lK4/Es5Wne7OVF4b4dG4bRbHyhR/xxdoK4Qkx3C8gRBgbMwNyGZDLgFwG5DIglwG5DMhlzK/8Qb"); - a("qIRLmIi3IRRMGXi0IViGJVIIpVgShWBaJYFYhiVbKiXE+iDK5e+QgJk5lfTWo67thcBsmi++5cQRlK9wseGsceZMbhs5k+61y0"); - a("olqC6oVWtQzVRRw3kTbfzKUqp54GgkfxZEtPhcc3qDsknN7i0s3DaTFYFU4fHqwIp8uD24bT2wS3DKc3Cm5tbo/4IT2fcIUpDu"); - a("md5haAtZfOEswNtZj2kksw16eyQDALUeqvI5dwPb4LuLbGgx5j+rxyp5DpNSmz2h9VTZ9t5XEnTbEfanqYRdWKMn9V/MVKyhh/"); - a("/jmT4S3pb7/NZAxfRS0feHznZP7VvG/F9eQ0c9INv2Uymu7SAKavR113nY8q5ExvINhSNJu9aoarEqia7h83XHugpvt/Hfz0jp"); - a("ULx6UnjvnVMtMcP9naitKnQbJ8mvb+wyZy/fZ88Rd7R+4P8VW67k4eLGnv20K67lIAsvR8XNYRzj4pkYsS/vIeFeufGCpTixCb"); - a("EwwAkgeGwOlNsr4hZImmlN3fJ7fBmtRlPyh6v9K3WgmvHleiTo/pAQ9VL6JgTN0/wvExOkdKB6nVjPDWA94UOnlCHxWo6kdyBD"); - a("mfAAQKNFx+wQ1A8SaU8CfTlL7hgDel9H2iiD1mtU96fmPp+TmKdzCgrwq0DgY3D7T2NxSzZXGKasNdGNcu4jP8Yk4HSQfxVWp6"); - a("LusM6J1K36dK+NPxQLR4vUkILMyAPmBuS/MhP80jv57cTscxs8Si5abJEq33AWcJiK8rNa/XFSl9Q6DqNvdVliVgORlzN9qvIK"); - a("+I35yAdyCgJwMw5VkkcFFWYHNDLq0p5cv5elV80qiPyvnr66qeqG2rqpWWdrOa3saC2sh7VFejtSLTV6VLf8xkaiO7Zj0Tw3Pj"); - a("jztWPlo+hnspJ9Kt6m/7pKXb4LezsqBLWfAmlpsozgKE0icdtho1WIKsv4v8UQfv79Ee2tYfSZ8tI36KLHqYmDXRrenDoqUF6R"); - a("t/gPqbAPEREzRi77wRh6w9Yj5G+CM4Dx2F/kNz/emD0WzWrKOjCh1/L4MEjLMPiDp3iBRYsUE+RT751NP+1EYuXklLN5aWOryd"); - a("odlQgxhYEIf6efqXVsfh9J1aTB+wRZd8/2OtPcFSxBeGrZT/NaUfGIPUjqq43SuxzlTQiBKKawznX61lHxkZxI+d1vrQiF64Vi"); - a("B6oqjqg0BtmNldsCMLd4rkmWsG4KJmgaIjzf+E6W9pPI9QcRxtf/MN64+tWc0SIwVMf5+Fu0V2/vse8m9vL5hVRgoV/WfWmgm9"); - a("yfRRZBkwFtW7iom9qjeO08ImDJMXEzFzpkW3rTBSwDmHvxFZzXd136reQTkyh2SsJE1m5X1K0fsC0SNEHNaZ/inTP+KM1y0Tyc"); - a("Py5GH58gxYYmzGxYDezQ1ycsiRAmVSkB/qvgl4V/gjGxPzw0kQu39gYitg3QGqrKKNyvEdHbm/Qw+l5gyRBPcNBTL3N2XFkFqU"); - a("jJQW5PmLPZ7rgXFNn36y4aAtdGEu0QA5nDrI4hrdcjuVWswXESbH/ylNn6onIQ1cvqEwUBW34rHYWEgnDFhKPyyvSKnpa3Ch05"); - a("zNIW9foCbRUJytYzCnrUYPhrkfnjN3ueUTKlSxJ73F6FrbgLQ0EU7PD4/PWeTm1TLTEUlxD7FQfJFJOuFxsb7Sp8fJImPYtcE2"); - a("jmVFzJXU6KzwtQ7hoLZiz4GRYhEL6QR20yotlmO0zv3q7sxa8nSLJe0zUK5Ff6t10e+c1F+kpGW15ddMlPmBM50Yt1PP+c8DFU"); - a("OIuDkboAiHmKXo42QGd/yKo+HSQlYz0HAQSjIObzJH+9qKMhGUr4HcanQJBxT9uxep08oYXplAD+JNGbekifRCwLEYcSxDwjBp"); - a("h/9Bnpf+hTxrfv8reXa0yfPhz/9GHpgzMxxwgzJjl4BRoiRGymSjmukVFbLe6YOM0pODBOk/+Mv7FenJVQSUI2OYAJDkwFh5hk"); - a("lPrmGJb8rKx2TaXJtV8T1ZX8W/SUX8nsiXx1VxgCXMsvJBJg4QHxBUxV6mi1LHkW5Z6qh1i73heK2my27/kp7gpswQaeDWRDC0"); - a("PkEi4uO5blHQ+FqX2OaUiz9Mf0/qcO3XhuSsY9ZFcNKzfVFniSbXpOpdWtWgeYgqdfQoUkccWQRrr7nu02r8W19ZM4zLk/1Vcb"); - a("mGwCV1JNn58ZkBYKlinGEAspOgS2vpBPeWX6qERpf2UpUQQ08nu41nyWzNz+TZ1NB+tmb9KWvSLDHhUBJpEE7yIPytQ0OE2xnJ"); - a("rnp+fDauVlt1h3Cw4XQwvfBgw+fAEeRAN1VKUCkZvkjkuQocmw475/dhxPSjMMK6TMNq88sYqs2lWgnVKsFBuk4XBIj6rYi8eh"); - a("mzWHm4TkBa6ji6olLs1cBBa6mvQC4c3OtPtE9BX41CoujR2CefFsm+qtNvkt0iRa6GoFTWkqDDz4ILH9mLka5HuGTFkGJ9oJS4"); - a("OcpjQIGeltH+hi1L05fxk1uW2UP6X8u055+UmyyZSqbKVLMumcytWr60GLxNDPyWtjwWiofLhBP9853oOwF9bU7HEpwimPQqtp"); - a("lC6Dpm30jy4z/cqfd3cuC7yjJUvDKXF89VolD1B6t58XgtL55jvHjlcBSarL+t6e9rkrfXp7/ODH8l01vPQQeq1aheTDgtmQGh"); - a("0al1DAia3JIRm5umaXIHkoeNNX9rpqFQ81dlzOnUlYH9UZegr4JuCq7B4cIoRmKCKY1dDcBnnLkYl4a7f01ADfKCw76zSECMN8"); - a("1tZawGrg5RvOPtRdNroPmbQ2gAzVdodM2w5pPUYaYvbP5emtF6OWRra23Ct6JZutkfl55vbQSQSDu3zkwT6FyD8xjHymU9ksDK"); - a("4dn+CH6IL+jH2UdraRiHsbTew++2GkZRvZm2Af+tAgy23qctg+mKAhVziWp9Ra3mw7eaRf23Zm39ZlKZry2AO1quMrpAfxYngi"); - a("VxqXUrp8AHVws5Gnw4w/dMTuqCisp/IHWbC8eDwQKMhKyZaZasXHObQ7V3tOLoNiB1FC+mr2+xQ0yF407ob1lMWurHTRC/HvEm"); - a("EUD4/EJVXIC5WKJmDJ3CV+p4PY/vdwXguwAfxKfJMSf//ZhXaMzOWVnhLJswA7p+Mff/YlhRLylfe2k9wdwW0x7FamKZ4Imv9I"); - a("ZcfN9o3x8fBgtAVtviHxcFBg5sxVmjiGGuDCiH47tpXiycgd++nZn6zbTWeNNs4gPSQwzNKNPaMv8AzimHSR3HjMvtnVnx3nLQ"); - a("GiZY9JgUomf6NOxOEBSIoZl2AmapGvWngEmPJUP+yp70fOxd3Zg5SRRIszUr8S40pKwYBs6tSK6J/jfrccvrgvBoAek0bCvqxg"); - a("pA3HRunPySldPhLGciIwWdU3B52qOWr0RGau7N80lEbYZ3JiYux3lSc3E1pDBW0VcoK0zp+UCXL3Ly9FsxjJX3YRh01QUz3ffT"); - a("TMNGQH2LDgcI+6d0qTUrG104ZYcep2Y1eoJIYnThCNi0AZqlmxNWfibrKfN0LebXl+NVydzfpyfAXhZTct9IHntZf92vd/v0lf"); - a("KKb3yR73BSPKVrXkTd7Faf3ucrT4CIJYidV6PLj3vPR7UYiuC2aO3mgRerQ2e4plloCMcdpDrq6/a5bkOOp+0d6mrYnFQu+jg9"); - a("9ELXpGh/EVRK+Tc56WF5bqkZpH042qRTgccAbIcsCq68bhcrdFneGuL5sebbe2FXw2Z8rf1Sx5v5jN9wc8axtb34bzgjmaSe6n"); - a("Uzf0GkZzArdBtW6Das0G1YoduwQrdhhW6Dh24rvbfyWdhrcQUEjUsd/bK3V0bte2k7/E5wNYQdwvdM2iGuQfGNG0odvejBlfLO"); - a("iSsdwWlYWNrHgU9k3J1554l78L4Ik25AShjCJf9ZA6q+EEYaSjOcM3iamMS031KNhZUI7GdVa7K0tAEhcyxE4Xzc9FA0j4uox0"); - a("meF8jEvAkI+RmBsrcLAf0TCuifQLLPsL/4xaEACaKvTLMfaGt6VRR419ZZjxwFh24WLS5QsENkU+xTvwamX/yC7GAs6MOn0UNo"); - a("3c6C7U13trYjNpJuys/MrbQYuHdLHe+LtCb8mIFLiffntZVuh8MVT0xgUE2rmIHJG5i8gckbmLyByRuYPNf6uvZfrBDtv5fzoq"); - a("EZWotAazFoDT4aukfVGx62NHdMXIUDRd4GOdLcwmpSXy0+AQYLOhwu0K4ZpxyPqffI0p3LaHdcs1KL5YyxB4bYS9HGwNvux24e"); - a("bp7Savzt9dNAw99uuqh4CtPsgvqtf5osxqGDX0WcAVHGSRe0CjzeepOIrwR5E7jD1GpWaZK6SmsdpL1cHIhhTYhXHAeC9FPfQd"); - a("tYFurdNrsqKX7BYxwTx8o44LsrsivTZQJX/ChWuyQTXD+H0+107GgW50FlGq0M5vp1YylWqxDnbfS+Rb0Rp2cKaiVHzU5jBjre"); - a("gwToKNnJ6sA2Z1ZoMen5JAg5C8+OskofRhPSvEixQEj4JIlEzbuNhfi+09RPaoLT8N2GZuX961nxq9lvRvis4DN5kvk5bT9NNE"); - a("8sTDQP2p7jIB63Sx3+p7yc2dw8ZoRHzErymLVYzLQYYuhT4WFRa+2pr9ReymTono4n/cgXpaU+V+/Z0cPzJluanWzNyqaV2Fwt"); - a("mzRgkwZs0oBNGrBJAzZpwCZzBm235zLLng+38snjrXzydCufPMfKJy+28snLeQHylnm3B/Quf+RNnkzCNGHLtZrRkLPte7r9cS"); - a("RXDwuYJjRxD6XW3XDbBjc2bORI5kEI+tUNMrZOQI2zVCBVw/6eIrNPf/wxTV7gvpDdEaqpgzvDLgU8MoO4CBxSsNuiEloPOeoY"); - a("MlNYyJba3qdUN5bCR0LVlgjVSI1k/X3Tje9HlMxiZMN0OkLxY4E/YhZCtAjfwSNwtHsa3KjdQz2I79UUTyi5OiYG6B7Qi5FD+S"); - a("O87VaY4mvAeE9MUnZLk01Cpnsws42wqBFCF1Oo3SqmyE/FJKgks7ES8qQoakvXliJrwXCpY7k3BUOF6Q4g3KoDNMcCTVzFMEjR"); - a("yU3bVX11uuibP910B5tBt5NB88npyaynzklnbRom/HVwg6wxtpMJa1bcRP7X5n8Y55FTzLk5k6ObsUQON1JckvWvTu6i33CfHm"); - a("vqN6uAD7ZPwSUduSEkB4Y41jnkbXwzjTuuS2wFOoDYWe9Y8CXE9om/Q26+HlDUki/RkRsBx7QiAxQegcK3+wtNHBPJEpxJBAtC"); - a("ES1mTVYztwPtfBej0MSnW+rOk71lYYwzwYNXU59ZnX2HmDpvGkk8EdT+YuTbKG+FmNv+lZi3ZsU8/wvuA/Ajsc2PNbdc1LBc1L"); - a("Bc1LBc1LBc1LBcFBHA7u15+/1Q7v9HkRu3nVKpIX31GyWaX3fjMaantm03z5LBkFLb/LszdIACU2Th4QJsDispv9yFGprrPb+7"); - a("67aVUQ0PY3GHeajtCa6HJHHlvOZ95hQFR6gh5KxdWhQDIZe0+F7Kt6x662LUlwxKS66kNj/dWINqj2aoHuTon4g4mJ2OnspBc4"); - a("b1rt4yIgoQbXnbph5CpGyTxECy2eBcMhj8COLuYh5g7qRl38lJIJpKs9Mj8nIfj2dRiYyh4QTlKW5zQ+iVODf1dzvQskzADNpF"); - a("So/s/29rbf3FoL8Udv5e6HAAO/8Qdv60mtUnLn+QqPvaQpX0/1iW3773Io+/qsdf9bX+tqkpdAu98yHnLlz86tBMZc1qVexnfa"); - a("twxbgZPV+dmyR85k3obystE3ysm8bq75o7qHrfnyPZmk9wWMiOlJGN66lz44Qve5PA5jETmziStk5KFXnIvFsgxSBeLxkLzqRk"); - a("K1QMu+12FqL1ZSv9km6OR3gq20kHc35pRcNBya8PcyInciJi1yTmIO2qhFmQxZT1nzlmZRaT+qFRZFdQlwF1GVCXAXXZNPyX9s"); - a("kwPdgolipE9w/9Zo0svZIIufj9dnmcHy3Ojffh6I27umLMMJl9lp+17+UOwbd38eI6XGJQMhDzw1Qk1CeKhAa0vVgEe4TRrzDV"); - a("nN2QnZE57uDTl/PXgjWr8U6gr9AHzo970OZN0rUdft8zcTRSKsr6SlPKNvXj3aLbyTXZ3/SsDC3aLSm335LfYooRmFAM07wVJn"); - a("QPTOhhmNBT2F3brWm/H9BfU/UAaawSx9LPrJjw4gYUGI5cDQp0QZPJhFwdG/MrWISScLVQL/Ga4aZDqr83+4ZHVatdwE7H9ASd"); - a("WGMydIenmz/fRRTYFebb7qEh0pO9uOhXojLu4ZMR36xP1/2E0kfnzed8OrGLG6F4oPXrYGG4m/ZlVBv2D3e7WDjjbijscPNX6g"); - a("XdzDuOGwuq1IxL6hraA0r035Ff+bwTei/FQ/NMJDe8cpLh7xW7zVl8fUCVhREL0YlT46eVKMPjrvo0fwVVvWlQ9elpGmf4Uzh7"); - a("boIiPO5sXI8jULsWA4EUyebz/u6nS8pb0VM1eLY/epkD5Hw1ow1FkAQWXSfGlAXdzfWuT3av28aqra5ZtL6y4D16JGmGPkRzOt"); - a("ohyepKfsiPhX8RQ4dkUStDsrlBdn/w6aNcXhkTQB3dn9YER1CTlqI5HEfj96TgrADu3DwnVYSKWjPUuAHdA3kI8A7J4rKYT/8i"); - a("pgLHgJEgF/jtczwPfgelS9GX8ywi5MSV8zTQPjt6/C+tg/WlZ0eP+D17qW/4ByhhNees1bYjW0BJkd5J5W0yNwllDQgmKftMEB"); - a("Zln0hV1QV/ed+8NrZDWtqX5eDHWJzTSrXYn22VaJPDy0RMtH4Yj6nHiT4ILtf01h8k6+/JeG6j/UDmClqYEvkyh0r+HL8TpwmW"); - a("PdBu29GuT7Oc3Wj314w2vRaDPeE1J7Tln2N2tOQoyZejDG3YG75hBrzUgJca8FIDXmrASw14qQEvXWt/kOl0L3Q7BLlb8DTX4K"); - a("IJT530buix4ouCzQeyzQjULK/fyA9uB+LVb4YcnigKfoZvWfCj4Ae8uQ2tzRPb120uN49sHyzF1xGaqcWwUxEJcxrslyogpdYs"); - a("l64lG5YxDsOaJyqkxRHAzSMVwS2aR8TgdvSpah7xBKubR+YG12seKZNaNb4XQ8wSojN8HEDQBOzgDA7mfW5e30+LWXwad1PwqG"); - a("oZCckdnjg+OC08cXnQEZoDTAdRw1zXnzrf7FgPyde8z4zK4AjpZK33f7j961bIC1R9VjWGZ1j+kkSX7RXpB3Dfreh+cJ2m7I3i"); - a("2rtFLi9o+oXmfabhnlMx/ALDwkrXhdHHcgd+dFZKrRejSVnmB0yXnHwsaKkgb/1Hh6p+tua75vqKMk9oI2kpOLIXcm/n2GaHX+"); - a("NP5UmCh18gPwffgNBWLC3pkZY8R1yGK6XFJ/FK0aUbNg+7645oHnZdWtY8vEndQVTbzqylMWBaLIWHK+VIytwVMky2Ib/akxo3"); - a("12L5bcdRmwf6PArtT5XE8NzGxUZofguP7b69oKFFdJZOUfbgRTr0fZ1LrUkt8kCJwzy3ilEvE99Swn4BayEpe4N6dG9MJacQRf"); - a("8RU68Qgi5lzQdajNdDMtdGcC+GkFa/G8PVZXB9/i3F1xGcY5Yp0qtdit5lbkS2KHXw+npUX0BVDZchQzH+MJ/7bw78PRzWTx7g"); - a("wVNyQFL7AlKgt2rQ+q+tSdE8JPf/sMXatl1qq7uDOwF3QA6b8+XwL3MWOXco47790WRLYW3zN2gDaqgUvHOEGJ7mlZpVTc/j01"); - a("jCDaHlC/oy76hZGPCmVD2OZ/W8fCP3Jq7SSdaYqSK5EhPpk/vwgGm5ed77efSIja33zq9PIkuDooSgnxk+Mie8IAIvB5QIOUAz"); - a("ZmXSBYKml1jgslqHiLGozuYN3dwmeTXvFfkoS7hwjRCEVCKLHp9my8CA2F7lFuo3oTHRQ/7g7DrAm6qi8EvTphMTaauIiqhVW2"); - a("dxEmtHsMX3NEHcuP0cce/E2aVFbXxG87n93Ip7T9xSCi24KM4qqJWqvBpHnBQpjf859+UtUxx+n80b995z7rnnnHvWfRRoHR+n"); - a("0/BiiimgNvdIHstWIeLM/8PCEfS6KCU1F6GpnNKOxRgGbGd9D4xauWaXyFbYPxF7K5U7WlNSawkKYFLaNuiHsQh0kO0as87Hft"); - a("7hvU31Yw4LxUVKe23T7Ocd7nHa1wIDEYZcYjkFoVlPQyR4zFMmSRI0dQqmKAObhXu4VhqhEIoNaC9tRu9xDRrkhlRlGEnuRsry"); - a("4Vm6/Lw/3eIARwBTcZqtFk6w6a/AoYHD9DqZJdBhCPnBqHwXqGrhWthnhai+y1nphiySPw+zpCy8g0uKoq5QOx2nYfCQZDysbv"); - a("r5twAOA3Y5VaB40H8wWQxFqJ1UJknUNUZBgMh47l2m7WTre6/e9wusj9n3Z60qa99fe619T6K+aEE5OMYXRki4ydv4bbjJ/1uU"); - a("omcLIihWXd3knfuOEktRav/AUSqocoHohGspXlLM8B10HzpV6FfgIZ6j9fP0/AD9eWwYXSK5stoA0iM0kUJLcavEFio19dHTZf"); - a("9owHtjz77xsu0wACxV7SCkWshv2TqI4PtkRfWCg+kYy7g/V7tR6Yaen055X9thBGCWkUqLN7k4KI9XIAIAcON30Vi0dFPLZ6hl"); - a("zR7RwyyAvisyetvgXG+Fs3ANsflRYnhRL0RtzqI2UxajwRw0SB5iGfYGDJulx15Gj/PQYwysNzSwDqERBoQ/+2FT9TxtdLwk6S"); - a("r22MAxzmoy53mjlDZjoi5/TRNNscuaXz5H+CcJiOCtMge0T3oY/gl8kyiCTi2wzEMQyUP6grCowerv/P08EgwzOmk0HlI1AMyf"); - a("A+ZD+7hFvgX5BYrsgtOKIRnaIKnFpn7KLBfr+p8sQOWET2T/IYuaizEWarP26pMimnJCr1zTtKi1VB/2KBo2lcN8hdhjfxjGGw"); - a("lYKbN5eUIrXmjl85ZB5vOj+xvmumgolYKJJfO1PNQA6aJZzj1pT9OWLLD2DQzq8gWjdH+XGl3kf897zYmcSns30PGDC/YO4b0Q"); - a("Ay/EwITxfClShzsDzF2+DBhDDk+3wfh8BWBA+H6NeBqq00lPotH/Y9tjwAVxde8V10lCa2Lez2MBoZsa/Wuag/Bczk4bdHPA35"); - a("rvQoBf1sVLvy9cRexxGpqkmCkewVCAk2zrBhydrHlUx6OGUoaKROsB6MimfhlP0+Wh393S0MUQZ30ZC7Cm0X70z2jmxtgoVm2A"); - a("nA/v7JPxANQ20KAXNb5oPi0y+ujzaBxrHqCc6FIQnUB4yCrqKCi+gARtILYqWYAxCP+3+Xc0WqxPogHvRfsccKKhb6a8r4YW+X"); - a("9u3h4e3llWeCHAA6fNUHPnhah9CO3hwaASoW2AhiQxfsfD7hHufcF4xUS1BainmxUd9QY73rvOJ8VWYVVwgB+M7+2Cr0aqeRQK"); - a("XHEtZ7x/MugP6f6YpHuyV+J779xD+gNPuzQf7nkbXbkqneYtatIIb1EQNkgph/ghpSqkVIWUqpBSx3blPH9Yt4FdDZj779MQ/j"); - a("4Ifz+EfwDCr0H4UzA4sblB3BcY5ykxC1D6YyDk1OpXLPNe24MmaP4NuGOAokuWfe/8Lq5HWZgsBL+rO3z9pZtafk+b3UXj0Auv"); - a("bHK8t73989ze/32kQN+ydgQm2MdpjSqR3SXq9nnoF6Hyfhr1+l6iFe2Lx2nJauxJTIG9QAEKwVoZhIvhPsVWt0BYBMf9olsEb4"); - a("4yubGyoIsaHQC5NZBbD+7Y7aX3UA8NLorm9XiQqBIWlwnBjyB+EGUzh7qAnbaqJ53unGTWejrtC4sJBvR7w5RU3wDz1nRabjOP"); - a("dEiv0CG1t30BdKmEGvYY+IwosgGCHyHkVjeV1VIqWSYr6HIARQvv3E+I154vyRwfsO8hgJ+pzW7oNKGX6dDLtMfetMLelGBjVA"); - a("DlOhTtDjfR1505cxoCKRs6q024e2XgTiaojnpwk93AWHnt9SKOUS7zjqq7Y9ppS2ge3ebyVxFI5EKCVs4z9O2aN2x8dMbnOt+p"); - a("G+h8ctpCrsvNbLG3F1tsafsO65QXdG8B0lEN8pKCvAyLCSBBRsbg1U3VsM+rMrPYSoFf6xJT0R58j+cAVysdLVHiR1W4knn8Y8"); - a("7qoBwxqxmELRmWlEW1yNOWYl4LxLy2unG5myUPAMTUtOsXZOb1Ec2ru0j3N4C2CrRVoK0CbdUoJc6iL85Cpp73jJNwYSqOsc9f"); - a("f+A4r2yeU74fI2BqPNotYthhKLlXhtaCa7YGcvTGeFCOB0GIqaGXafdC1JEk6sBhPkTcBwISm5WjTauP36uAs/FiJi3L707GKW"); - a("eR2Xfym3By/F9EC6ekh+aL86kwmfPIDltP7u1l9/9R8Ry+Tl+BCKfb9NTtr9nWoWSZm3XRnIIsOu3s12y8OPAZ67RvonthvQBY"); - a("zNS6e8D9kauohJMCrhU00c2grAiXXRfR1HoRe9EfnD/KD6CVx2Jdp34R0tYIKlJQdEOOodQhDkBCkcfF6h7yTBx+xGOv2ua7Ce"); - a("ZArgdp2tgsbegNwMA1uZmu6FF8pU1gE5eKjX8M4i0AxveZQBXksv+D5s0gBJO9116ZOanRJaMglo6ALB2WEQM8V/jd5SHdq0bs"); - a("H8N5EslZhOYxKUITjwmQejA53Q1aODZNw72p4RFtZR28JujdvzfonYEg/XrcWjuri2VEuxLj8PAYmrq6hnvENGIXDScLqMWJaP"); - a("EP+pLUnnrOMLXu+UkshlocjE93kT+Uy5AuHEYjgeM+Gq3aOJ4A+rgtStH4z4wHqBtRSIDPs7uYtpEi7bI0czp40zwckoW/g7He"); - a("UOyd0JQfUAbswlK35CIHnrBxmX+guRCuyzY4MNo63voGYXtEdmgn2SUY+0r7CZlneGxE2S2Rt6wLxr6jnaUS29F+OOUCmoViJ6"); - a("Fyb7oGDmniCW4PSgRj243Fk058EQZkURDgAUhwRoguWsSBLIhCBm3kzk/hh5/oD9uGbd2rekPx49Iz4mfkpJN7ZuKTC1yBq5uk"); - a("Pd3RCqvUYSqE7udQmqRUcGDzWzpzhvYLXUH/ypZeXIMyznngTKVC5xZmKJwUEbYzIl3NtWg/Ix7MSZtKyz+/eSsFUUqBB5gysG"); - a("dhNB+6rFuP7aJF20pc0zlNZ/0+pFscl5qSttJAruWjHzi+5ZEgwNhl8JIkhmt/tGNW0YKluH6Zptf6nUVJzOF6fppHFn/waVFv"); - a("LOC+oPFPH6kjFbljFFfIvW6h5lEQJ44DxCXmR8BGXgzVhKg6nq/VfsBGhxy/id7SvrbxKn6im7w75JKcCTAqgxGKekx7CNwcVL"); - a("cER0byQipK4xT/b95r6Dg2eNZ77aW4YG1GB+xZZ782Qvw3gCgg0iot48Sl0Ai9xvPm3ehUj35bpSsMDkWX1UGGMxGB9iFyy/sV"); - a("CPgLSagDMuqr/hTWj3b/n9kUhPP7H9+b2+i/zi8vUWIfBi2fNLEZ3lQWcY6Lp9+W/4aL9yoFZ4lt9q3/1xbgfz75XjRR6wCY4g"); - a("RCjaYwAP/J3hcX1YpaUqF95DK3M2GDIF+g3f2Cvp/V8n7mw3fgkjuTXn5QNO9x+Ndni/Y9Yu/YbeADtll+JxOFcCCG2CSH59K6"); - a("pRyLVEwm2Bnq5yCYGkR+S0RPdv3O6YFgvSxxlg8RfcNCUQe09nDrflpe7KF7iEvugvZCcQTjJXtYwd2wUoCjIFfvEMc7oQLpSy"); - a("ta/3e6O7YZ+HXdiW7TPyBzGvKjc0t0mHqWGsoBXEYFXtqZ0D+mX5Cd/yn8oosfRsPmQgNWYEDcZazYj4RERHwAosR4T7r8FRA/"); - a("4WRR8lI8YTWgJfMRmZnxvlviVHp3dv/xmCGTf8f+/k449rHBrE2wgScBCcQSengIFZYFUZGE8zoMl/TSVTlYj7bG2DkaU/aKbB"); - a("/Tce4XAlRjJw551CDqcAPBy+yv/h7v7MulLPZa8lmb/XLUUje1+T0cS6FMzWJfdz9rs9V2RTuqdSwmgy2SB0M16QahMb1oKWAK"); - a("e6dQn0KyWGg47QswiH3LMPIP2gp8f4i9Ve3ld0hX59QD/b/HmzOZsvbadnIJIpvEPpuyWHvhBd3woc1qH+3BNK1tso4YeymWaq"); - a("ZHmE11exvpik2FfbN0MDYhk4/IpZe4zE3maSdiBDMXUW2eZ8xQmmgc2SbRXrv6QEKjCByr1QOLZIncsV0u3U0BMMGXZibC5H8x"); - a("gB8NmeVUZUReOqRtyntGj/AY8bQBTzU6Q6xgGmgK4XtrLjVxniTOzp9vfPvP/KmLUZfBoj1uSbjrGfhCR/h74LL3ZNTB7EHSJ1"); - a("1g47yqJegQPwSBgru/whXV9ws1kfpJ1wsnZ+deJ/+aHr7Mwd52YI/UHMltQRM2txFl6fdke9WDD9eGY8MoXTb5eMunbfx543ts"); - a("h/8EFysU+4qyG5D5dPnaAfjn63IInPpFYPIt65ZVwES3qlCvcQgpkXfXCOmx5zRuecomUwUClxXYKy1B7WkriIKrkUyGfkmXnw"); - a("7MoFOd+si0p01sZunKrAbtMaAlFrDjK2zPCDWozcSuQ5iWCqUHFiKUr6ZNJ+E0r8fKd3lnNwt/D+bE7FMpv1tbMJMYvlIRdnF+"); - a("k9qAhSHjltY8SGoCMqhoW4ywDDbgKbXzqAeCl9iopG/kjsHhpYSh9jzEqIBaXjtiUf8O/MJMDhFlCYsRw7FqvbVTXv1vRfMQdN"); - a("g1oQjONrEm29FAwz8vAtMRp2cIAU16kx0KizthrofwFtm2GpR0T9FHW/2RnBnxwE0mWi2fAVpF95A7dszF7sy6aJYH7pb2Wx06"); - a("+bsvKMVjXUXR1GtZ6XV4codOQ38ar5jH6xYOnFUiA45HZKT5h1vzsNLJ8r+/Q8Es4DIPfKZd+RytDQHcnoefpGPhRu0v413BeJ"); - a("fRMEtXxi4aSQivbxRGnZ1zeDW0K+eN9b2LdnhpHq6/6mYzvmO1O0LZwN/ecku8xRa/bdtizf3g/Wft+8EvU9e5HxiqfqJQ9QfV"); - a("Gqp+mu7KzvI5UtQiK33xW/asdI41K830GGM/+E/56cG5Zn56w9r/l59+c66DzOvWnw1fGfpTOAekPOtM5WnEMFY+atOdsxZn1Z"); - a("2HL8+iO7Pryw1cY+jLO//Ipi9PftSmL/sXZdOX4z+36csPlmXRlw79ZZqTIPo06BKhs4SHa+qbi7B1ZNtOs41n1WM+7O0OLWgO"); - a("uqVt0LHHGy8KCYq5kOAL1s009py1jl3emW+328BEJJ+u9m+jKF2O0P3RUl0vz6aHP4gaJxtPKLG1aAeSIPAJfR89QPavotTzfv"); - a("Gy7QmR7XJE3nkTeHf0wRh3KeyQUIxmqtU/hUGp8sp4F0ICF29IcW1BL9kBramJ7pEZbrkrS2sYS789yQ4Awif6NjWIB8l6wU69"); - a("MBszA9yOAWwNX0HDbPDvw3NBPjMz7LSPdgQ7/uf8T8iS/oGPDKGyJn1aAxQZeuFXIVF2Pm97yCZnqYVuiXw9dEC+hZyrdPmJ/W"); - a("6RjzG1twgQuuiLBHly/FhXAnLBc/yFA7yvPAHKoUpQrvqMaBAvOYb8nzlP67ZXcXpdORvH/riTvj8KCbEGVhxb4zdznVujPf7X"); - a("l9EGqzgO8Qfrwxp9i5T/pM7uIVLrhq9wEK5ssdH398BbqmA5ePxERD7P2wC1bZO9V96CTiAKnngvV43vLuRNtcVD3Ymhs/X9c9"); - a("lqIyTqtjryrQHrA7F7plrzENNKlto8URRTgRDgUeygILsIlDY9DvISO46sNiKlbnnpt7J7l3CvR0xLxErRph9txLbxD/YmIjns"); - a("FUwLJzJ0iexuCaN6eS69iKHqYkPi/spjIpJKkM7iBjVKbASMaVeN2et1UkGQpgDhRIrv51ZQi6GhPDA23dFah6YsC035Q+nt1Z"); - a("1j7+yX89BmhCsOGmmiR1UUTL+6YuPGzsH2wfZoTaB9BCWEdDxyeXhabJNzFRSq0o0S+zJZnvUxfUVm6DEM2Ng5QN9aKac8More"); - a("lg5eNjgKqJ39FBzs7Kbhtf3im4AwScQG374gX3wsJqHEL0qjvtp1Xh0+VqXnsxUsG9piKSMVBVdvMqmh84uG9m/bcfSiPZofvm"); - a("ywQYoUhGJ9nDsP+j+5cAl+A6/T1hLkPJTLe7kLKBGoyC78109/vbPbMLi4ynPpV5d/Iq5yvFcuxNXQIpeEseqJlq/jMsE4hKep"); - a("m0wCYDp+uqxr0COfsEyJfZ55ddQkF97VSzJeBguTeKN0rG3zXtViDAX8Mt+hsI3nFeOVZB3PhIVBba9znOCQRM6XpAu2xMUoqH"); - a("D+RFxI/YB3+WpAp9df4uaq76UMQuHEEJ78DZ98AXP8OvApyYbPutF1/x1dSXLhQ6mEWNonXVAgkErur1z2A72R40ekg/5fL9gh"); - a("GEvKXcki+bJumo3Be/T4skE6X09vlksSBk2OD7m6wYGUy83MEaJxgTcU+yk8PbY9d8R80Sro/+WCwpD/U+9Va8isQB5bjpVVDD"); - a("2Zgz66XBzMcjGxsXNF+4r26DYsF+N0tv9QwQm8YssNy8Cxpgys732xb+mKy1Yw//cx/8+nYTRsg24qvkdBsYX/ZfD/6jH4/2Di"); - a("/4mdn6F7+5/t0aJw7LPwZSvs/L/Uxv+oWf8TXN2FwQEK/M9//fhr8D9d5Yn3aHmLuAL/X0H832nyf4vg/4N5GUsm4mAT8f/irq"); - a("+wyIuV2LuZV8GJLrzjFV4cLBzCG8H/tTb+30nwv208rxivJOt4JiwManud4wQ3Nv+/bOX/x638f7f0d3zyBczx68CnJBs+60bX"); - a("7UB3TP73ElMlC238mw/+pcfgW2bZ49BF4TwcYtsq/qfv+GQtoHPaS+v9+i/jSYaBJAw4z+/pNEcQovRMRATE9srD9iIHYi9CQT"); - a("JUYdNfZJCElY3kUDyvGIFHsnsygag1fW7ky7Hv0Z6+ETqmeciISKtwfLrzN90W2skZh7LUP7fX9tXRpjb7QbZK8j5AgQ3hM04d"); - a("1w8HMd0HXzQJgOXv4w547HJ2joTAY/NJ3PoBs/WjeuuuJKE3B3faVSdyo3az0RW2IdvEkJPFkFViyAPN1ofZhjyAhtwVQ2pP3W"); - a("+4yN9JuF9SZXORTf98g7TTcbS//2N07Pd5n3JMMm/Fu266e0zcnfEe3639ie/eE++8Kb5bJO7WF3f7oqU5KhmXebIaGO7WDx7Y"); - a("ATr5qSUFnhoWPCWi2udlZM4txy9C5qoeuRTtwfvssYKeSuJ9etlaR0Zg+GF2vndGwRFO34Dz47vmwO8qkyIbyuo+BfyRRnU6wh"); - a("0+8kWmbiZMx3N2MAK4gmuAjRrVy0Mc+PYB32Ga3M6AGz88BWQJsXEOxHaoJBmll62FZLD98BARXkVXsx7Dnqsmu+8W0El37paP"); - a("sl9oD8KMXb96K0h4D0j4MFyYp+HCoHY1Oi/In7kIDXChdhOyayENB1KoVLFlgnbkvQbGiwnjS7dhesPDAOXghbiQ8szhs3Qqvj"); - a("uuTpU7LgEZC3FXFlQrk25KrHN1pQ9HNFAfGz/e11T9R6YWMnosvaQr6AJQlnKGXAIzZzuu9UvpBVvfgLPpFF0l9sf8juFxEfzx"); - a("4ZSN+O5NXPbRMEFVCoIkhVRCH3jRNZSA/GaGF3W3RLFHqfK6kGBlaiE7NLgh4hsbpHXQHLvZ15gsBsngU6bjQ4VcPqLDQcCIW6"); - a("szCxhIja9lffGgoUBkSHuS+WLq1fAiMPsmKskRCM8khAG8gCqRCu4h/dtYkYJL1zqJGqC/D57bBKqJQsaVC55W3EexACJCjRw/"); - a("Jg3XsnlnubeHZIbWA/ocepRpbBkhB3l7bREKWpHjbFuGdhkqzIGZwvajgTJUrD4P7+xDXWQxjPia8VH7lj6pddOg/6S+1g21GX"); - a("fbmeGsrUiuDKJdMSn7gK0zCO2pVj4QfQSOJhnFGlbND8anuQjzNzbG+IInqL51W1gQTwGulcxYRIDI8cZvxotMSw9a8qagBhgP"); - a("ATIeMMAF0VtHB+Bgq4gmROdL7hWspjhYzU97BzE52I1ahzDgNB/OxDjQV6r6qIqBOLFtoq6bBHOBnRKgZ7+r9XDCWrCeS4QJmq"); - a("cba0n2mlhPFM0C0MfW9WQgcZmA9UNNpQnMBKwl1pfqfTk0s5PRgRg8lsO3dJpbsLANdqCA1g96QYVeUKEXVOgFFXpBhV5ANe86"); - a("ziMv0urvZHbwvjhu66k5ErhCO3pLY8dxxC/hP0+g7QsWaBH6aM/xJ4ciuUgU5lQbn2G160/xRUbqWgE9TL1auFe0XFtwh8GJy4"); - a("gTv96C66MM1Zk9P1eOYdh/ltKQQKHKwwkjZOGItwJiFzcFjXQE/x6vK6KQpOpBowSDWM8KIpywxuwc+xlWIgaOgm0dLaclohI9"); - a("QEwfeAoxC8t0S0qKzAJsHCIg3qBfrKL+oh4/wxKJFUZCfwKZ6JSoykW8KaWVtr6deVxCUy+g/Mh6WCZ66gygO+f3R+t6bDW504"); - a("mEUf/nxXPMWzyfeU7CmKCDfl7MhvMxOuxsFkXyAP37uOrhM5uQlorvjU8FYu4dF02GzkaIJaTKPsW1FPEn+CckP/MqAxBXOlCO"); - a("U3IX+7DXBNWAL6RKtNdgL+vifA5ezZSij3Tb49FqqQgPTd8qkwwQWXByLCfjLeSf9tcLma8nIWI/U4qM0yOmB2IBxPz3l9X9Gg"); - a("jKdO3d8aJgD4ztV90nI/CAU7o7BV6j1dLPPyxwoeQWH++GIdvoLoEMe/T79MHu3Eb/yrblVDfFMSNrhMbJv9r8XK5n0L6rMPPH"); - a("2eO/Qyea/95HUD2/MoTlqg+oHtT3n5J+M83zwEmD2DBhoahBTy7N77xeUdo1TjxHMNhTktwq4F974QfMi5f6eFvf24fVpC8nC7"); - a("0VvQvnKhFcskdW/zE+PXQqo9hg4LdPBj9Bu4SFbkpNs6ckOgl3Aq9G4Kt/ZFWLz0H4sRL4oergwrfXhefNqDt3IpnlvBoXaMEB"); - a("D7TD+7ryerTgAF9Q3WKomXyVkIpPndH2cIQSjxYhWtskQY/GuqHB5Tct+hv0hWpGEL9I26hHEBYIecRg8V19yVrSDWQJFFFE0f"); - a("tiQxEZof41OI+tgDMxiSIFPJGZhSgz9F7RzDG4P4KxVPZzTiiakNotIoYdcCrdZvvesdowQVBxn/sNc1+8V5UJ2vELGW3vjbZv"); - a("ZJPKq0pukNBFD8MbdBaSl0ex46/wBx27q81KvezxxnlMbzl2cEWlmsOfSdXJvfNQm/BX1dbJIeQj1lPibQUBNZ/aTE3mAxxdoO"); - a("3UkxHZAfXr3mC+oW3zhB5iFLyrrinLj26u3wfVM/JhoEJuCEQlguzBmJbuS/oT2DoXKR2tNB9FnW5SvAeM6b3iEgzLPVhE9S0h"); - a("0Z6p4miwroB9fjC757F5Lj4TLMdurKjEr70E8e17afgbuQVN+x7hz2Des2jeGwbgtETW55nPrqhGIyJEsggE0O9V8YMvGRAZ9m"); - a("cyhC10wAmjfKH1noYFCT6stBNkjkBOFcgZZGkIE11eGpsuRwBOppcMJGiUDHX+ou1a4KKssvgMMDoIOOODQtMaFQ1MDCoNQmpG"); - a("wQaFwtXssWvauo6WbRrMoG2K4mAxflJTmWuvrX202267ZZkJPQVKqLby0cOsLSWrD2czMsO3s/9z7jffnRlG2Mdv/RVzz73nnv"); - a("s6332ce+45G6h32CwcIsM7KFIf+OJAjlOpsjtJbwPn3Y6+ROE46zulEAFRtlOWjT01nfvflscdxZgf5xmHrV0C9owJisGBY9Yo"); - a("gGZUhez/o7OVRAdeSvXDypGAGOAgR/xGIzGnvJ+Q56sWiH3E08QMFlHsZK6HYR7a8SqTbZjqx5LPjFL8sdTUIJKgC+jPDRzl06"); - a("LS2n8txpIbYMRX17t9NXeMgNEmiipnPuc4LE/G7RwNTqOeUEqgPYrvIVDmVGYiPT4sXU8EkUA25e+abRDT7YJOdQJbwWJN9DVE"); - a("bP1ovnZJ2TEWTjbWnuaTM7r3PMcLxsAMTQlpJPP1m8U+TVGY7RM4at8Aal+HUmSDyZFyHPPPC7xfVLPffS6i0I+0s47HztriVP"); - a("Bfb7HVQt0g8+yqktNd/ZBHq8es6HoM6a4eFxV7lxuYu4sMIQ4jGymR1UsOr153dZPyk5lnkq/EXq9XRqzXZcVKrxKshHjPsmyG"); - a("tqYYxHq9cGtGad0vesEKxYR0rjeEdbLe50VEmxH9FvXJJydpyDw5fqzlK7Z0s0a6k3jHY1m9BGXGXtZj17/mjPW/Lnb9aYVL01"); - a("a4tLAWDItMkG34ETsypIs2bPp32lBxxjZEjlfejgiHTFgaI9+bSe1yPosoZlYWV1+APimHNIXVX+BZja4zjjKi/L/wELgTIMk3"); - a("1cfZDSt15uB0clKiXrRe8kys/ThrjXz7IOzZbMMkfh7AZPU0QDLd0i+k+cQ78jnoH19HLA2Gnvf3LZPMhNYyKZl+hLRWhZS3h3"); - a("1/1/0FzqjqF+tkk6LSvUvNGGYhBFuQKl31iP6afJhKxA0zqeZwvSLSIQ0thNBTczT055fjQ46G/ogg2EGWqeMPlPh3SPxKxgcz"); - a("FezKJCW2kYSC3YfTVqjYh4hDvTmYugWJDZ/wfnMAqgr0wgyge5JF5O6BOMfAcljKFYhVbxkgWyP7WzHd/5ZegyMv6TU4jKBTSU"); - a("P3ghrrro1G/sC13jvTDB4Tlkiwdidyz5C5G2TuFzn3dMzwVrA9VJuScTSxqS1w2q3Zn5gwiGSWpvvOjxPdH8kXsn8Ot+r0r5f0"); - a("ZxL9FkYEznaJM1LiDJc4stkx5Ml0h//599EMwekkVEujtp++N2Y6OzwqmJPBirV0RE69BuHI82RXfHsY/rh/A98Whp/aLb6j/m"); - a("QQ/1Jfb4g3xOLvYOrm6JSo9Loe0mf1kL68h/R5XdJjv3feJe9vusqv6e5GXtwQ/jN7dOX0YKqxQXsG/JS4RpGqvDH615LR+IPl"); - a("hlbu3CfqZeW0dHoNQ4n4AcIKiRBqb33s9sTOf2WX/Ju39DAePaQv7yF9dQ/pv+whfSTSD1lukEetqHRTD/l/fLH79He7pEfLFz"); - a("CeI+Ngoz9eShei0velc7pRpjP9abgHcBjFxrQ5Ap5rN5P8RZ6ra8m7Cs7hfJJaY5iQaFmVjDlvTJ9K2xijOwP/Z+P/GfjfOibO"); - a("nTvG5DaPibesVlEOW8pr/5rXgtfTKLxH2zeDrlpJHAipwrawuHIt7nmO42MlBLaoHHnnGQjZ8WUG9yDIQYWp8hedxpC+UByScX"); - a("iaaEZuvs2wPNhr5eWQFC0g/VXSBJlNAaiA9Kc/Q+lPBv25OFDsp3sPyMIpT4D1sRleauaI0aiHgK0MD9bhNIb7ABavaukRU5e9"); - a("eWz/YM66KWjURDRqAizDzR/i9LbYHN6TxmXpMLDpJ/sLdKVFtwm8ibViCQhuB5IV1gJWRG1mo8bTntwcud+LKtHYCNEbaQu5C0"); - a("nX9SEYw0OfkUwAVz/0tBAii2WZxUKwrb0v5HuKo/BTs42qhF0616c07/CK/XKjFlt/cwaYJo6Y5mUDM835Y3Da+hPCYBiE3Vfg"); - a("/wFgnEvBOEnEOA+I85cm6OVtagn8oWgHehufDwC0L5R6K+CRyWgc9DcgpIEWN/NIL41HyiSPkLAGtGaF05qDVY6uDfkMQUzgTk"); - a("U0xQStPLbAST4WqQYq9ZVl8/ibSHRfguaUURMPA0/7Lm4luBUwmjlnjEkLx+Os+bFoA+uXvYA2tUh4wS7AWyTsfBfwnwSMNtwR"); - a("3obk00hTRNp//M2Al4WIn3d3yaBHUSw/Rzn9wsu5BLdwgVGiT65TER7MYU5Xe7chIlHo0x0J6cp1ww+9RYddzDyADvpOdNh0/L"); - a("+Q4F2iw2ZTh70sOuz89p3avJCkHt2ENjeH9dffAW8SMKUv3Qn497H76zO6R7v7v+afrHBatpOSfy7lScKdrTEQ3yUEhov6bthH"); - a("jghFuOQbhDXeMhyRvBXjPC9lHCGPVOKxxPVQvxTixRW9V7KC/FjtKTTe47a8KeRJ/M7Xp+K7fYOnEpzJbqKnozDTsj/KqJ3812"); - a("P5cVT+J8f+u/Ib//fy47n9/2X5t5/6N8r3pTy8Md6QQ07boNhxD8LOua2FSuGak+RhpP3cwpzGm9+a5+t9KzmKMLbiBZUvYU3B"); - a("InTMsr+3mN6Gl7DFCEui9aHzNJlC3Q6pTD5IKiX3JfiawE5jARQpCX7f2942uHXaU932xUbzQ3D3RgsWuasKrnAkwqWJWpjThH"); - a("ogx8lnoXN88braS3qhro2ICFCEb2BtQZsBddhQTz/h5b2DdL281wD8Z+Wt1cpzY/C4vDtD5d0WR+UpqbdQASk2bC592717yTnV"); - a("SCJavY9pthHNxB072nNaLzYt2gwk04/Y7bWYHj9PnHBi7m+UoTVI9pqW469RMS3ZEG/IN+UMjTN4zNUnbkfG8hFKyk2IVUsw/x"); - a("1JnYmgYirbQOT7AO1lGgR/9Qn80PuIJUDK+bTFdAGRE/0DB2p1pmefQbaBG3zbG9WknO2+psa23tVtK2eOeSynybejcZ+F2rDt"); - a("u5wdvtZGtX9Oq9xHxTqfs7093zb1MvpphDMcm7NeN8E5rNGZ+D2dyVPo7PKQ88gJCPRJWAIwYgrAusyPUXqXKMZiBfoVEk4sVU"); - a("hMCraOA2pM/RXF9NlL+pnv9j/rZ77bEHRV5+K4dJ5li9W3i1/FqNkrQneymIymm7hfIi9kpT6LenEtkJWhP3sa9JV8Vte9IKfT"); - a("L/QYOlhw7Z0Qz+cxhoLQc/RVmPEaYQnrMXgLDIPYcXYw9WhanLSZE2v/u810GCjGbaZ/0I+6VErnNP5ARXb9BQ+QMlH+QjMqsJ"); - a("vP/o1tqMQyKwRSVhmFeztrmp9f8yzZETWE8jz9hwa93449pPdbJ4LVS83PY7H2jARWVYOu07ULSVKn611A6uIJfOy+XpI6d71O"); - a("6pz1ktQoYF0sSR19MJzUIUDqSJDyAytF0lr1hE5rxRORtL6p12n9DEmS1kxA6if5glZjvU5r2+91Ws0IhtN6RNJ6AkmS1sOA1D"); - a("rQijhnT2dzDrvxgQUKcD/I7ZflHPyjXk4AQWY7jN2fzoojIcej+KF/GCva4RbcS7Dn1ZUF488mThlO7Ze16a/VpjmQ6awbmgwo"); - a("YANGYIte2pzH9dJmIQhUEJ1CRC01r3A5n2MCO3BlHEKHoKi3Es+46AFsLlBETJWdd5wf6yizCqjCqb2AIe5k1q7VHURSekGBMN"); - a("U1bwKTB+qnqRpqMHU7coXh9tNw84DLr2xNzwIXWRaAy9Xfx3HR6yYjip9Etwk0tQ9+8fZkOlYv9TRmYbSpE32JNi2mCw7THgDa"); - a("ZdIUvkwK2RkH5feQhtsjYUkvAxGvigg25jctldv2Fy2qJaHJIOZG3CPhrWHKfUhQxwAJQ1WNMP3De/PB2lVRBhnbOIM8/Wuq7L"); - a("RpwIx5PvalPHg/aG+X33Us+e07oscHK+hxCqEz0EGT0EHiJq76ri4iXDlfhbYO6K3rUomb+rLZgEMkCHEiwuUb6hhIXT1uNP8U"); - a("fElDrJge3ayz0/eSeYmP+YBgBRUxmhfP4L6CFPHYAAwfPbboMqfp5wVt91si3G0hRE3LUC1spZDiFMRhrC8Pyt1zjPkdi8yyO+"); - a("Sczf5g5YQdiQ/funOoYlM5A3uuO6p5hzuqrudXLxRpugBIQuHJtBf9gvZkUrYZpyPtBse2p8IedDqghKj6QX93S9F+g67uZVat"); - a("Y6H8XvRB+1KOY3d1u1EFlRX0BlAVvMtV8LFIp/i6D0A2mPrrAfThrAbA0iv09od5hIKan8wNqdMU+b1F+42ob3H/OINyzX7n3C"); - a("YnvPv2Wrn8A4Mno/o4rfQrbFxuftHuyrPUYVhHEOyoTGq/DaWo/cjmSXQbEYrtbwSMdB6qhTuMYOrZA4TP+u+W6EpNu4gjLdGd"); - a("Fq0PiqedK3HheQ3N/5v0mS33N+HKxBcBAp/PncTKxJ+hvcA2Sew+SJezcgIgteVSejkBtM+f19G+fCyc6D8AQXURBBVB8AWJ2Y"); - a("A0SXATILXyUka6VyKtiyB3DyCaJydyHXMFyZsktisCew4X3gHMvgLzUok5IQJzvKB7t6C7V9QiUWL3jcA2E/bcFmDOvIwxv3hO"); - a("x9z/aDjm54BA9wpBt1bQfU5iv4h02QUbAakPjGektRLpvgiSiiC5384kxwmSN0rsuREkZxFJO0g2fEmM0hn9DrurfE8dvohl8D"); - a("RqO9WRAOTeJSb+odvC8E094mP/GUwdz3NffAhTyh+zkNCt/LOH9K8GdJ/+YQ/pr/aQvryH9HlnSr82tF9/34n191l9sl/3N32y"); - a("vw9BZ93GreL6xamQ7q89je3WzbQ1mBD9g/NJbdM+m8jH7l+cRyT5cZL8RUTeJKhDF3sKqP8E1OEU02lTytJ805OVMptvulWxW3"); - a("3xLZMSiKp+yzdQ/KSJnyHixyZ+0uknetCh92ODt4FbRZIjlwSK1W17YYmVDhjevXuLja3QgC1RijPYhWc77DYmv+XyC5FQv2IY"); - a("AVWmmfGGw1rqm2LleKseb0W8GfHmAI4nTtgYS4QYsjhva0VjbPvrtPtZGKR5v4qIhPeub2JaIAmSE4S8wrdtVZqOkgYUK1C4/C"); - a("qbYVmi9+l1QDICJm1O6Iq0wdbVA9sRpx4ItzkRXj401/hV5l6jO8V7l5/yO70jTgcmKAzkm/amxBkqrAIH1npNhr5xhsoU7Mao"); - a("3hfTw9l+LBuaZIayoUZBltTlPrUVfcVtIJv8E9MwzFBUK7NxH9r0eBsNP+LTAhY+sHBnrHqKWmLvuj8Cz0zLoDENeoaL8fRRHi"); - a("dEV/sSPBbQFuG9sDgY+DLiPQLuwp97QrM8MsyvtepvYjRwd4l2HQkkIX9lWqDN5c8ha1QxpigSFkPLkzin1NdIznW8xzLKF5TU"); - a("DQRPNBd7v0zwmK+qGwILrUl+LaI08Z1S3w3I1b9EYxf07znsWhe0SEHbRM0tbpnIjMxK9lPSeLuVCKDEN81GOuVggO3NsC7X3f"); - a("04lGfE+IqL6tc7WfaiRaNPSPlgJsJtCaRxOtWaAHOTxg66kWUOQhnMdv0l29nAdjbQIL7T+dGms6wF9MygHxozyQ4R80H2p+g3"); - a("qkOC51wttJcFtMpECsd5zMxfm4z+WvkgO1q+8Bzv9iZRBrNnBNiUDhyZ21C6oGHVxrSdt2Y/SDuKVJ/Y+nzMF6VQECOr//D4dj"); - a("k53RBzhdKbexJy8fNPwwSEGeI23G/7Lg+UFcOTrDlQ7GIcmkHg4ykvsCSnNO9g+ZhS34WEmch3GL5eAQ4U0yNl7zP8wdDDnPlk"); - a("XD4F/HGSKJOZA7/ObVEKkrH1UXGmAifgAVEuGxdy4HRnhTmS4pY3xJvnbxWv+KRT+sQZys/m4wMsDmjKakfRQai0n9wMrT4iHk"); - a("n9gnf49RsB4d0PQvUcSvHWEyGolr7PeClj/oSF/E/9OJyNPOojZg6nU/i8RBy8Cp5CkHVROSEJUFj56p2icDZ0t4h9l8zKgFoT"); - a("zYeQV0bOh9BzQsi0ACSAkiZQouZDxfsEUwGm92UKGtxJWmSJb4EVLlKsBg4/TVF+1Ohmqmo6msDtv8IoX97nOk3sdwza1ro5rk"); - a("43nIwqpCCozjkiq07aniiG4hmx/TbdaUi+aYs5zrAEHJryDAJqpp7NXYJV8WHEcRZ/oCCUYT1lGI4MdZThaKee4RxkuCOUIZAi"); - a("bgp3i3RU3zNGxGzTc3gGryzY8msMgLs3bOA+hsY1vEN1f+EQMNDVof7oqd+ov3gAvbxSs8jfiLHRluz8PpXgbIIxBtwKUDKw/i"); - a("EtQijFZmDyncWNX5sYoSSzA4ZJKzUdmnTUx1Gfi+DUugkZ4H7ha0XqZUGFz/u2kdTj6cFp4tsoqZSmqhlE6RBMa5b3u6ouObvE"); - a("58Tn5UB9WwOwP5D8A0WUku0viqU5YMIPXi8vltUv008tczNbmKx+GcOHfwm86omxNOKH9Yo4j4HDgeupPUH8K65bnou6iu7wHs"); - a("ilWRPVxM0RPc/QFqjrzDQRVTfRfIhWcUfwIxJnGl9ImRlw2FC3OBCTt4g93wdgrGmeajxoAl98/6S+2f5Ikw210A6rYDugEiX9"); - a("CFn2GMnKdfCqV+r7qjjzTXxGeKdwdbG31GD0PssTEtp3BU1K/cUDl/6Co2qEMdr25awjJ2Q4hHXrCb58QLlsBfum0rpb01vh9s"); - a("JmSTOQxWtzMZDRAQlHnHWikxIsaXGsGxUaYTT47nCmShNMlebMn2KuBA9SBOtVwuGRjWSbPd6XhOZGLNrVJ+jbrUxbWfDcOpqG"); - a("Vp+DT0Cw3HNszk0xNfxB77ff/E702zbqt3EbANECsgF7TiwETuUuGkL2IxUYH3rnlH+ddclw6lmqqbU4f0a6taI/eoQS3IP8DX"); - a("2EDIkmMTgg4xfBq99a0kqLwjk4mwh7+6OOh3pR85+JN/BQJNS0CS1QAgxffimaFl8RLRff/oiI2jOB88h8y0yacrwl6Vbc263n"); - a("vjZOTGMrIE50s9NcSSsvETFLBhSdK+3f0wNl02tG/lBOQ0JnWDIYd4XnO0fS5hldRj114ynmkgAu8U+3ViQh/VJe2jkV98ucGr"); - a("4MR+1X6lI+IwnttUnEDTMzWGh9P61BxAEiZhWDOJcT4m1AlLQizhtA8RNKElA04Tdo1QtaaQSCFoFAnE+Iw5O6nhai9ovx9OHo"); - a("u4wMkvtXf8PNz2uFwRfvbcSeR4FkYrcYLZPE1OqbbhbmV7Drc/qGNDozG3YjnrdQK87nn+VJgieHwiE62zGbcRhMlqTZ/v4YHd"); - a("d1+xnbvp9Shd3PN9iu32h29yVKB3iBPRn4KZ8NvDdZT/GrQpOYjhzadISKTdP3mACm2GiuNKtrO/kUrW3SkmGzJtnTWx2F2iE9"); - a("82VqR0zrLLHrV1dB5s8xNZC+oBnfVOAa/jZM436rf4ODHw+fuwYCwvxA5VA2pRdqQfqiddNVmn5OcePeYCvpBJcK+Mz1kfwWGC"); - a("bk85uIoTCc4AcvB0Wfx4MSVkKxAfpEZzKZX08027M7A6PQDnDSUBI/bTALSbUfEwXiEinuDcTZXzTaa6X+4pnqw0wpTn71sj4D"); - a("RH3qo+oj+V1Lw1kGZT5IUiurVo8Noh7VFDfBHEs/CuzJ9pIS/erU07EtIcnzDoawCQsdzKHytw0bR81iEkDQHPv8r24WVv9oiA"); - a("dRlTZTlXRruS0uPpd0KbPLfheWIoqy9wt196Wox1Hek1+KgFaD6uM0M1nuTjMCqJtyPh/98hotd5OKBRT+24OkSHOc52TCtiK6"); - a("Igk0278Wcfzt1GEurLsOluu/ROYTSwbAXBUCuyv6EIVXNb0LU/VvdHGG61FdnAE5F82GVMeSusVqcX6l2bLax3lgmqwEH+SxQ6"); - a("xMnVKsHcPA6qCX90UF7nHuEnKQ4yWZB6JXQmdoJcQ+EbWq6Ie5ncj9ik358xsCkb0k8zuncWlE3kQ9L1pQWBtDpTy2fJb44lxp"); - a("fZcUNi6AOCGkkLRCmsFCRXawsaZ4fhqnvTm8nF9beG6gjE2nuJ5wcWuLQ6cPDBmKdNqced9XmEEhEE8zVN77TsuVx1QvU9tGHW"); - a("wRjyNw1aA+dhPmR4Dsj4vfpiqRlvUFv7mqCxofpjpWjQDj1yKoxpswBNWmvyBspC+1giLHmrSx3PyoPv88jAS+V6PhHLoOkOb/"); - a("RKUJeggMJwL/w5NGRHs3REqYZPktJgeXD9QbJOkrIkjnRZFunMukfyVJ03qIO3wd43FgyOKkfAXN3fkQFbeiDCW3IMhN9COgvh"); - a("PPtfjgESnffihCvg0IPjzULw/yVVpF0Chk+gsR0O0RNnfhD1i67HccjpEL3gFvjDAaEPo7QoMQov6cJ4ub8lB4owsBobojuLpV"); - a("Q1GBA6S2MC9eTFWzsBGi36/w6yft8YzQPkupModm/xRtStwIa+sB3HCPOu30naZ3VXs0xmzBaZf/UVH1GyjOck8V91aqgsMQZf"); - a("7hW52/Lib9+g0UPTkNXWBGkN9Bm4KMu9iKfhBHIUCmA4iEb5zqrNnAM1IJM0UJ65rRmiHUmo/B4OSXGnAywfMBg4Zk1Jjybfh8"); - a("VwtO8Sj8zccntmDqkwj41bN3IOlQFg9k0sP6rPNErT7rPFYrbpO5abl2+m2m+4+HdOQHJLK/lpqVpmbfiMIY70WJt1DiLSC8C9"); - a("KQvl6m58v0XEEH7wvQSKZzm8QbUanj2RD0pXWZ2iX/osXNoMV89zICdJf0gOiJT09q/LgLAYr/6Rf8lSTIkho88j0BguLYhaxL"); - a("USvWr1i8IVJfG65V8d+OFpxiRBXo2SZdRb6ENZpuL3qHPuvcZv3+EF5ES5RrclnUQs89g6m3gxHk7VakvN3z6x70qXtIn9dD+q"); - a("we0ot6SM/qIT21h/RT62OmR9gT3mTEIExar41rPgK1zX58FunY1o0E1DBCXB0AK5WxkoKpKYyFca7dLb+WGOU/ub4Hffge0j09"); - a("pM/qIb2oh/SsHtJTe0g/9WD36V/1kP7ugz3py7P/dV7Slel4InQJMsDHbjIv5wdi2IdWht5xF7TD8qHotGxwTif0KUj0W9gMka"); - a("WZ7dPnHVlxoIsdbpkfJY4Vdo4UM+q3jndJgCBmM5MNyLmTzNoevuH6YFCvyvsRBCPq0776jPW568z1kfMtP4EpWUfyS96NDt1I"); - a("4aePyjVWvKdTUrYgwWc2pj6L39j2xdXDZcEgT4FTjxoN1blE25PU0AYM9Y4vhJwhBymo20tloYXHM15J/RlINtgJreknenwfkd"); - a("EuprpjRygfbacWAQV9iCn+wbKY1nil/tYbR/RqDFHPJtJK6kbE+eKwKF3L9qdPS38RXfW/avT8bitAD9dB/Xwa8vD6DrjFQMmS"); - a("QJS+ibrvatL/A3KuyNwIGCNNDRymvnGa2zZUJP1RJDWQ/EltpxHAfvI5RJJaYkK+HES9fvs79fqNof1YJ9O5EVlYtkSPtaqnaf"); - a("IdToOUJXtaLP0awFuFdyftnTEYkRYDBKwUyKb17359tZm6SF9tnAiSaaYkEpFlqznMORic2jZNKZriM9Q/z9SKtaP+PfuDkU6d"); - a("3i1U5mHR8eSqo9BbLaZXOozc5Q1p7E+CSvHlsp+bReLbudbaUnRSjGLRSW5EoQ8dh2v5VGSDsWmq3WXMf804gCexPdl9zFNK0U"); - a("mHr5dvdw/uTri/eHQnobWk344e72J/BkvoQJRyxvdnw95SE3pIP3x1t+niEesXV/PxordaWRoM0htamSOa3iVXdUMPp5x42GQB"); - a("2mOy2Mj867qvj1rTXbo6uTQqtau/QU13qKVot8GqqwftheYQlIlaiv4prDPXle6GPuYPRoOjvhciwNOPlqDlvdRrWqTuzhnkoW"); - a("zrufo0Twkp6v6rmAtw8g2kOnwd2TsbDAlgqn+IaJwSxd1QMPXpe+MN9Na8DyD4d4v2MRPln+O3PdpTjDKniPuUXHXJVcKWPOuj"); - a("8X0dvVHNRskG92BEMu2f/05oPwHjfNbqE4/37uxiA7Gb94JVq/6r+n1cyvU7B1XBWYwpzfitXps8rb4r76H69hGNqEFkT/WT/P"); - a("FibP6Q7697SF//P6a7Snt47x/mM7SwlvzNNbARuap/8D1ThNVw8pEKH04BC6LIwuXIzCpytL3Pbg46YLEByvUkg3Ec2W03d1oe"); - a("bKpuI/DIHmKvFSUsFaJLPZ816mVXV32SJHX2FHFaPPsf4ZNQ7PexWB2yS2QrY6XbZHr0+q49nk+CCa9fTeWn/MOz6FzqHpC1in"); - a("7SskgS6R4UOB98+VocG7Hy53QGbCwwhx2L1/ipxntOTJqwEJUoYODGfM+M7gOf5ezEPHrrVFmnsPEq7n48Z07tPn1U9+kvsfOV"); - a("+6ZIpKj8lV2SosYH7xmUeIJZr1kE2b4mu7EyrUcMoGePMeQX0D4BrRHQDwKqEZDpOENVAvq1SFspoEEi7RYBXSCgWwVUICCXgK"); - a("4W0BwB3SSgGwQ0/QRDMwT0lYCuEtC1JxlyCuhmAU0U0J0CmiCgOgGNF9DjAsoW0HM/MjRaQLs6GUoX0GaRdq6Azj7CUJqA7hBU"); - a("+gvohICSBTT0FEO9BHShgAwCcgjo+BqGfi+gwwLaLKCDAmoRkCqgTwTUJqCAgD4T0CkBfcRQyuuQTqh9DoFXir7Xtr+3+vSd0j"); - a("CXvlM6F0EIHGajlci2HQ8f1IrJfLFAuJCvpv6d4r7gOFMuaIQ+Z2wnSXmowL2GDwwNvcSZkRTNJD+GbOe+fgfqs2ay5M0u/vke"); - a("6eG9+NuR78UPAj/cOO+NVEDmZOmB9jHdA602uWv12UnoqRcSep+I+nC68PmhdhTJlCh9caSYt2K2lMmx37+vi9ke6CM/Ifw7qv"); - a("yzuYN/3tMbpxYVspd6IiKUxw//msS62O1Suu70USkSjvd4Kqruz88DWgstr8PnegNtU9RSVBRyZniEFO/rQaUEmZgm1JdJs0S9"); - a("HpWE9jKFdbtnD16rLY9jeHkU9VS4njHs/aLnBwaM0C8+1Z2/mO1ifaKFofM6cdQIiXgcvpPwGW1ZW8nWroP4J94VD4Brd5eSMN"); - a("EFN5sVM0ZS1Sy/N2V8YzRUTLbXdHrGCSN7nix2SLGjTWjgt35IDbpS81kgnnwmTJV+EzS6LQkTf2agR8oPYJ4/0521Mz+l/Wsj"); - a("VKwQ6KBAIgJHEJAmns6g39oU5M2veHeqzpjEtrGS1YUT6bmV+gGOfGd+n9UKAoW+bXr/lJD6PbaBbJ9vIlPqpw4TlNaAUvs1QM"); - a("p3p2dY7pmKEO2+2XnJ5w5eCy/L/lSdiwoUbMQesjw96zn8VA7KunA0oLNgSqoyJav3+wj3QXiJyb/J6CI5UIIPBEnbX4japP3F"); - a("1sh6qQtEjQaq9zqoRt5jv3Sb1R+m8R5Q5g9bH5E9XWRHwNEQJ7bKDmoPCBfwFvgs1SEqn6LmMln1t6AYbscw0j/jU9qT3Vz0W2"); - a("Ht+74OKAUZoU8wHUg4MhZsxIOhZcOy6Mc9Ee1clupV41aw/WUnvQYa6/KL9/Om4hp9ivy8XJ8iPy1nCa7L0H7MSFt9BU2y1x4n"); - a("jstVzwLjk37ufiOpJ2NvAPH779ogfB5pheAdulIz1qTeD7h2e3qHOxnm8G2QSx8H45qFSf3AJchwO2fIRoZsTuBdyjlIuI4T7E"); - a("iwGzx9ChVTC8rhvYl3b/yyAuojtgdGf0YEssjGznNo5ktsReBcF8HPa7A90JfhTRq8lfrJSrJsUZypXtyKoFGu6jzSx1gIWJlq"); - a("rj5GJC1rTwKsbqewm/QlLGsDiECgajD+uEe2f8bZUzZ/ST2R1P4uT9USflWDnxSwqBm1JfT+GaxhTxNTHE6gYs5z0kCHz320sy"); - a("NOIfazc2VVt50vt6q/NhjpjlXztTIIulqDUZSbx3klRkkr0a8hJALhGLrXM0DdeTlzWf7VjER8UpKPMXaniAJ2QcYfmieuE7NE"); - a("l/1u8ASzwVNtzAbd67MXsmWp6dmU70+0Z5iLI86kDKemHh3KLOmz/Z1CZLOFsm0/IbLlT7K5R6Bcf7W0n7NY2s9ZzIw7DySjaE"); - a("feb9NHQuO6bEwW/QiesuIjcQ+g/TF9TbBl+JrRit8c/Brxm0nfyyBZ7DNS+PI0guJ7WS2KnL4UMxLmsKLst9TJaDBwXuclZ1IZ"); - a("KsZjXH0nM64nhfZfIs0eKAbQqQEo7emVeml2WVoBgvxg1DOYembycT4Q9kXKyyKrE2Mnd/IxxoMu8UDaoO65kgfxy708iBorsK"); - a("6IkfXrluFDAcFsWf9cxfQjsEPf4UC21xcY53e1eJcC2diH+qlOoTBEPQ9b4wziYXg2OBzfo46X0sVHm/Q/DdbVHZ6pqCG5FuOl"); - a("Wix5mx+kDr1zqbMOJgIa7GITBrqVoKu9f7MhyFzbzfn7dPm/ba8ndNB+Z5n0J4tPR+wa/hhlsSf2e4O9VfpQen6pD2U5gjyUun"); - a("0N5kyefW5ERBZ9v1W9wZien7j8YBmCPb1JGDLdzt91vmn8F0bMTwgUUMCCQCEFejFSmRxTfA78m0G/fDak+V9W6/Nb5fyPIPh5"); - a("Pu4WY38/vo/0ZWa4WGYm0TJzFi0z/YT9hGDEOrNvuV5OpSynAkHx3bDvCjxJjq6nS/Eui8cPu3fWfeo9kB8MIopsNbiUcaYbsE"); - a("V3+TYRIjc6FwUulgWaZIFxCIq31r1Fx8jvJGq8smX+Nxfq+ZsQFJ/eWcK+hVjSXsKwQF51Wm5zuo7/Mjn+kl75Qn3854nx18bY"); - a("PT00P6Qj8+9l5lyZedxC7r2bDQGSOq+QOAMlTj8EeSQDsBsi2EZWMbb/figX+iBuXUC6zjaoZQbyhcpaNsFwUTClLnkUfNSpv8"); - a("EqBPWOUuM/S4wLbYK2wLQyZibe3n1YnHdq2dau+Ul94kZaxYx32rrKVqLl98xwTGSpRrolcAX1v6TL5tznfuyoJ+5RH4BIIvO0"); - a("c24LXhXErJnv47wjqFd0/o+0/NOLabHpdBorbFLcH27fbKnTwHL9YJmca5sjxrvjV/pwrL5ZH45VN+vjfW/0934DIsRqdCG+Jc"); - a("9VLj+8dGOypHIfuCNOXKcXs+bVnSj+J9wuZ2CK0P+RxZ0lixuAoOAQ4qJZEufQAh3nuwWxvvXY73Wx/kkaz0gaTy/Qm7WODbuG"); - a("2vRzvU2XUptmuvyWF892zoWX+Kbl/eASwLcns4nUdfqjWdze3ny4QQz50dHa9uQdepmXyTIvRVC2rVrinCVxBsi2yXE803pw8N"); - a("bu/BVi3JdjaD0q7kc6urgqJP2MpfK92nz5Xm2+3jOjjaTfo1wZ6pvOUN9YalqElVvL6jYEXBGOD33NcKjf13cocw9dkBxgv78w"); - a("oHsP7T1Jm/apVTwVRvpCrBgfPj9+NYPmx/wtND+6L8ep+W6EdPcO891iTQvJCXqDZ+jYXAqK7KmQyt2J3Rd0qTgXqsaIny8AIo"); - a("YSyZuQDF7WxuvHJXpPrJFil7td4eO1Q+K4JM5clxwvWlp/Knze4ytF3yvoe2WeXGblfgFYYSxaKUknSdJmV2jmHu3X3v0fczTw"); - a("pkLz7/wMC3wPcSK+tODJsBfsgm9il9dLlvfIPL28DfN6Ku+9yPLujVme/P4Ka6mwhyr1wsbKwi6Yp3PZBtpaVmlrCAIbQ2vIbJ"); - a("nz8C/0nN8jKNaHnwMnX+JslzjvIihG7nKXH977qizz66YH6SP96XEe99DDq/wy67LeiA/OtPs5Tsyt9toJcJAx2Wbs5j6eOxMz"); - a("GvhqrAnSt9tZIpmPHQEqUPOD2DpXnxZfzgJq40GeVszeg3QOvN5P8k6BZmfTn8FU6h+Xj7cPgSJKfyyUHsfpfWU68XDwoLhXAa"); - a("JbIDppv9rgArLaf2ssv96+1pFB5BYStMa2PonbpbNl+pcjJSY9wXK+gW5PzlbB5NHp/284JN/8xW4jyzeTuso3Wd8Eyd3qE50p"); - a("XTEWmHAMt6wKAsjiYM0HPPWlWWqaObDIUrNGmwxrHgoFFmuBVaF58q67Qkm/DAXcIuCeT38u46ibQ2krOTDfne9VCyw1t1Dhvz"); - a("KS97klIXo0yDy/+etb8bfZ5a/PxjdKv29p8Nva78Va/EXab472+7GWnqHBuzX4E+13j/Zr1NKDvP5LZmF+8u4zYmcaxzQhXNoX"); - a("R9BFISiBoOwQZCbo4hBk1TG9e206jZY4Lu6M7wuhevYRyZB8b5XmBKtzJ5VN3kvPA+1QOEgLDMA94tEdJGJwBVM7EICgeVhnib"); - a("FT6UVuGlpg06vU8Yr008D+OeAFLKF47hsldWOaHNXLDZTqHuiAAvKUuoHZtIPp/bi4X0VcwlV1E7Jx/0SOO0jPqiT2O8Mu+te6"); - a("WZucTtzorLopnlOlCt0MCNrqE4wGticwNhhEtbduK4QHVge9v3di1bwfidiGCN9kpkJQwEMDOl2mqy3jMDfHjWXhf/52owEm+t"); - a("v7AJ3Wtz7S7iIcGlEvwG1ueYeDLVp+x2u3PTtY6jsM9XX4mXWs6TXBWJ4zxlaZCIt5/fjMZa8JurPgkJJkVY6VVcbh7kRE2S3r"); - a("WgLJRDfQy+VHsp/CRNfzEr1bA79T5X2HqPIfAuBivoYeTe0cthBTooxpap+h+QER5eZp5Q4KXKiVW4AER22RgeyvBUZ1KX8gl4"); - a("85T6KF1eMvjm1F+D4EiIXmBK2C447N5uLZL1RjWzyE40cQo07cyXKFAKdikBI6UDVpmuYMD8oi7JuyQQ6WgOYvti37GYeU62zz"); - a("62aavW1HGcSDbf51zkVAlH4Hlf4GxFd6AoYZG35OVlJuQDJF1CU3kq7/p9gniXOwQ9QUCR3OuezyWa3aEe5ZOEo+QPcLOIRuM3"); - a("3zrpGsoN2H/D6TsguaSEWHCRf2qBBFb6jatJkplf4s5gnpEZpuBvN+UN1yAfrR9P1tfIk1ZTGqP+4yFjGP9gdTnwcNEAziX/sB"); - a("1t+CjxatBPXbJ1HB9l1EvmDvFHwEML4+ki+wd/uKDre/ZGD638DFoNBlGvoBa7Fe8z4KFnVAj6g3xmMtnIg4lz9kexFIdkJy9w"); - a("VCCyPkAPaT/tcO1m1aNVroNl2vtoJoALIJb0EWmmBwTxNvT6oXoSG35nFDbKC3/b0QvSVMrxGwX/3pZu5/ddMefHN98afFtP+X"); - a("2tdsumyn0DBSig5ryiRS/tD+pNh1TycrUyPd6DuYWC0grZGqgfgoBiCmniBnJj+gw066AphTs5F2pIIvD/cuokxNkCypH+bQQX"); - a("Tc50hA+scifSvStyVYDU5o7yOGiHkuXFmQ9ncjy93qUh8HQlHOWxByvXrKSDPNa2Npj0D2wQmf65eJUkmUabl3WjBCR66rPW7K"); - a("UzUKdK/U6c4TdF2gC6r5hCHGB1CWgCLXWZACgY9YUFdmR/AdEXQi6A9ysAx5vy8XeaW8Fen1J3CndeKfLKp8IShEfTRdqwelUE"); - a("PXj+ZO6NfQCTz12gyeKjciDkn1nNS/4UdKmiCSnkScH2l/1dIOU5pNpD1EaXgP+Tbx5GrwMtu/WSjfB8yMeB8ASJ2M7GT/RiIl"); - a("TA9HOv0TIA0TSLdIpNenhiM1AEKrm46j1aZ/Mu7lEnfE1eG4QwEBdz3hfhJg3P4S9+Mrw3F3AALuLYT7N+C2/yiatO8WPcO2q8"); - a("IzbAVUgvuQd4yGl2hHq35zmEvYKDOYImoenMIZypBBiJ1eFBlWyAyFEVW6HBAyXKhnWC0yXCUzNE8Lz/AqIGQ4+HYowwyRYajM"); - a("MPya8AxDACHDu3qGEcggOTOW/s5WIW9yFfpIgYcuPnIJI+LWlyNCq3qRb59ly/vCgI47E5KnuSpOGjB5TPP4AwvZzWDV+K6ECn"); - a("23pmeErMaGE7kQRBDv8i1VhUKkXJKi9xv6NaULxxSusMvX4SoYbSgvcmWNhmzDlRX3Rnke/hoqL3BlxcP3AYXd5/HfQa4sz+Dy"); - a("c1xZiTBY4soad165hQ7qSxL9sCkdSGLf0MIvQ+xGv4f6FsJ/420Z1OoOnFXw/lztWEFN7qw6v9Dnpgb25gZGZChABiS4Wuzqxg"); - a("RxLykX3qj722VCeentlfiN8uU/LMJjv5IU0j/4/DqyX4he1OVGkl65Ru9X/wG9e4jeQ+H0uun/6tPtpzwm6sBeove677uLzg/v"); - a("u3VLRN+dd+a+MyKDP7rPZPsuqtTb1Uuxn3TuUKllI0TLEPUTRB0Ia9vz18ZjPsiQbYvq/zbPf0bv50Tvl7Hpwb5Af7qfHER/bP"); - a("jjGUFr7NWjWMsiQPKh6Vq4D8KXpnPYsqVZkoqWv2L+guBcySX99vE5n3qb2X4hokiAekkTaGr6+33J5Io6kFrj3cYmmz0H8r5Y"); - a("8Z7LT/o6J4S+zgxeYM87zdB2Af1WQG8L6EsBvSGgN0W+8dcwNF/TYxJQ3imGRgvoTgGlC+hbQWUUIHXaSGqlaY+DRBmmffjZmI"); - a("CAikD7KRfsbyKA9AP4kad8VsUrwzKYGveW0YCgHcGPibhid4Ly37EKdNHvXVnwQTPtdUYrpmXI5T0aVzEAI7YY8idhIvrrbLIy"); - a("3WI6DrEK/XPR+tfM69/L2vr3C7n+RaxEmwCpf/xKrH8SKaEkYv2bCqRqgXSLRLrQEY6UCUj9mUAqkkijneFI6YDUSwWSTSJ5Cs"); - a("ORFgFS+wPJ5cf+2g7gSVvU7N9V3wOvlPUPVX0T+KBGgrAMvCN1CHXO1xFL2+dXxJ4nZ6fjeWP7b7m/fNvXlCRkuOCoYqTF4Kjd"); - a("Wtua3uGobazBfnSMzd1vjNWdMibbPWyM353TTrIirDJbXSN7Q6egl8FhWdfUfi3T1OKTEZ/A8Xxms7y4dfXWY24c7uIwdg7L/U"); - a("2BC2iOXnnU4hnknAsHrYUJmZor2zR4tDLhJXVgMD27Ti3K3umH/8Gimp3uRO9xi2XtdOxC+JW11CmJtR7iVDTnOCtFscUfGMV+"); - a("hd3QNdyjPUqiq3+6s90NWB01GueOwvTJRsx+OZ3FLTjXauc+9CCpCKxNz+BLA+FOTr1reOipg7tEro91wtMdz3wE2DQgm4A0Dc"); - a("goUWqYGKnrK6AnztSFoAizCkhrJUQFuALN6RVRMCL1CkdAGaQwP+uDRqNh+VTMAfmPpm9Hcnki3FlZ7ilF7xTmHVwxEFMF7l7o"); - a("iEYS7fXPsY1wZWA6FJf01viSmxx0Hm0/m3L5VD8rlkGGpC9o0v4/68dCvWHtt5qSjZH1zJWplwhV/XXY0+qqNdld7p/LMN9Id2"); - a("185XzRMIp6Id3PfkMfTd+A3xJ01FMMHxdIWadZRYE64wlOX8v4jnr8Ed9+AwlYVM9QTdK7MSHylprirkPh1AJ9PQPpbM24SiN0"); - a("cUux3fnAJghw8VH6sPX4Vt1zdDHuJ9N0Me5HCGKshLUJfhBipd8MHJKHUCAbKTYK5LawVgo7IpJmYoShpC6NeWqI9rE7m2P4/8"); - a("Ry+kGp703oKJUolTayU0GmeAqVqmyEc5n5qi8nOpaahcI0Dxe5DY3nCwrImM9Hr7Kx4Fmv07R6NqQgnxzZbSnGIB8KphYjkkj6"); - a("2fuch2QZlpoHQQLlWcFNLF3Hbu8+rBoOiKw+Xd5LLcpClRuod9Upz7L6JD/i94H7Ksya3twkW6HvziGaMT906bDZepfeVaZ3qR"); - a("dBZn9SbzGdulHH+bnEmU04vjRqknEN/sRyNdpVPifVJrFd/RhdWOp7T7kywbvX5ZlTfQWJTj2DipW6o9SIJ4UCSGIR7IN5ybY6"); - a("OwI5hqajnOeM6jzQwft+O3/RCGRwv+MKFgcVB/BLfMdKyb7yuTiuFADmcmyWmpw4bvoo2Szlar1ZtQhqX34ZxoXdtKz+s5FzHJ"); - a("6l57i5SM/hQpDQ7UASNVSnniSNzSN7LMVNviZy6ZnLBB4VONBD+NaoGVy+/UvawNUwgogJYskBSquOchVQnApXh5lcaKstvYjQ"); - a("MOsJpMwvxcZ0GmT2oYK6ZILc5RWjISzXD20i1zltsgjv0iF4yH0Hs8c6jlEmDiG56LbVncvmsXV5aq2TO0f8GruWSPIpDUkZ2K"); - a("SVfklk6R6t9Mf2YdoSyHnbVvzF5Q/rqWOBUDdcqWEvArZL4R6jnU0HvlllLUPqQKisBGbgkxr9CkC3PVQd8tUWCgufbbJjZBgv"); - a("Jn942aj5cHuLZFAi+BqCWD9BErlh84SXtSiXpd36r91Y7HtfsyBnB7uzZgV7pi2huyS6ujdDkufwfVikuJwO8TVYVo8DWvu5LE"); - a("sDb+dCEpkQ8hFdNyGuMH+RuTwdf5MrzlWwYhvdJqzqlf3VjfcJL2obasD15PUcOAmWVTtEyGzx0uRHfj1rXkPAoX1zOLvwElvL"); - a("H96YI/zhJWsOdNtzjJQlrjKP1HDtJWDwW47pDF6o9C7G5hixDhR7uxqyQeJJJbF5YDbLl8keX/xkM1JAB1uSRkFJ+5jVR/hLF4"); - a("5qgN/1oy6Fr056/6dZG3x6MMvXqADqm8J8m2UV2e9hQV+JuLXTutW3i+8/eB8fux8Tyq+knqmA+1x829SNnvH5sxPK++XPNlck"); - a("i/GwebJR3nwHamt0+CY7Q931hIGmlWRqW3C7P6w+5Q8AI5fnxLIIRpHnmX/RdiXwURVnfDcX4dxFCARFCQoaBDF4JgZ1Q7K6kQ"); - a("2NAooWlTY1YuuBklWsIQmGaJY1uPWqtrXiVW3VitaD4pUETKJVDIgaATUq6ksXNaJCuLL9f9/Me/P2vc2GXvx+ZOfN+c3MN9/M"); - a("fPMdwOl3R/FoIfQGhco809nlq2dB7JXFV9vl7vqggd7g1PdXlu/d8lvV3yjYoyujugWCky406FfX2Qb9+hJBslRw/eF6viEqX5"); - a("PK9yqCwlLBjnlG+m9U+kpRD9nToPP1rVCHrDl91YvMG0MPv8pg/dhFxZQrifVbiyWpTZ2JEGzib/cRs3kYPrCGr8dV0AFZaxde"); - a("YrRB8EZE7/+3I/zHG/EnjxQiinbgz2tf4s9pzBlPna0A084yAPsCQeF8YgRgGN+IBrdcIvRRqvkmtQOQm0ccNb3hY9jWmfULMx"); - a("Pr+5zSZ7rir+MRlPFZG5OprHbL8qMS119ArlLQh+hoWzbpP9GaYNV36Cf9/X7SW/pJ/1PidODFHJBX7ZrPVDa7/arQ4e8QGoXw"); - a("5rEoWrfL5i892KN7yYdXahhpW58VGR4uxvZCusfLoTFFUSqT24+l2JnXW73erE8p4L0lmmi+lGNuJSnPjl3v7kas9uHNxFGuEz"); - a("of3h4IzHSn8FmypBscw8XvOHGWlHbPutDpLRc6HWwnG/yPr8mvilf4kfonfQLSuenaBT8YGHEQ7V+YsP0Rpva/0tD+Rf23/8H3"); - a("RvvKH6fS9o3nvzhhOgBnIULccNnddybCMrOejqufNcmsH++MhnscKiWu/JxqIpnrofd9Fl9Mskazg2q2BKQibebe4srLBnqk1O"); - a("6yXiTWVA5EgBzsVE3GUD++WQ31L3Ig4eG6gIeaBIlYwlfTloJWhblxbrmbZxIVh1BxzHwvEvpEj/PPK6uFWtEa/PiDjzbyz1Nt"); - a("/PN8O/+80iFO0jg6lHuD66FAtIs1KEdDybkncliYxZ9qfy18IM9QPpC9iF3aA+lwei/6DuDme3sCm0TciewAcLUYnn2+BtQQSv"); - a("KLCJzYaXNFV/LaA4Nkc8AjUuA9wut6cX1x2Xs4/qIGMb509r2bpIoiF5pw2AUc1giH765mHEaYnUUAhzWJwxoG9p1/qIE96kvg"); - a("8D3n6wP7tBzYCVCIC9V1sjCVGLWQGLWQGLWQGLWQGLWQGLUQj5oY+INf711VidZbmQnWG74ArP+c2+96u7xbrXeTfjSQeinrSE"); - a("Mer8dw4GBDvSlo9bhNqtUucOS1u+ZYUS+pm8+uwR5oBNPuobDQzZICWAtoMYQWQ2gxhBYtwt6J5QVhT0HBiGuapNOQkSou24xX"); - a("SDTsndSpN5lOh+bg617nDghGVKSCV1L9HkLcF6dpBF8hitU229qXU76lvljF5mA7QQFtk38MlXRqK29MoI9e0k1rhSwBFJCynQ"); - a("HDQCwLmBzXloWpO95OXktc3Zl/5xiNBfnu4Oc4fCgQzPLkbRgZ40mAeBPSG/g6JlGEQJq4DO8sous52zPEd3z77rBjrl23gDiv"); - a("UdgRbFTyuab0mxOkA5qyTWxm0mEhrH3Ru9BMtojyNiqFEtxxmKYtbWqaNkwDyo0/zzpNt38tZA8UqnUoghcfvxT8Oy+1i1gp+F"); - a("ZhvjoxX5ofS7C8CJMHmgXx2xGYgk5MENKaouct5PlCSqdDiE+Fw1iuHXSOoIX9gpM1LGndenlGcXC4CbkoD/WMC1acyW5iKnIp"); - a("A9XOg1bPKuciZQTa6zCnli7A+wP6rk2twwxSrESKWHnc1dolBX3hY42tfwCK7V/228+7nKqfsnlY/XMT1mpXocFyYHj5REf0+s"); - a("NcL87tLsI5lD3bfAY8EBXOSI9kUBJH/9QUzVXBMUPUVdfBxt7gBycauIKJpNPQX/U2ou01gwmjP17oBOXnriYjiPTVSG9Hettg"); - a("QTLX0DvveoVJUz7Fgn+xVMekByUmeSPYOS7vu6GAauh3l/fZ0ABTQ09QQ7NsDW37p1R5mY3F97/Ag5mAXDu61oIHB+1fnxaedu"); - a("rFABPO+4bR7jpQOdSPo//EhKYUV3CPe53uL0Gl83dmfPus2MGhwkZvcrPRaCZM7Fadg7e4Si+E5yiFIyeBcGxA0lKXKQqi2WF8"); - a("pvMnfPyWtWiXuaJRkplKLswE5zAT7xnd8aBFD72s81KwTHPC45r8HRQZS+Zx6R2PDeE6yVVDZmQA0RLnuZmqD2Z+uIWm8hgSM5"); - a("/dXABWENRPMKcG81Nxxs3/+tl/6blvKSxpp7GCkYelc4LthEJNe4AfnybD74WvqScJ/ASMThqp8lXBB2FrVTJcF1BEatTFBu67"); - a("idSnYdQgUpwWSPOHytIjZ/saQGVDo7Qb7jOMfJ9ILVYRvT22WSHvER8BeZ/xW+ntOI3pLWTr+9jL+8c3tmeIEH5BDI+A/hgh3n"); - a("BCvCEG4tl07+znfd3YuE8y2gEo6ptl7Gjx90eeOS2b90GyCV+YiRF0Vw1iZGM8SuCvVvm4IpwaAKmkTMfSAfR+Xgh9g7Kv/Mll"); - a("mf78MnfVaPzNqhoK5ju1thYPqkgPlpH6Zjq36WyGWydiLv1xSDSKlMyC4AG8x9i1eGLpuaatzO/LPkCNOM+vEef5RnGebxPn+X"); - a("Zxnu8Q53nd+ZwuB1C04qocOg+zKJR0IgHQvh9A2YA+eECs24Q07/KvWYhSiQcY4vh+cbKWUvn8noG7jzx7M+DvFSEqByZQ+Our"); - a("c8VRRj/eDlbH2wmNCgu7O4GFg2fqWLhcYuF94FpHCk1QLOVK0lQln7xmosNUScs5eiWvy0rmoBJeXehqtuhqNnf13X+rq68cZu"); - a("vqPwvNXd1f2mdX80xQphKUWedYu/rX7f119YdXVSWNn6CSrcXWrl6BSsJ6X/1p9IjTAlKarZWm6UabSyDCd+ReuTMFWTldoFJI"); - a("oFJIoFJIoFJIoFKIUUms/MTnJ79xfBppP1aU6+eK22LOT/K4NP8qfqnNIn2abujTkAWi1MdOTsZ3SY5xUN6137qZzhBbZr5tM3"); - a("WNS7yf7vsc0/r+Tf/FfpqtnQrPjxzoTUGAKd1JVwlK5yJKN8igdIreqP0zK8R7q/1+oWlVd6r1b6cPHdrVpybSv2KZWxomSqDu"); - a("gWz7cgDciyhGhzGK4oGiHHxPJumB93X3hhBaPX0RclJkE6PcXA3FurXdAaeDDogYMOGp03Ub6dDAXaLy1wlfhuQDMeSF34WUZr"); - a("xFkLJUyrTGSDIu/TW5rsDF1Lo/RE1pobnINbKdK7+oSnINphspKe1grU/GuuNO3wglSJ5J2SFc32jUP8USOIzObl2fYlDyL97u"); - a("uv0Gk52xh3WDXmuFglS7mOnY+YXiPC2a33KF6obBQjnHEfc3mwYlG87o2JkL6jbfefXi81DcNM8J9UfUbrWR9kejZMx5pFO8zx"); - a("fBvA2em7R5qfygZ7tvgcUcgx/t2iwI5vOYeUWgR5uOgMIYtZ+E+9pPfKy4Byxqp+w6NiktPvJXliaGSRqI/xniiLnD90/B+ZmF"); - a("YUJUBw+VJvALvaaLROrOgUl86RWl2rVfohSS2xkfG4hy7IFsr+C6aV/ngkCOh9AUKDDRJu1JrDMZ5oyN2kVnyIn+rrcPuqbWuB"); - a("r/2iXZjsAwDKmdpRj3PpmlbUpWOazpbJ8YlcEgEYF0zNlGVp4fLK5WDz2m980Padf5B1g2VaPEcqQb1CFESO8QtEfWQ0SQw8IP"); - a("20BeRSkYLh6FENYAJwJzcH/CB5KBarVFuuPRTDFHwylB5HTIM5kaKFv/yPMImBi0FbFvFF4B9vFQ+GjtAknSKETsix8U6DTGIU"); - a("je35/SnHQA1yaW86seqzmZ4eYTephH4FlOAsrfh40Oj4MRJzwK58IUI99ia707nJxtcpTNtobm7uDMYxmRmnW07iS7ORfvqG7n"); - a("sTw+Sn6+aBfioo2QvBA8I4Aph4pQCVOCkL3/PVTyIPvPtJs2B/ZPODGsyLXqJMA93CGn+a6oevSJby94lJQ3nJmlHcMEpEl7p5"); - a("w9sHEb1V9YZBnt66MqrXZhNmz/8FoZRBW8ut9sg9a+X8JJOTb6XyC+9qZsCDuQvjYdpocXsC0a/nty5Gx6l8WAB7cY7HXth0KH"); - a("g2whmOKTKX4bxY+yx69HvKK5cd4Lgu1ouDKtKN/jrjwEVLyEGJQZX+ANUVuYpDBXwS9MaZCuFt1Fx+/CNmS/c8bkz1/srkxnJu"); - a("qAKpw1BuPiiiYeoiZSqYn8xSMryAaCFNyi25m2LQTkXDzSqNhcX90uo7qRRnWzn0N1L/DbPdqrOhWVVg0S9vQXISvFHeUrK2Tp"); - a("MNbhSSLwQzPd0NNpI2I0aBDNGa5D9s4c5H1uiXGfm/WLg7zPxa8ft7D8wpGBwVTpbKEvxsDOxuXspHak1ha6nX34B2Lcqhgr4G"); - a("jBKInQlRSS7kUtCG25HxrXQ7KXV/srt9PPo9ZSPKmxuKkzmS5vrKXlb06XCNAwslvb1tsbDRWOPN0BcKuOaNKS6D45auOvRvrK"); - a("Zo80ZjVthVoXgDw+fTOZyaLtr0FdGtzyvF8cbNfP+i9vJvtpp5tZ/yk4Isfy/a/pUETANt5isJemwf9R5ALYRRmJ1PSqAaTy5I"); - a("zk8neNo2oQOtekJcMp8EREgeWuRyUh6pDam0ZSETebglpLTOZk9Bpj+CMIASr22dgy0xqL4Gs1klzb6CzIa8IlGd5XC4KNM/NH"); - a("NgciiKlOW8P0GNnj6jdjDaQSTqv1dAItgOfpNCfRJ50AGClwf+nkPmZxDmYRrK9gN+mxwR5XL+ZHTmtwejfhWSL/xbU3uh3sH8"); - a("0F9tHlDaVRbbN0iBPs27+lM0r2s2t7oxVifbJ9KcsAmfnr++xvxnZ66gY9nSepqIvp53j+eyL0ta001JMcn4ZmJ8enoW78jXM/"); - a("SVf3k3jvG7V7nYEMfXc3rnndrnF8vAC4lfo9D9wk4/hRcWk0quP2om2Y0TJEcA3gC1NepMnzyZnifJKr9nkzn7RH3Os0lSrudU"); - a("e9j9NhL06HfDSSq6J/+ibIylDz6Z/isAcfLsYKYn/iYVj7FH+x2t1adp7Twct+HAKCDJ18qSCMbiKMgw3CaKEJdnuPHfxj5tk0"); - a("eHv4ZJyxqRejdPhCNhpofvMcpr95PvjzRG+ehz2lGAeXvouqHsqzvnnmQC+R+xrI0HO+t4Xeyy6mGpk9K7j+p+6luRLAWrgCB9"); - a("+fJOpPyeV992fjzxL1Z+aTqj+3b0JVm3Kt/VnwruxPxXgD9Pn7hdNZOvIEBvH0XXEq62nau2P3XyUuQ3gPh3F34fT5THJXiwWC"); - a("NYjjxTScM9c5Sa4cx01faJY7uEX7C7sLhUvaLi8z2+DzqRhHS3fd1uot5WGrJydF/8zPZC1krL2VcGlErKhBO+GnWdRAnfcO5f"); - a("Me819ZZBQG0ukDV2TeZPnM96kiXnb6K5pH69ouloaXX2t7CLWjFRnoi0FrDGAUJP/dfvfW25jS6CmJ97vqjQn2Oz9zvdJJW/Ux"); - a("iBTS4B1iGzxF7/5z+nZXPPp210Xi2iXZ1ly+wZep7b9P0b15HejjE3v/t3RvMvkaSrtCp3uJ3q+7tVfNoC27T7EG/sP7KKqcad"); - a("xG4UFdu+oiY0SORJCvKjdilEQPR4l+uGJvnmEz0LMlsBdCP6IpUzsAX3imPVed77kH4+6zbKEqvWbJFJiVafFMPbLFc/yUFk/O"); - a("6aGMBb9xOqD02+KZ4kRx0vj96x7MyH0TUIusRre37SRfqtAVl9F9789ZuE/THQvyl/yyPZg/yuEShX27ay9zNFmaW5wVGcdIKe"); - a("+aLMNAHPiIsOhmQc4E7xuZjHYzqQNf96ADa3IEf2oYTj8+arT1KNxbS0KFHoqk08Lh9GdK5DSGifSfqdiDyMX2FkTcQxTXQHEj"); - a("jLgNFHcj4sJ9ne93FxQRkYbp43X6d7rlO0l9W/HxYyyWvvmd4Ice2b+8BT9t6Pfj47BeuOY5VHPsSsJwR46kXMTX1Mqg3G9dT2"); - a("GS3uZ6vBXsTHcjI7AP482x394qb9/n22/f6v0Uqk2ptb6ipHW1C4oOqPT4+JMp8CdTu3OkwB/+OPoCHX8qRxr4kxnJioc/mZGB"); - a("2tFuJwfVLMW33zV1/EHb7xIQmvl+Whh6ZmYBnGBr7bdOWDg5UbdwUiTsm2DfE/y/Hs5KFdBeTFUcB2YzmTLpYPtlL8vhRG/7sm"); - a("Gl5Pd8zgTye6sl27K2GgM6FT7bM1ngKuPtD2h9XEiHDiKfF2RSu5kusbrXRTL+5owMN48nWN8PrKufPyGL7NvzQYQV7iom5LBp"); - a("Y6k/yaLsFOuRKgh7SE/+R5IbGGDaZkotlwsL/qr9sUjuiw77vviHVnTgq+MT74uXv2mgoxqvdMt42fnRdvwYNg6dAwBaKgLife"); - a("uIWIwx+8NZA3xBPwJtwJd2yG91+MG/i8UbvVfGKgVWsNXqCbj9sI/mpd04XFA/qnvMuAXd9eLar53QWK+cXtzaQvhl2JXxsuFr"); - a("WsUm/PJqhga139npb5iQW5L3Y3U7vwcL5Z+U4kn7CY/xbkt8kZunENKdEr9R120PoFajYY/eLhoVYKp2e4x2xZN7hRunDiIXeG"); - a("vV7v+mNxr2O79UrQhROdBjf1539RACL7iHz8QT2T1qj7NyLMYlXIx1RDvujBVzjozWY+NsQYHOag2dct1+jemdI188b0CnDXMR"); - a("wlyEMBchzAWYlAn9y+g37lg5PvRBRYQRAU8gUIPiOM0Fi/IWP712e0nQzmwpIS2VDlyIpEo7YkLHwCheVao/78ulI/zsRHs8lA"); - a("Rgo6crJB6mv2D5DBjUQUe/qTxkBpRIJ0drewaREulQKJF+UZx/RGC0nw0aFK+Jin/V2q/ApI14Ea2di2dp/MLuZsmkznMa5hwV"); - a("xTuCNhPKTVThsBk1lZOjQwNp1EJ5mKJcHDUoMICi0HZJ8HjPi3D5m8DCkk1/j/Vx3sXZ00/6h35ilOcCoauGx/Q/r2cpyDZ1eg"); - a("q9nefs6nqK0Cv0Ex+cMfOb/Bbgo+FuKz+mMFgpFJ9/RMVVxcEf/Zjzy/EqjV/Mi7mnP5tG5iB9NEpoC6d10yh5pyJtKhG/ySiL"); - a("X0vZiShbHDrbp6wQOFsNR/nBpIIX4IW2266WZ32/HDYw0X7eqf310AT7T4lG+3lRPV/9OplahLnW+nSwquj8eAh90lI3NvSw8S"); - a("rMsXyo+/BbkMxHYJyAhnIO34ukCJosrbZ6/kgnN024p3byhXHyAV6N70RO7LucuQBD+KUotIlXZJf+8uhQp4SE5zkfudngFVaw"); - a("2qn90yy1Gf/8Z+SHHIK2Nia/zP2mcEmj3T9FbQIHx+/lI+0YPsU6hvCRZIivAR8nZrONeT6ycHqm1jlYT8fHCE6X7JBR8CSQgE"); - a("/8392/wvHuXyOhKa2Ng9doebfK5BqkWq64mBWNlcEWz3GO2KuXR1xM8mxXr3DCu9fT69Doip/a7159+WeOPT3FfJGZJT2iDRFW"); - a("fQJ7fSA6eoFSrg81BPcq0bU4dVjX6yV4GEokb9A7qq/1ukr4wwu0W9atkD3gyjemINTnulUx+q7YYXrzUjulc11MVoeMzltXNd"); - a("1WR3CdrYrLG0Ymx+TLEe8Otoz6i2E5STUoPSHIM4D+Br3bg80xRdxCP6QI6fJK0SHTjANvh6ldTE00PA9lIKdQ/YS+d1+jU4pb"); - a("EBCe/DCgdn8qtMxrLaJvlvXTSWb0j0eExML48utkfiyx/EgnzSXxa4rqgetUZlCyPo0jYoVt+E1KRak546VS24xL9li3nm6dvB"); - a("MTFnQ2q2Q1Z/DKhgk6udW7jSaoXMqdbHMyGS7zboNISWy5Uh7wbcR342H+NkYURI0vkd2jrL5q4r/ndvsbZqBjGVc+43Sw/YSf"); - a("ybth4SLLUok7vkv5jRvnZQ0LWA41C7MLrswSWAj8KpnUvjdfwyKc2Kaljv/s7b1RlMPnp8gLMDwExhersdfVCyfrqAwJWP+k0D"); - a("5BR638qOxzaCk/XON8qMn+2+/jszBgCe7b6l0+8KZ4l284S7zLb1BC1RrXtNkR7/4NIClCW+GZUj9jivqaWj9jqvo6vn7G8eor"); - a("p35Gjv4V8niCMzxiTZX6JCfLp31wSDSqshQFZxTJLJkMSz2EZWVEFkecCuMWtrs/6WHL/Tvm1f/NiWpRmd4ja286CfbdMNrPOp"); - a("neegSO1hae5FTcKvN7+kn8nn4Szp4IC9mTHCF74lE3NUXf+T6LkR78Bmb4aC/fYFxSdpNss9SvA4zi83GIW9avq+/ox343+jJ1"); - a("uBQLmjjchq12+t4IfGUaD7zrwP0OeBvQjPtdd4xcEBxTWjc3davO6wn8HGMjuAVzC16JsYf6Ou5VmhQh4hJUoR9LAtHimtdtum"); - a("5BKJL444eL090Q2EX9tvol1A0PmDx5Q8j0ST3JLzcC45mgAuNxGwL0oYDC/Pjyd7N6E8vffePi8WvXvnDZx89+nqVtMai2Rfy2"); - a("q+3xWSI4QDJjl1DbircT+4rcU1QijwCw3FYAcjmWenj3Rx2cl6SsYuoAmWi3Fshycnyntf5sEd9hjc/SV8tLOqHZRIEE48v+xo"); - a("b140+kzcRwaiKMMISzzG7dbh2cDH/IexEp3brdY3XrZj8v8V1XuzgiWEFy5Wxo430H1USGy6h/tOpRqFCtqPj9+XiovT92+X8r"); - a("L21aNJIM/WO1XmiFVE2Ghls8tpk6FzILjNC+ObZoII01m6U9eIRQkZLfN42I3b/eQcLPxKgIQ6J3AUZisswr3LkOMcOmbQ1HBs"); - a("p9eZ0zhgJ0UP861DI3969H5lT9iy0aSHtJ9S+f+tdxkP07Y4jkZ52MgOrowe7Pdj4Wy8Pc+xW0laFORHwhTJqVJ+R6YSZLLstn"); - a("41+CVhG/pyC4Hj7tKqeWlL2lUhm4DlzJxda90zLTFZk2PKlu4MnmsXDxXCfY3a33D0At58eOfyPU3YGpUF53YEt8PDNfK1T9bb"); - a("TC3qEurDPfYyTzSF1KVFn7fK0cdLD86fg4mWHDyWTgpL/scyNe8d+K89ZXjjXHIw50QI6PuAz8Gzi7gWfkOMbO+Lzs2PP8iXZ1"); - a("dPt5/YgzE6xPde+ik1fB37McSuf0QIvQOR0KP9Os21e0gi/UYpsboBPvlYpDEbf9P57Rb/v+YLz2l8r2G1pk+4TfNl5Ktw7HLT"); - a("Y4bPef2f2PF/Rn8HKdiP80NT3BfdbOf+JrT2ACdY+qh10xdAEzOghH34Lobwj8rt1C54Cb/+RHrp4VGwrRlL7xY993Svtz2Hqb"); - a("OgcFvW/5yua+5UvGDo/sxKn5HvZEGMbfjZbi7nyDmuOOYh9/S9095TUq6N3sK0O809uxbGk7hu/MpSkbL2uHiP7mfO9bFfdSIt"); - a("cyqRlBUqDWG1qBhmwzQTaPZAbAfnmGJDB/FLLZ2m5PkdtBPuCoUA74O2zLkLP8Xm379vno/SHBfGRkTU7iRrXLz5Vi6yvTEumz"); - a("SnxT8xPLb/gZNwaNTopC9U3HJrHiJjUhafElkIbXT2FQ7aQ4457fxvOy3leG/8ksjo6SGZX2SsagEqnm0o5xxfSsjzM9b3FFTm"); - a("/7sqVtPD2pGy9rKw9jLvO96yvCnIoKMD9iHvUGB9sbfPwkMQt+yF2L4zDG7PseaqWRAcFGka6zioFXjTDpTZZhikIljX6ky4Nk"); - a("t+b63uEwT+chtUsbHa4Hmnn4ZnwudOJRP32OgFaFaTArJtnAGn6SQFQbIjFefH9A4tAghSA2/Ph4Z+LzdlWKSk98vlZocNHO/+"); - a("xcrZa46ehrrSeMOD+G33Qk1vb0yJ5mRWXgVEXOLPeLPCT0e7+G+YCoIqUnNAlSOqOJSakWtt1c3brs/+1oNyH/Z0PuQdPzWCCe"); - a("ahRAvNKYiJ5nJh08PS9U9DyB//8keX4LJP1X91X7Oc4LxvVhfsjCq0MXg9/1kqTn8p2yErqxCR4pO4trdzhLyFVx7X/yXvg6hd"); - a("246Orv4x+9jH4meiyc/xG/NLgLgsyNojJ/pjIleT9Uh3S+4otYcv3egO30ODwxycHD/gGcI+O7Bt88+q38Dfz9xiE3qS8cieeD"); - a("34dXYz7WYD4aMR9tmA/MS6DDUE3t64nY2Hwx5AGM002Z1O/nuN8VRTyg0i5MllMNqKJ/UEA/QnfOlV5Cw4xYfXyXvsRwz9Wozl"); - a("Xb+Nytibneo+V87XDQcY0ciw0sgUPfHnqF7euB+B7zhJvmu1PNt66sOJWosIRce3MH6ukLvo/W9jf/W8X8Q8bCmH8qg3fhWP23"); - a("owQOrAYOrAEONKJjbcAB4ALmQOKA/f0/2nuw/j7JFslgLjQwAsEaDuLo4EcNAExHerUf3BnfBehsf6i4NNhORrZKQmOd6qs4NN"); - a("+JSS0oLQhuLG76NMWLF5Kmz1JmhUa6ZwVHcsr4TRDAR0IT0pHgT0/HI6wbSeeWwmoxVeIPjk2inN7xjcX4PCc435EeK5IRWkbP"); - a("POylJsl1RyPkKYMYJl8p1LlQKUAaqL4A0kDU7rODNBwgDUSKDaSBBNJwKgSQmpFGIA0HrsYHSfELQ6Xzl+2lk0TlOF/Zm8XBth"); - a("LUCRsBxbARUOJsK4aNAL+zKfhmZBj5pGPR/EgylD90JcEcq/RHXH33DRBurV+fXzXP1UC+FmtevYXyVJSGzpp3eVHDwmhB3gHX"); - a("bdc66Bnl0qhxrw+dXxrsoOElj5CY83mQrjdH+pPStRS8HRbkfVT9DunjnmCqr3Ii1RWOV48b9VCZz1EmWDUPNHp7wMXP5rhpyS"); - a("5Zdejt9nTxDA/VSfEgny0esENAgho2kQyVUVoXec2BYf6G06sPEAGAh9zISGHWIeT2h9ZSRo4lRYKyd3GYIrGM6ry8j10rh7Ld"); - a("oW5Ihof8lJ8c77dDaGgluZuB8AGnwUdTtJ18WH/CewkKbCsKflUQ/LEoGCku+6G47G14f/JNatKq/YDF2Q3vSWW6XUnT/Tyvt2"); - a("os1bc3tq3qAZHPwEOOOPM+XpoRB5bq7QxHR3Avw5G3O5ACDZDUvO9dRbvz9lX/mXoFfCerSnntlaMxL2dhEDBWRcHPuCaNzF9J"); - a("h0UwL43Bqh4Dl0JOzoS9SmSq7WVa04epXhs+4z2a8dKndK9s8ihtuskCEwshF/lDhfPyC+cLvY9t+0nvY97SE6H3Mc/Q+8A2Mb"); - a("sUXwKZ5iSR6HppsJs/nU3a6H/0EqzIpEe2kr6kQ8UwCoIDqN22l3C5sBR6Ik1fYrH+Iie9tnCesQnkJMVKwKj3AEj9uZBrLWti"); - a("pKVhJgeJt/C9qUozyfp+MBHP6QtgrwTgLoQMSHT2AkPpgK5qnwxh/OnrPSFwCDRAFzlAhkO+JbiSKn3zePzPNmHbAugkpAgeAl"); - a("zc0yjenDCAI3NpM7ltT2/UzKEJFcyPpZcF88zfNv05P2pV4wekzElXT/7x/RlqS4R8Fnkl8laxRgV1flMH3UeE4NEu0DeFEeYW"); - a("MG85NG+be3qjtklSnNt44yGln+Rw3Nl3E8HKnPT4dSt/XExL66JLR/DBLOP+avQDwzm0g3TTq+a7VpL1A3jfpS1A2kufTXzByg"); - a("lZmEdRaKEs1PEBpVSVOipgAXY+kJPetWeVwpEokzPN14a+lp01H9VJt12CAiDdyT67RoMXTyVAvbTIebxOpdmas0qDVfO7qgEL"); - a("AdVwPQI4ZU2qrZrnqHKjbbyEAmU/2MNlqAou72s9q5QN1niBPZxJew5ZYrpThnwCylZekAzpH1sFINqjnKpACAu6YZ8f83oaZp"); - a("6PyBD7FKDwQegvsrEOLXmPrjK4Z1v/ujrx5XVrX6LDQlLFQFAkumBHCkj+03yFKE1iueFJoVriKuCEdzI5zE+LZEam0N06I/VG"); - a("A793vkf4De6+kLHq0HduD6qgkVLQ2MeHCcA8R8WksIVUGt0diUtpvAGLow95n9OM+VaiiLqW/NgbrXlJHA1Gi1S10R+W4uR3z1"); - a("/Ncyaky5zdbV64I3O0qtdZL88Mp+q1fb0Wmdbr50gENpI+p6NP+ENDktSXPwR4CQDUAbTFmiMIZ4VSsHGnmCBDrUgGArvJCQCW"); - a("PmqQZmCDqM8gmThg5PZFF+LrC/+tnobw0NrepIBLLzgPBem8Q2mq94n0meeRPnPGYTcJAYQnoPSk7POZ91PdA3PNq8t56k4g2j"); - a("K/XTyAsVTBHu3+p4wHsEIZdc6TRhRbtzg2tsTvVYnhMupeowTQ2Lw7Hsz93B9c2s0W/N8nSzLenCjd6FrZqx3VPf8Hvu+QXcfi"); - a("G5UG2P1AWq3baTVgdcn9tKZgPVJcEQ2+PkxFRi7jcxXMivLhq9lHZ/quM33ON30b94L9RjT2Anke9YdSkvDMrFfiE7I+RF0G4L"); - a("hU5oyMwc+voogIuApedNa+RovdWeTyfh725n2x9PfUhaJgVlF9T1+3cH9oqfUmZKc3vKH+9HsegOGCyGh/AJeOSc+R8UlPYFAr"); - a("olk+JmynIvb9V5K0AG2+bdcbxGkutIoiU4Qy7rwq7E/dSH98CadruUiMedbx2JE/Pv28aZ6zqqDmpTpKCQzUyenxlsMeBteDBr"); - a("4T5PrQH2IpmYlOx9qnoCuVXNFOdRfz4XYmSatdhUCVBxI9g0HTcy5IsuaM//77bfz7MvyWHGB9SI1/nu/Gj1WhApvPBKH92EPa"); - a("j+/CU5UMU9U0CTU4i0Xc9AXoICfh0L5Be1Yjhp3E/hzM34OpAjSl3cKV1SFsVaUEBqY6rlMLyU8mpW+NOuRCekAupIzfSVbmEL"); - a("62i36EuB8Sbe32bEge6ICSUounb3CQ+rh23dv38JdVbp88oNsiaD6qP1sE/55+6s/XkT/CKX3rp047JpF+6hPXqkH99reo6oRe"); - a("h0U/tRHKbNw/pW972QPIOY+9DxWywjrLILe++j/Qt72jGVV/NLnv/vzs6ET92bpI9Wcc9efnB6z96f6t7E/FeAP0HY3Cfoahb5"); - a("uu7dnn6EffVvEjpK/D2ipUOh2qtumGqu1UVrUNCz3bdMjLz3iZoHgd+gksOLGTBOKhGMOKth9a+QT28yX47MTCGm4yrNTmULe2"); - a("k/Yrn54J1n+kr/XfKOZHE/PT3Wtf/1itcul3TDCWPqaOVv4tOHEplXQhClDMDEQJqoZIIZh8gkEGGlJ/Cy69kMBLU9aUvlPWlB"); - a("4A+dD5gyfKhS0mpdtu6S3++0C3X5j87ha23ohxrRlC2hrbetPYBIyU0e6krUhm7CHLohQnBa81ofPaTTqv6hlB6byyzKnlkYHl"); - a("rk+9B6N2yFTMkMVg8r9rn7Jq3H9hzyS02B05XNiZvD6dLUy2eqCpII0EJO9BAAeEj/uyZ4IVI5zdXXgEmyp08+hA7V6hnWqPbb"); - a("Ff646kUFtKL1yKWTh4599ugdlGn4Hufh/bF/L68n1uLE8Y50Cr7sgkXwh/B/Cd7zz0BarJ5L/El9cU+MaXf056gPit6aSy7MVR"); - a("cIB2yxEWO0Dx1sfQzv2w6vzSc2qJ2OwdSdY/8j5Heas5b+3p9+CDkSK1ASEfaAChc8TF8Hm7EZFOEQJDhskoNxuR+0TH78UC75"); - a("RUvh0+D7V5WAL4tFmoRNrJC1yLEsOoxId/E1B27wOUgWNhr/D2F0z2KP/mxE/qI/jhmSGfJK3IybAPfQUhTWzLzch8PgpqNx4m"); - a("GpErxM3gz7GAH5/+/HFXAvn9oQuosfy/9d0/5JlOeQZQHmmWfOihFFOnv97eFpWBhy1Pevb3xVT3XpqsjIH8cwhThRzVtEVeHQ"); - a("P4NDLChGMYRd/bw0U37FFFs8P6kGaSRaUTeZSatHwdoJsVQPHtsaGFEm5hHNubatSre4OqewQJVN0OED47P1KREFaEeWwUMrNq"); - a("VoHr7vUVk7Fas3E5ID7IbYfGJLmRlCmkg7QmeLANQxY15kbEvkp9+ee6A8mrnety1OnIZH+F4w7eHmWmtvtQnbfx1KH98zYS6X"); - a("9+0RtFIEdLRcA6dYnlG/k24QdS+YNvaKOonhDqGUr1sM5QYCIWStUzaqHcvJoXyk2r1UIpzBT9+WCvvkBKUECbl8m2d0gNic8Y"); - a("GkTh8ZGNjxxtK30E6ZFwsVg5x9LK6VNCEO/7tTdmMs+UDEHPcAM3+tCv0dqFqbjICcjD+sq8QbcyrcbnRlb6wt4BkEGNCRtW7h"); - a("V6271E+d/C8PP6AXLAlEDcC5LFfuPKz3v7knew2VuVYiz/rt3VMOWUpCYTv93c8Ml/YMG2dt3Yu7YckEh50v+NHfNayJpplxzd"); - a("tz37EMCYmplIHqRNu/qz3gT6SGabAG2GTQAaOC1VHHI7DBHsLuKJyP1EKgp0aJfu5xm9lCN5ozwGwQ6kZ3HzLmEzoE0UwiidgQ"); - a("MV7Q3HoePtjsAoHbdX3gm0XTaK22wP03Bw9759lnk13NaI/QIilOyApbwKDDNXgnMeiWd73MLSauVpOJbH6CNprI+kBZu5yunP"); - a("8FIRI+3LJCQcCNZf/sVa9WYR6cnkrgTyZK/S4Ztfh/PLO8hfe4aySGJY8kAE/FMIeA179i0wosgf5fhY4d3B3A21tuLbAwxk6q"); - a("0todZ+lSEuO6hXt3bT8Uzf9lMVPVYk0GUmgahH3EFOp2sHj9uSKNQMpgqjBGSPgNrB45bmXi3HaugpPyQ5aKg+hrwgzBHgvsA3"); - a("lZ98qx8ML8tIREclMbf3F1ThpX2MQ4PF+Yz3l9XKpp08/4EG5QgDY0NgCyxHu/5pm3Ux+U/kTMY1GgQrB/RqXWJ7Ejmm8U7/Dc"); - a("Z73wge7xwx3jk03gt5HC6xWIuw3Y82ag8Ukl/EQo8OlDW9WqTPiJveOoMNtzNMFROobe2dZ/lymMP4OJyjpo9k+305cez32ez/"); - a("5ToqpqBQrnarqCeX6xnDUT+M4HrYce+ystIobetx62P3tR3iPuaplyY48kgSaG0U6eIx44WveqPsC4C3I98oYV9lhGf5LhyKg/"); - a("AkIP2+Mj48wj5/MYyW87brxVKPtmOJYiTZ02dob/WV3gDzrdGPeqMy0WbvQspz446cSbAlh5Z4ykOzPcGe8rxmWFupL2IbFldF"); - a("DRsW85UNi9G9IjYXsdKGheAZnI9TK7+1t1PnQoUzmr51L4O0Oz7yelStp8at9dMDfdSaJWu1W8aw84fQdT3COl5EhrUd29SQ2P"); - a("1RcPnaBaW968zfvlJnHP9whrV/eGwPDJHL9f40QChQ9vwwoSoRlKKGBVH4vdbtqeYQLVn/BNlZ7+FiTYaSSgGkwahUUf4Cd6Vb"); - a("lhey/1h/EP9f+pqZgNj5Z29PV+hghxf4uhzHx9qZpbgJ1paVfisgPZMuZadRa4r8TRbkj/1I6jC7ATOg9dTzWeWhqKB9H8XQNL"); - a("O8Pcvaq2MwkY4SrVfYB38OsBFtvABTjBcnyAQ/ezffQs8yWbMPWE3iH32pOv89WwvqNDTisFiz/z1c3hh65odjXfIalKYL4VzB"); - a("0NWLZFCiziYGfRbR+AIwGdhd5ZT+BUFW09McCPGxUInBSfzwrIvFn9ds95VVdv0Q5WKBBuKX8jEkdCe/+/3Ul39JZmCu9BHxQr"); - a("Lg4XiNwUEV1sF5Y74anLtvpveNLuvgVC2n8+XuwlIW3z1KDNJYGiA208HoqMaI6FMC5RDLfamdHJ1AyIjKLrIxyvvi916nMv43"); - a("/KIlNn5Rq2eO02ByDaVirGbrx0jGspA8gg2QZ2MhhRPykL6vxXl0w2EWHpLt/YxsebiEroc6b2CbL2KfxVW5gP0qxJKrbiw+oU"); - a("Jynng7zwWT8v7HWI1Xfl3zZ8ZKqPAKtnZxKGUCCIesShwIDqGq8ue5qwZynfPcLOsDTZanfA2zcrUnv3Rw+xUOLpTJYzMrk9bm"); - a("M/xmwVZG7tGEAbzhJLY6RICv+FqK/Kj53O0pJd5VYDBdii9HyMjbF/8+MonkXHkTb/0LX5Tkgtuzm/mYjMrc7gJxLtmszhtx71"); - a("tAawbBA/qWLijbyQZRYw+eR7P+kaG/hKYh+XHanwRj4FkkwTvnl+VhddOync+26FPZCOhYEVBFtSNqtTOSlNOoAFXyZaZqilvX"); - a("OyT5KxVwFodjqW9eATj40q9wi6C/mKDwo8yxLg6VMC392e1EKQKpJcEdkfSivN3V7wrfO1YTkWgqsT24DpxipTfjtxFU0MfZX3"); - a("Ma+6lPjcdClnWfJd8YIRmvaKy0b/sjTzQo65/QrE6VhgoJEcR6IHJh95SpwOujP2JtGPlRHQh60S6DoN+HZkUbiN/WQyJ8ZxlA"); - a("vqEDGZ+DG+99HMvIx1bYZvmEexwsPB+TiVwsZrdymeMeSoblY5+4/w38arPjVwJ4RtvhcQOcwxQ4TW6+aRDRSH0pyeOoiYXMQq"); - a("9rl6BSN5vICXlE99IjqWuiynNtv/ndtvz281q884N2K2dsoZuycnaDDNYd8Na5ageM3EDvnZ9Zd8DKpTT53byN96PPPXTVF+Bk"); - a("/uMpxVIwv8/GeT8rIfbnr6jQ9SgEZOTXgn/+ic06f+MEAfqZdCdAejw7+B6+g/3raBOZCHnZEaC8RzTQ1U+7cmsvve1QmFVwhg"); - a("zmSXML/yXkLFCbtJRkxAI72C4ImJY924lpeZ5kx0bwBQbpdvzwzvY4xgfN4kUsh30YDH1TZFjHP0rVpVu0MIZaaK0kWmRWYu3S"); - a("3mWIkM3yMJdgPEtpaG560jKedv8NBPYEynv8k2oYH35UDeN5PIwMk2UcP3qEQPGkMy//KHSQIttEZKbq1Tjq1Xc3yXF7ydq3sy"); - a("Xz3OKswdqfGgyZ9sQTqj92+zZL29GnDhzWuF90nkE5H5Wb/YTqW+sjqm+zYvk1tTAzhPMXO1HDGYb3R7DScQTAKsaSIrlHYquY"); - a("/NmMEf3SqtehX0gTfSqM6iwXsJ8AFsT4UafqWrz7zbQo0OnvnxM6zQTcqxHSDqPBLOv2AVofwD2RLMuhHfouDm4L7kS+eso3W0"); - a("AZbZc2yQaUh5G/+gM+//TYCI2dPyzHCxAcQxAEDl8jV/a5y4TtkAcfZo/pg5BabvD6JzyIZX92stAyQi7xujnDLbmW3fRIFgb6"); - a("sDhiWrn06zH09c8AsgcV5nt3VE0QC+MZirvtIUKFUi7PLLsnBvACbEWGMGUYLAudKQpVUtwFXGhup3hVmuEOHCkSL6XE05CoQ8"); - a("JKVTcC2sgkUvEQufIo1y8eQ+RITr8Q6dpy8jR/KVnd6FvftkObmpxIP7VHnqe1Fjhb4qMtfNqHLhOUh85rTFsHOVhFjY3B6KP6"); - a("/kqMasFdguMYFsdgN7c4PYhIRswkRrMro4DbTWxLNAJ5CDc+neEV3u12fbbUrE5+tBnT2f97j8IHlNM+4XKf4kc99gj1STdg4P"); - a("fZeu8O+f7EaC9bt9ozueStft7fOwV91/AjAHjXIBSenF3gt2HR3UeSdHntFeX4JKKLGe+uuFDcQdnfNXuqdEcgCin8ywAkTz3b"); - a("3pIenUenonoRxkmHIVv/Hr+AsCodbPWQasw0JHvSW7hbJ3MdSBUQhgChnfja7eFeDUF21r+6TARg3xwBNQI2ewasb6XUxFHgJh"); - a("Swq1rhlkXXj12Rn5K7iHPoDeN7Fh8ArFcIpXcBwZDl+JCErBOSWXJbzxSGRjLm0vLN7mAmgc9V9L2ouSKV3kOe5J5PjuobONOw"); - a("OPRL6XFguqReRqm0l/D3qUQhR2/rpYY9LzpQbQlnqVmCi97RltzA/O2rANAx2ISDLXWNHtfdrZhXFMqUOT1KG4+Ux6A1UrahuL"); - a("bLaVRknEe1E7aQ1PUusMP4wJJyhsjT4OsRz/ifASizVLN9fbdpsyz6Vbb3j2g/7xuKBvjxrNHi3eaQasfSOjfw2FW3X/eEdPtv"); - a("6MDK547lCOatc9V16mmLEYGJG4w6nF1vIlbR4HlBjNk6iHIRGTBiZ1DsUyK2LezHfPuFSax2mtb1gup0Sr3QNopbLdpqpwcNPp"); - a("pw4wxQG+LaVFzeusBJtpx4shW5QGcRz/bFD39YPLikEdiRFPwVu+PduhWaJ/llYpv9ZSIuvX31QOL3NqkPi7HWaJxj/Xqfe73Q"); - a("iX3jfHwSXZVMig56MzIEiqTnOo03MUwSt3v0xfKkcpXlEVvaHy8/nbfG6JYkno+t2FBqoYuP8FgKP5YPovNQGEid+iSy6AB5QM"); - a("i0yQ9y0ZO2ctGLKfsSyp78IGW/mGpsTb0D0fhHwd9yUPVq369RyZeruJJLt6rKP6f4DSL+bFGLf0ts0UWb+UX3CvzIvmP/Zleq"); - a("y5o7RZavPwQ82fuoKxmf4nqIqEMxjNrru23W1+znz3a0p+17UG2RlnQPpW+1pSt5FGo8cppKt79nBzTsT74PeX8q+NC0P6H6c6"); - a("n6+Q+qY1/779Sx75hW73469oW8+/k8u1+cZ4f+TjAn5qLL+YH91Z0868cgIyp0UIX5SEH4hw46L4twD4WPQnjaJphmPfYTHqY7"); - a("CfgNeVQw9cWNScxOHBQauh/R0fbIAIz7HoY3Xevay7XcQQU+QhiFz6LwtZt5Cn6J2rEbPbynl06HIaRAHgj5b6Y8B+5TvtNy0C"); - a("WD32LqF/KeT3mn3Sf6diPayL94f/U2JJxOCQsRAfQ4DmH6R+9tFH2uiD5aRrekXgp3D046b1J/k1epgb3hPjWwUwkKdZ62jO9T"); - a("9woYftxjHt+vDvCQ5VC9N73LEDz3AY2vmPuhH9DHQ7kk4ozR/DO+hPyNJwfI/Tt8yqfSbPDDmHqWZ9GdD8NViURH4E10oxoh48"); - a("Jxj2jwaap37e96ibAOw/c19H1oLpW1XFit/rbV+4RExn/w8xPvPsQU0+bcJV6ksumhUvf3gzjehMpJ98/1Gv5MdNSQsf3migHl"); - a("y7CYotWcVI7b4tH4UzGw/LhodYUrMiZsXMMjF4fLEc6ODojMxt5YvuzKCdmO6aLY6W9HK8eiXPVon+s1euTZ/aHv3SvRHhVA0S"); - a("yVLa389N4BVYN2utypH0I2PzLPt/EXyBh2vYgc9CqUA8H6k2QAVeDd048gb6ED2zgeTxtjEIHYtXIwanwD2zmpHLOGH9Qu2Doe"); - a("ucEqfoUcriYxNIZZh3JqgGDIktTFnj/FnD+kcvZVf7o5v89agIJtMfkHqfz68+JoXegod11c+Y6ig/Kn2xjPn+6QXcAJPs2Rz+"); - a("8XihRD5c1fgM6+0u6wqExMvpLv4dSGvGul+4QdOMiHGL7/y+Z2a8vGWiVBCgQH/jSbJEh5OKEsyA1oUzsvRcmCHLz8Zmj2WLz6"); - a("TAIRomXglM5tFOODj+zD4JwNsEMK82tm8POT/h2Qqe1f1tM+307z/LleUPNteZ+WsrrQhBqrLECa/BfMs7+p2O1fvZbg/JdIf0"); - a("a9RUHDJMcQMhZ+5mVf+fl1Qvf0blfdsyqWYS6obykvCnaXT3Q5XK81BtP+zD47loes2YKtUJO/biZ02mx+RTibNNX6amNwQOTc"); - a("sNkGAKpF3OlGnAdxiCC9nnMLFZJO/DmQNHODFUlvuYJoqNk63gJhTZTMoWodr/ZG46d1aS8jTdgfwJrrXxvHNF8L1Hwlsues/W"); - a("Uf+2oqa5d8Xunv9ny4vYsx/WGX/1LnvRaLLzhr+lnUBjDve5fbTm+Qfj7SfVc0uo+hgVM5jPRTkM4JO80V2Nabl152/8hWObUB"); - a("FWPZ0dwv6a9reYWITak4q6uBOqO2J545ZfsO0VKIfTzdNEOjinjNmEciMkv3Q/MnkpMa8wrUXPINnzPnUVwqxSnfNJdQ3Hcv95"); - a("p909xBcR8hLvzvrN9X447fCziKAkNVgnV+9iSen/fjp9vt37+U6L7BsmvGnVznckm5AzY3jyxkgjiUxAbIJKIjwbjDInBpWNBy"); - a("kJNrdhGveFttTzQwGQtNO1MttJcvweg9/aZ1oR1ejo64XvBucz3h3RFZwYefKwaQv1UkaA/09korjBP5qLvDTLrj2/PEotyvP+"); - a("ukmDEllDp+itOR791fQTTg6zMUaOMJtJE20G6+jGmAMiFifz+Sk74uMV4G26DOSnrX14+Ki54Kn8z8CH6dKajtGXJdJtbBkIo0"); - a("/E0PDGH7u7vp0BwBL0A0oredZtozgusAe9m70md1GkCo21qFt97RwsKgkdnKQbDTm9OotVbxBPTNe6gnyv0AtSnY2Gnph53i2O"); - a("v75y5V36vbEtXXv33hDWt6haGg1xHo194mAWFzEINT4InCVxxGjd+FoNHEWCRB0cT5Yli54e/OlxK7x+H0rZm3rQje0JWh5hqn"); - a("Lfdn5twGftORPaE9W/iverE3gf1UzazjELY54K/tyXDd6sBOO74RaB7B25evLOVmqKJGccbr+krYk46Mlv00l653WiJkP7bY2u"); - a("gC+0suLPTqaSdiVjqZ15Mk435Pcb8WcSky7laKKxdxg2TcYoo7j+Okwftu2ZKkQzz/L/RGu44zvFXf/gM/mG5hfSMqf4hRXlss"); - a("0zZ+RqkZlPqDzpu6gNKaRco+6sUWh1GO2BWSX9V1vbLfZxsOnFFqe5IXj7AOHMoZ4/EAIccwY3y1aB/j+pllXOPmctUtAdLYck"); - a("bGq3E9nr6Hh9emy+9xUs6C9SsOMMbJC6JVXhH7t7RsE8lneJftc6DWqgGv0k8kKfix5Fj6eqCryxdFxeHUN79J30M1rkVILKaw"); - a("xGIC+6o4X/YYInLFwR+67hLn78Kx+YVZlXNICL6IRY1msrtkZfmwMKtO6GvvyVM0vQSnX82z3krT/3op0fTWwrG8QnCwx/F+Uj"); - a("u0tWHWu8jl/5ZagXPrsWSIoKTsdUhTaTPreqNFzl+NhWWaYuf6oknf1kVdt5fHcSCGw12PZTDt9o+fO1h7V/bDJ+v//U3p6dXr"); - a("lq7ui2vpKr7+zt8Oun2J5zYwzAblEKj+WPBD+4Lhv7hvtsW7b/7hK/N986xT1JRfdD75e222TvlLF/N9sygkFJ7U1VAiqWh8Rr"); - a("a8epZqa4+2XjtniKtlvu3aiXoT3jujaFvb8mOv/d558Po2DTNLtbMBEhA/W6tC76W+KEJ0u3TR7XKQcbtUZwkbvwJdu32pEmaN"); - a("l16dID3kwxB5sg0+s5m/QfbHlAu5DwOYiLu+tZ5Q4+JboEd3BIuaC7MN8pbXzce0P52s5vfXc1DtVY3W+d0KhZHIcKMCRTBRfS"); - a("igVmR8/ZfVvcIQbN3qBOcHm/85MVsrvDnFIebkFQsFwZ7ikJMwuDhUQJ+aVP5QZmOFeKDfF7qT7ERww1OuIFhJzHMnQzSWv0va"); - a("ycZQ6Svi8eEwJvIw10TKMyEqKszm5tBdU/F3lU+2+PIHaO0Mk5qVfTwe16qe5vFYrQUQSDgeNRiPVfY3C9qkk+jBhnU68Zwj33"); - a("6RC9DxKDViOB6Xw7JaH5Y2rPdJ+u0ixGY0GI6hC3kqV9PSZQj3X87j8zh5MMt5WQgH133rkCWBpOLXo1CJXLqVxk2tlw221LgR"); - a("cgLfTjlR4dsgHD60A69Y8e1XFwLfxtjqk3hnlF5+NfnT/6xXvICr7CAS5iKOWBB45pEnOreNJ/YMMBEEYapX0573sn4rOpOTMQ"); - a("9qvu3rVR0YlHvZuPK4Ldi/QfHW0Oom37mh+nZ+eeSH0Wa56leo++zB+RcPWgSU/vGCSUBpmDaW1elAmwk+7w7w05Y4Ko7wNSAY"); - a("5PNEqMaQ1/LyIpi9pGbpDkfFsSS/NU1N109LMeCzXrZO18sXJBA7stt/xXMeACVjGtp1IqwR0OUI25eDuf8eYX9jEf+8skSY4a"); - a("jBjz/4aD3/PBXmn+fv5Z9XVh0gAN9SVknrqFUZpEZ5aRTDYJcHa+MATqElIYSLQze4u7YlGedQP+uCn5/N4J8JMItrX57Ay6si"); - a("szh024TVPHpe8upTEL2LU4CNs9hZOUnlT+/UvQC6lr/PyHgWuzKtewPP85sisPQ1vOa0YYEj0AZJLOZA6JtN08KI6Dyct3E2Pi"); - a("NJL+WGsilKvUGlBtXkjXLVXeOMm6ad/5V4mG0oHON6YfYY3EHoNRyPmxhwkmpgjNHCt/aaxRzkXGx5jk4Ar/AQBX6hxPvsgPvI"); - a("dVKwjiYcY0rTL+xNNFAQ6NM2VaHP2Fm0Xtfq6POoRJ+lc7GNYfy6JRwkcb8HTUOiZ5Q+JPQErW2noaA7h8lciguF1hAqXf45da"); - a("SOwoCnUcCzRsKDBFFzXbtIaFOArhGARqcoQBeXANCzDEAbJKCbocDd9TfKoiZKe/o7APVHEZmtBBpQHnwhnHpp0qvxTfm165oY"); - a("iMfZRuWs7JK6Nypgj7S4hw6+k5rwl11AoSJ9In7zd+K3Ma7yWi0pe5tEGVRb+kpaiIz+EIf9PEvnA/0aqCHt8PUYXxZRZ+3mV1"); - a("+jtbELZxpX3ZG0QEB8PFr2GnnS/QkrVIhFFhKLLCQWWUgsspBYZCGxyEK0yNRaT0wfJVGLm96j0s33F9bJkAcPtaEohKxNF6KR"); - a("VrHTRSa8e2QmpvOGNfp0viqnM3W27XYW976/VD9D2Q5AeM/sHRhIhYPRyEm1vekI5UQjRDTPMyHT0dT6mBetRPPW80haqIcBCC"); - a("01naOs9HLWY/3wIwIxdwppnVq7IMt6kYDB08BAivKsyGEon5ysoKw5B1AufsEK5afnShmMhYjwuF5oAbwW9WubP+rX/iN4jxmv"); - a("4E0Lefb7NmoK4vKQgHjvsQriDcWAuOl5K8TH6xDT/dH1oh1gO7+MOXVsGp4AOaKHzesUI147oYLuspHTFV9qFXCMUtZcxzSdOA"); - a("34Zpt1XpfIcmA/S+F0Ufg3g0XcG7tZQvEVvbEc2di1SE/kz5EZMhi3GbnSeybOx6Uk5Xev9v4W+34Zz97+sEd7hX+r1EdVgbj7"); - a("aylGDFNUo9jWVh9XDd52JkNSozhbOk0ljvB2jpOrmRl6MiKXzqMy7EZ4Daq7l6vTncvx+fIDJ2J2QwiSX6mS8KM0tkfL9mhHbd"); - a("dO3yCM5kfSdQajUDiqu8uhF1qzhnfnUwymIwoKdwml40kIqUlUWN8oPWfJgYY/xzV6dUAARWXYdQRdk+sliakHMl51tELGgrOJ"); - a("v/2cjoxNEhkfmgX8ifWLea90mUdzKnuYC9jfd8honOkpqet1EwPVgP6OLCZ2q2Uve7iXE2RnHE7d0BMyGB3q4Tu07FMJaqHCq6"); - a("OlxAdYhfFOkT5AvKuWQaeSbbFRQT8EJ5B5la+1mTkDSFfkFx8ozX0iRczIWGF9vUs7JJn1BdO0K9DxsFb4JTDO0Ad7j3WZZBnD"); - a("Dshc0h+/gWf0XuE/olmJq5S0et9SfiHhZ4PlRN4KNnPO5c1c7PHdnjnci9Ho9eO8Nn79awb5cWqpPJx/8Vssd61jV93vCfuklY"); - a("BYM0Uep4FCjKMVR8nBXSXmvd2PnGpwKQ/6B6y0+SNl2b8ZmwBHvlcLHEtpGGAHjYEar8+ccrzySmi8RnyhxiswXIiPk26AtsXP"); - a("eMRuPriOCpekBxrRA/RNjmsSd3/w9WoIj5VDiDym8eNsRYFolMrQ+HzOddgdxYmKF5Qe4BLPBlTFk/S5CVvr3QGqSUW4XjHuSa"); - a("ax9OWCUdTGsEsKYXgZKdcpQGCoubNjZEEfFdKuWkz01dVA1h64vbEmqE41uuux9XdOBdsK0CvTTro2GgWMLP8e08JhSGC+kw7N"); - a("ACHyOojR7uL3MEvarfCfoP38cwTDQj9hr9x3qhAQIwhKypuO5D/p4q8QUtbue4kNlz+73MniXf/s6GWXm9fp4ie7PaJhN8hDj4"); - a("M2wcHaF5uJfrcmE17qjGCmwjmb9E9FgGsIbU5EKyxqKfnI3SqfTqQh9ByG0LJiacn9g3BBijjmSFTrBKrlYuuw+zeJZPD6FDxy"); - a("imrWcsEPZ5L1TjfvfJ/zx80pxraQwxREbRGdsY8pPZIe6u1jHHIEVnRTjwBKTmwBh4muRtwMj3QjffgeqadTJEDR+GN3sjzwDp"); - a("OKJYaKyhBOv/U73Qar3d8+M9fKXdWwJ6+OhWZuSGpgHO3u62BIKCY1nXDcNaklMpySaVXs9LmObaQo/O8Ol7uuQZ38XIipOPj2"); - a("XIFjbIdTFSHlaFzZMLfF9kbx8T2aRYQru8XeqIGvG3BpQfmzzE250ZSMVU2pCOnBA0+nGXRMmibcXUg5BmUOg3Ht4Ps3PJCduH"); - a("+Z+sC6qYPk72Vnn+Pa9/k++L79iN9a17inwgXZCbw8XYc/aXsqnD2Lx3DG4E68qFJ2g1ryKXVOljoYZON9XjvsCespNQgfu/aj"); - a("fwL+rQ0w8m1x80XiUaxiKEl1ZNGfEyPFYVNeJbzTEplvjpcCPBRfpOLlDojI44H76EpwnOrKxWegK6V/sXblVS/bdO+Ozw3uF5"); - a("9G9IdPPolPwwifPmU3Bo02RLLLbzDU2neajUUu00EYNlsS4/Ovr14j+dev3ycVNfzPyhfxhz9SJ+o45+kF4jx9L1BsFabxcYFi"); - a("sRxrpbDBNU77SNihW5MK8AOETAMOVzOwdTrJaz9unYHpRbqRybWZ1On9V/ILhlbRTVIA/BL991NNL9Hc0tlg2fAxBKOa/5EoMG"); - a("IUeBlH8hmQ8xSa8oyWeb7NQJ5ep253sfQAPety7okfqdxdEDro6pCXnP3EIZCZPKZM6ynT3/hNnPNtNuXr2aby/YHyhaQv5mi6"); - a("626RJcNU1Y3bBHTnEnQLZLsn7TPVZ8rsp/ryVbt/wI7tym7jfGFTvgmUb4TKl4J8ICdNnPFWU8Z9W5Hxn4Ytyin7TPkeMOV7l/"); - a("I16/kQ26nlHGJSxKk1dfoxynuPKW+HttwtrgKc91RT3puQN3KVzIf3jRGcr53zXWPKN5vyeZWcMEQPgX2NDnG2bQS23WjCtqtO"); - a("o/fdx3Rsa5HYtqHA8BP4rjC+gXM7EDwEBOelb9FvWnkPr5Y1Wp0IPK5VisC92mIRWKX9EgFjIan1g8Vu3EWVehPf7UwPHPfK31"); - a("VCxEq/m3KnzXfSbtOds5NSjAcBvoIGSN7eeWcS633o54eOtczL+90yvne1E3PibJoCrDXuwYPgyeP7Xr9QdOkAF6+kTBo45p61"); - a("P8oZVjEk/MKA9Xk3pmGSuZqLZDXmXO8jV9dOcf1k1i0AkA8b6doVG1BAv8aGOf/1GxnGNurKxGedND/rsJTpWPlEkn4HbMNZko"); - a("839+7gU0+bwTVuJHZuUk2uKzBCmEMDoVu8jatsjKTraIIkQDz0DuK9XNZGh9aA1xhw/Ma8+wCfJo1R+HR4Lgq5H7FSr6oz5d2m"); - a("keal61ZMut7L2rdtvQy3G72sGOUX9wjh5/6WZCz9JuRRUytvNOrBGKXN6U5Rcw3VbH5wd628ETE5m2gMq51iDC93qjF01V2IL8"); - a("FPiIAnPFPwIMOE5uL9aA80c8TRNJ38Pxai52lvM0v7EBFdmsVr4rs7xcP1GnPzgaONoneHiQscgkqkDMsmtNz7pdVwug5wBcG6"); - a("eVHmbRMbh22Hgw95qNOBhIUiYYGR4NUQu0TELlKxYfl8WI/prhGcjgaqDRPZOVpN5JxTSP/uYX0iA3Iinz8doJa+D9w+IxzJRz"); - a("W8FGvW8ExUHC7qL02PcXOoCTO3qVruGSg8ggo7BW15UYjPqvvTGro/5da/63mBNflyAStd0zsczDCagkZUNJDF+G7wPa6tuKM3"); - a("yl8tntUOGXjOUT9/QpbIU6v5WSdB/yqlr2xTffWdDlP9flqi8huMkk6ZUNpt5BDnGP6sWbLaUTG/ZslzjsD58SEMAcI2qIIRDp"); - a("yoZ+EFcPObvACsxbQVb1PZOYgMzmgLczI1UDHJlNOn4I9Zlbh+Ao/1O58PxyeL/FtY8gvfC0vq/PJmScFn/5kDjdpF4g27TXsm"); - a("rAi37fyTFeX3OsFWfGUe/zwPJKT3uoX889Qi/nmeUNHsRLDbzHZkGDIBg6L9ghgpk5C11W4HyyfdmKHQ9KkTgaarHrDSm2H5gt"); - a("6MNtM92PMpWJEyYYpzeqbrVg9uqROjwkeq43jTwQnjFudyMiCwQPcs+RAcOyC8n0lD3WvCBZK/zLtfmvd4dhNo1KQUJo1TRypQ"); - a("kwjUH/9oBbXsNBCXvcniNPMl6vaXNcqaFlJNnyQbZxMfLLpB7FVPLqbkRlnyrdi04yjtEZm2QKO0F/W04ZRWL9LQkTatfSfrkr"); - a("eRTP4Pb5Do8X6IHvNYXzXCxP88AR04ydaBh/JorE0D8MxG1J8t236um89JzTLtPQ1pQ0TaWqI+2olwEEkNh94kdPcNND88xkxE"); - a("KcBQY+OnRmjviz9fQ+NcJmHH9gXMuKxgXwQV3IwKWBlXzm3LdxgJdm8BaobThXebJBLebv0ZPcwarnvYu/+W6J2UtWbpNmwXpw"); - a("gXNunYsAzH/4Tj4iRSyJIsUiJrcBJBg2gByiICZTfvPcacVKYJk6W8Sp9u6CWwMpnIjjdx6ENZzhho+IocJm63rPqLLagavABZ"); - a("b6O2PZ254fowZnyO9EojfY22fACnr5Hpl32C9PlG+iotBRgK0FfJ9Lk7kI4bS9w5uO6SWm1oxUC6smZHzisP22ZEVFKCrW7pO1"); - a("KOtI882lukDih0B8d/iRXTJkxUeoR94g0XKjT97ALWZt16gck+sYfa9minPiRdD3xTHLw+hyalOHiWuzhYlakP++vfiqVQ3DAr"); - a("W8u9DVvVz8V5f+x3VFQftmHAvojPOGMXuF5ImQDeNohVWB60w1g83cMVVCmgMdoHv7c+Hlx2CnZAYa+XWYqCkIYEIQ0JQhoShD"); - a("QkCGkIhDSxvReQpas/jPatr56a81tdDRV+LAw11J8j6KvNBT/SYJ5egCd2nW/a6vFRPXqtFvmvFXKvqBOBRq0SASbqi1ckvj8L"); - a("eZd7Y68B7QbpV1uBOv7HPYx2moXRsUTarI9Y7UDb7ZjkbfZHLJaDzGVu/g8vRKNASClq3CS2U166wArbA0DXd8qfC3Gy3fz0sE"); - a("2cSjkrPIbWtiUHZ5RKDgBVwwO0NdgrOJYPfYC5ivzasDvT6eQzO948MCl1C5ziMagM7rv/LiwY1JGMkHyz0Tb/slcIddyNWDHi"); - a("Tpw32ZkYf41AvHzMWYPeP06NK88S3gZKpfn6e1TIgN2EWukGYO2r1Ndn+/LqWSLdFHaTPfi7DNQadL+BWgMQBGpB2AhZnlVZvv"); - a("qDkWU7guIkj/7O8EXGGHrteWRPCqJanIqksM4fNtDU81N6LFiaaUs49ULm75oZynq49pzSZJPN5G6dO6zeRGSEeBdJ3X+nAfU0"); - a("BfVUBHnN+GR2nzIAfTJmXL1r0bzK9thE8/QLWAHa4BjnX9xZvRWwGvIZ2gooVkfAN2P3vB/hQ6CpeJ94hWTXtK9OQL7mNxEU7/"); - a("coJqaM15OiEXZ7JA/0Sv/cj0p7JG/dksgeibSfaTC3NLMDaPXMb2esgpdaMQTKNxXgqo6sSAqU2HmqbK+uNjrSVfc8r49RDNi2"); - a("Z8SMA7cZPj8A1Z0trwKsXfVUf09tzyGo9WjUyrwAo85FTrEEperQBvQ3ciFlzzBl7zayL5EPCzL7J4/0ChmPqwcpCj5jEhDx5L"); - a("utx5+Hc+Sb0O8w5GarnWr47fITl9RJ7uLcOjkROx7ue/zNYy/H2joHvEcthINEDMgeWJrVRoJ3vHg+xRKvD4MfyKNeF6wZgtwx"); - a("Q7VQDhWDcdlqMezM38ModF2J7HLOYgY3cr4u1LGJxYcQrttEt9vzeIqGiruxkkyBmEflUdM2hWubIR86DK6R/Ugt90LHKj1a7g"); - a("0WFffmtVd/JnlO74ihNA2jVf5/uRy/R/8gx2/I8sT4e7BjOGFrvDH82CHGcErMGHZbx5CH7cinMWx1yJEIKbVtD9PZQh/Dlfvj"); - a("jGHXn3ppFBC5lSJ/2lO7z1l5/DRlRxN5fnysl9x5skxn2TvlOIj4MZ5Bf2lv3j5FT15LgJqJ5Lk6lLyWRT61nX9esYipqrGlA2"); - a("lDQ48hgng4jlJ0OCZonE59yz2CTTQBRTJ8+YXpFS7kcFMO4X9ZZppI/TzwtBCvDO7B0ls1DSvx9y8xq2UA5rbHyDsep2RN93cZ"); - a("6hZHsR79dKycL40kskp2s6mmc7mmQIlxnJOOn6T8qOSRaEKE8A8piiI4jkHp5Dt0ivCypAi/gS8yaRYL48THOZvIrM0+KXuCPr"); - a("Rrpe5P2h9anFNStws8KbY3e30SLnBTC+DD3lv3deX5MfZUiZQWtST5Q1nSslEY4853qgvW8hiNQxjwXZEDcH8hooZwVn9wQU9k"); - a("ahjevatftNrNcsBuViPLlqbmoKAvr8NVdzlatVk5Ndu/2OkaXmQy/wQH9wyowzeefMMP4cuUSGrSTvJNjOKyUa7zZLKU+Qhkd9"); - a("3dVB5CSjnOJLddSixy2nxhBmNAhY/vEhDozcZVaiEltSKjc3rEJe1gAFxYsRAtZcfUWtEp08ORE8rDXC5aHTmGyyHsmC6KbNRs"); - a("piyykWf5GxXp5cv8yFcT5owMIVkKJUvq0uBHWSlRJGA64nLkKesniOvD/kV5ELqn/CeOJYx0p02eknLG5k6Jk9u0njlzbIn0OC"); - a("XE+ywWMS7rQglbmwQskoU6hEUMWzn1gv2/toex/1mzflKLU626h44ke1YN1n34sEkHaw/j2g97/0f2MC5Hm9qMpt7/wB6G/uUw"); - a("jF8MNYxfdHfo2kn3PNu/7Qvze+gwwrZzB5vwII6/zJ99g8++MCe+vuxfK/v0lxl/P2D+H5FMQxXRG3zL2Ggh+H5qsGcofdR79z"); - a("Mzzaz5zfDsbmV5Ihf83etj5eP9c5huve/C53ut1vvSbpHHF+ypvx7E8tpZFL4aYaUfbCfLfMtWpvxi35edKNzn+/L2gbZEla7t"); - a("sqb27d9dqL+z2q52+0DdR3KqsIevTFLw2NgVuu3+7AeyfDr+RobSJ9OmUweanXUkkHdpAxXYICFKpZIHUB5x3xFMG8G1twqUyP"); - a("Io+b1rOPYyWdZFZZtQln1lo+zJVJZL9W8fe62bSteitG/NzAtvyX3/9atO8u3+0tf0z8FU1aGoylgFqv2d5vaHUw0FVIMOwPa9"); - a("dgDs5/NXb+xXvtniFhKTxCUfOQGNicNF8bkgVJtvEbpnhxA4QwmcZ7HpddG7pl7kWlXkfVK+eVAVkfNWTUUCpiJnqCLrqMjVso"); - a("iaeT+KRLx6/mEq/2zKf4bMP0SQmXGUOZPKIoD3uwHcEs/XALlwtmFxWMSsE/mz6a2pPAl/q6unUq28Ca5NI0m0CrkR2Rd81zX0"); - a("tazXURONVh6FQBQqFdWHUvlkKv9rlHe9yKYPXuvB1bgQWWiDrjwSASzr6uoxlDeF8s5CXtGB9cgqujaCEk5OM7q2pceEPzb4q2"); - a("+YbEDu6AfyyMUS2hsUtG+lGtAOJxBOk0DeoID8c6oO5DgDyFGUEE5V428GMoG/6W5sEMbbYtWhxlR6VVW/TCVaYKDhZHyqmq34"); - a("f30s/ifQN9cdUquVoHP230AvC1427OmvdxYFO4M7a3vGXZ/cE0l2Pdy8+AgvG0XnJreuFsZ/eH5RksvsH1fZIlD0SUQJf1Z2lX"); - a("GFkHZ7pPoA7ZYDVN2zjFXCqnl60wjO8Sk0vZV9T+9oyjqEsu5K1gnzlbC+ARcTI4UvGUWcDT/XOf3Y71h7CFX4KCqUwKWFqqEQ"); - a("8a2ofihXf32Gbs1jp53891d/Bs8/1686L2p/+keufbS9dobfVr9d/6NB4Yddv5dtXVnoYyhtYtSFWb2NbFSQvtRixLKFoioZuO"); - a("0qpwisrNSTPtcDu/TA83ogxSkDozmQrNeTWsHWjqYjrWL2cRF+N6Z3hS6XeF9R+J+EyBncX+mvnCKm8fDiwjlkLZ3Bms1Hj66R"); - a("+ENp7X+PSSulNPSS035AWr2RlElJHzlknUti68ylxEZZbizSIJ+kp2VT2iMyLQtpLGskE7Mo8Vbl08RjSc8hpP1lubEnrQJMvL"); - a("Q4XXC72FawvPCCUKVJR9IO5Uj6vD1KC3fqaNJvqtXP3Ovkmfuxw5Wfua3CDgbb6FLr0X4+kQYoyPlNuvan46JRtiKhziV9+3uK"); - a("XEo0IbifzslsXGJSc3HZel9e89JhMGjBFiiEvybD+oSzuQQZMEIbZsD4xKSvipxlY6mIs4XNYWQGhqpjOB9Lq1dZDKTbzs/1MT"); - a("cpZx8n6P7pT1Xaa/QTTkR4Doq+/J/uX5WPxtiH+EHhwpEZwIXjaqz3r98f1rd9CM1iH6LFk+P8X/im/Aptas1/+0/uXzXk/mUQ"); - a("G4O4Fl2VNODoR/u9byXilzmciew5XHsqnQe7E9pzUPNXJP2F9j9/iyzzR5feHnqaUab33f8j+4+Hkv3HZ/sdbwyrD1wkn7E0Co"); - a("KNcPilD0RnAQZiMONNI9/QzNnn2V3A2PXdjrg6gb1F8/6zYm7/tiU6dPtVs8Xo+LmJl65ijqUHzEM8l3GU7xqmox0x7xzdQkNF"); - a("Y7sSnTJJqbsK+wJRK2209GfWVf+P/lwg+lPKTUSutPVnydV99YctyH+oPYawrUeSR59v7VNifrKVSsbzh/T446gS7oDV9Md/34"); - a("Y8+oP92+MLtgt7GfjhkerQ0W/aFKDfH8DIpvEKC8Pfc7Wo0u8y3pOD3u38rd4Us0HfYrUg3frT6EXKJHhf/c9U/bfo//7qoO0J"); - a("LfuM9g39WezugLG1a8EsCckqMTUJ9Hevrv132kODXGrNLaqx6XpjD1sbi79/x6BRm/TCdQ7tzQ/hERMPhd862f+W+b7A8uK4ps"); - a("AHImWcdAqLerP+bpqQLnofqeQLcWOYvtrwZd+/7f5IfWw75jyD7ij/PM21e6NQymstZBeorYWlBE1knMooJ5w9kwRnZwKzgoWl"); - a("8f2VUmSb4d91nqNijnD7N5JcjQMNt2SSvcz7mR2fx97/mBPewCxl5uMX5kqG+cwF5M9LPmPMnsfGlsnrtr4v5cb3D058UDxf78"); - a("O0WPW9Mg19L/WG34Fwbt/rSTnw75ThTIt6Vwe7osfLegoHhP8C3HqNj6/ER7dS6pJabHElOjSdfOboruNPVUts7myJ0B1chr1e"); - a("/VQp+HE1av/RNQfzIFoi9Blrve2m9/h2o4TyxNSkzbufDKS3s383IbUNmYLPr9eR7KcK3WPGt4OkFGwyElK3jsKhuZuDpXNE6K"); - a("1gaalZ3y5sHW+rCp0BKcabq/DMCXo3i1Ap9CDDZmkdCsMhowoyQtPQKx1TAK0zzJWsBCFo3ih6L/qd0FrEeU/ZEchCwr6SqCGS"); - a("oeODXukwoxb02NA15r7jxLiR/QySlrsXRAy/Yhoy9VrUNiTnBy7pSq7EzOsVpcuK5h2wVGRGq26JPfw+zYELew3ssZxXQE3F2s"); - a("wKnVX6Z9GFP2cx+1mQC2myOjJ891nUQ45I4b1QpGeECufkF5YGBnA1AdgYbUsqDxeFZs5Rb+dKNE6USa0tnOMMS+ZMiVRnScVv"); - a("zU1ZsF8vE7YfiM8AYugFo5b3GL7/hTxKPe9g7I95VL6Y9LJNRhafrSp7ffEyx02f1096pyNxuuaw75+sxND7WmJ+lVxT0hhvDy"); - a("mvbn1I+mOrmk9O4aTQTpH0AhZm/198lMbqGwn6QPvfKvYNmCnj/aGUdoO0kQwlOW8nPzWG/32EbeSuXRhVszrQUf3hFutyUVzS"); - a("aQ10B4JFdxMZ1B4p642aOmovby2wGAUoTpJXzW6MBVVZ/fW/+nMWq6jXvDdxoEabzoGGJVTlKk5tWEThu0R4IYWzl3F4AYXHij"); - a("CDsEjkyabwL0S4vRfh+ns43EbhShEmezOaR+RZReEJf+LwGsqTLeIbKTwWYQW9zX5UDf+UaLpVNZMsYb38rRG/rCIhg4tUcKEK"); - a("LlDBHBXMVkF0Rg+2qSC6wkG9J6fhbonoNSpHowyGDQ//ruWrRgm6Z9HZ0am9j12nz6JdBmo8rrprkT2s45j2GKsN1nkAmlBKud"); - a("4NSn2tJOFerppThTUFNDdNlPdqqBj0bzIHpZI0m+TQJEVmRGc/ReTDZzv78NnuIDhWOCBRP9p165cZSqJ+lMMkUa/guxWC+tis"); - a("apZuh100iZSZlKpdxSntkUFiI5uAMISY872bA4NPJya/q+5WVK9P/jhIjYo9oHQyaLeOH+m/JPtIPMLy2O7BVUcvtOJnVOhuhG"); - a("3rQe043J/pTtfN6AD6VZE9RdpQp982+k1yLa+n3yHi4t31Af4Y+yaJCOrWudK1e1ey7YpGRFZkkXhxqGRzdG4jKwhJaVLtX7Rd"); - a("C3xT1Rlv0geFFlKBQgGBIoWCPGx9QSlqAw2mkkyePgBxs1rYg+mwUaYtrYRuDbEY3XROh7KNaTenq9NhcQotdW15iEXYrOKjzt"); - a("etAa3KpOJo9v++c27uzU2atJvj96O55/Wd73Xe53zfjTiP6vwZYGBSwBG3UsQmHlssO2Xcp18g7oci7jkZtxC2duEDhM0RXvkw"); - a("T0kHksYkOkllYGpcJRKAJZ3aXSV/FtYxR3nOJ3m36pcE4n76ZvAHv4rMJtXWSOepYfwblO1K2BXC2ZutnqWbESLdy2RanX+MJl"); - a("+hzg1ZX1hWiETYuLfVl1jOs9XdMco1ksBYqu5FLXeVtwkV2IyAiu/Zq40qwEJOXMsq0GBQAVnop9ezCtRHUwFg4axnFvyyu3cW"); - a("gP6hTL9D7nfxXds1uDXC5I+UlWdQMpJ8igNJ/jTdS0Yf/TZXvUl9gGyAa+NK59prOEquBWw+XgHgYzuvCSQ6tzi80o6fvGUMUy"); - a("/ApfJFKgqurRwqDbjk23yWzU4Kucu3x5WqZKRBOx1IV+2qVcAhTeWL+EThn4wbqnF556qIXH60JBqXJ6yOyWWJz9Je8PkUN5jl"); - a("t655Ty2JDpedy49Rk3JfDUuMqs/ZZxnkKSrd8ZjWLuTwNwFMYSmP1ktZHRBvRQG9mst48WSw+btMAiLwI6A9s5aPYlWF356mU/"); - a("ifpWmimLYyoiiG3xRNFA+sii0KqXwbqPev4dFQp2rVNEqGa9sGH6BSVm4oaWkxeHvAYmwr1Ur+E720lUolE0n+dI2FFAnm7bqN"); - a("tx8q7V4UX4WAjm3ftejYtsqise3ktRHZ9lZxNLZdv7IvbFtezdSfb4lCva/zlSEG2sVc6eCTQDVcieTs6Smk+jM0Dsh4smdQxq"); - a("ghhB8B6kdlIaxYPUTHisVDNFZ0XhORFa/eEI0Vy1bEZgXS16q6UDgkhi7sGcy/ZP/gpTjV/sGb2uKyCV4QlUNrwuwfwMOqxkMx"); - a("o3rwOZ7Q0DdmPXHIiVCtCCWLUJ0IpSHE3C40cJvhLAqBo/To4XT16OF0I+QfLg03Bm0x3DKNuyuKQxLhYa3nhNdmIIEOO/enam"); - a("K44eqIYlj4nWhiePma2GIACnGqGMo/jzZ25aeGjt03PxKcN7IObaYt5JAR3ClyiPede8nOZxL5+90iZpbPCiWg8kgyUdJ0mfRL"); - a("TuKCao68vZbNmzjaKWaX+dbZlqpbOGYehZJdJXKeym+oJQuu4Ha2jb4ZoEyV7JvOqfxNJo2vKxZtYqwEJHHH+UaKvYU/hU25Fy"); - a("kRjWYnQmrWfE63bE5P0YT25PKIQnvg+mhCy7g6ttDUBHL5DQcMIekFscasW/mKm26+//ZAsP6urYL1y42paxOQWixTHeZgqmZb"); - a("jaVh67ZsnolU1txJ+NB4aMePkU2fDOQcdgEomV9AvYE4XvFxn9W1jPggCnv46XrnQXHPmUVAuWCrGHykL1mM2Zi+kd5cHF7OB0"); - a("5cEMrIOsPenSdTpNSDsNLKQyjWeadksfAIzbldmZFqemEaalqDIv6Fvqhg5yOPzMCIMEFqDM30UzCYZoIH5yAM6igaj8sk/bTM"); - a("Qp8XpDoT+hFaAV4zLiJcji2Tb+8YgVDLBXcma5o5bGlEzfz3qmiauXFZbM2UmInzlhP46H2M8w8QXJYMmR3QKlX3AI4vgRBlng"); - a("LkwfGLAW1e+ttWMXfxzTZ0uUdN3JDNFg7qEJLv3NRNDu0hW9lV2qRM12/dj/4HH7zl7eMOSFL05gm5K+j+BDH6VvL5AHD/Eq9o"); - a("JWeBMgY7OwTspQArrMxhF8jOaWJfsobgKIGfBqh01ZEkTU7fXxxRTstWRpPTP5bElpOR05tQkU9jEE07r0Q3pSf++g8l8c3gAv"); - a("yxTEsKHQ8sD3Bvj7f9kXj62f2cmoFUv4VJKi7IoggGL37yuTDuF8rV+75EjRPfWRSRE1esiMaJg4v7pLGZKomr/DHWr7MSQ2n2"); - a("bxU93v1V7/dIsseGkL0/mKGjR5qu73JvyIqTEdpkbQtDmMOxrsHBqVhzgsaC1VdGZMHl10Zjwb5FsVmw5X7ULThwx3tR2+ysBO"); - a("O8lPfk3n+A+2T6xjxgKOO8rRUh2ox+bRPsorPv9RezaKwSRT67TlhP+SCeh+BWMUDTD98boB7BHpxZ7DbOLL643zCz2HsGzfnE"); - a("XaL9PRQyfbCr0wd32PThR/rpwxrqbQ3Th5QB0aYPJ5JCpg/jVorpwzgJSCIIfhnnD/aQ+YNdPzD+3awJfJ0zosCvujqawNu/1a"); - a("/5w+tZ/Z0/XGAWWEeeA6Src4BUczhx3YAdHO79Jv1wb3KGDfcvsz+82OP91gnoe991/lfj/R+c/RnvD04ke+HO2OP9Uuf/fbz/"); - a("NuHid/Q+3nvjNE2auDCiJqUuj6ZJWx39G+8PfRCt7+Ch48BH/JKiUrMMH/t86JYY5z8bYqRX6tLdndeQu8/tKEP/KNzZchu1Sy"); - a("38kSE84HZ9OKMzOzM0/JEh/PgEfTitc83K0HD2qtDwRwjr6Vc+vCuKf0k+n+pQznfzqsm7ygz7XuXsYX0PTKAjqhV7hko89ubC"); - a("DZSGvR88UELHmF/uIbPH/tUlvqLiZrwLJYcQhxXcioSBwMaOBIB+/wW0xELvdHNJYd4nrgm4ki0TDrzAryTMyejo6Q30E0vRNr"); - a("J8Jda8f92avMZWU5pl8ietsdaUZQUK806VPyouzKUX9YS/CAy/bzJkTdT7Jp4jutvj+7nEmyhB4zI648Yb2Tgka93vuFNpN1w4"); - a("CffPVRLr/QbqLPQ0h1V7k6wWzthQ8+O6mh+WNRvfQBjlYb1avWni9DTbPK+wPcXLAdWdj+HvR1QZrDPhXqFqjm59oRmVtHCMbP"); - a("QQGO6+m8oW2HJPSLsQVvffTJadA6yW3ybdOrFg85euEQR4Mq8wh8GphL2mzBwo2El5Ck3d1TiIbjHZ8o7zeaTghPV6TURSP627"); - a("yEIBeqC3b0IPlBd83amdj+eyS/OqfeIBMo7K5Qvl27rteW87LI5mh8XZxP7xQM14+9QvcHuyfAC/+/QPwffGAbyvg7ekr3raQv"); - a("xzCi7l7cdxyTH/AOWPZ/eQW8F2eZcG98OKPK1csRMMKfIcRsXCj4Yzr9FpcRx2WpxtucecVa9uXORfUOLbYirYcn7B7ObSmbCC"); - a("1G51+79jdX89+taE6fBljpi3gzFJBZWfIA5ZXcN5H6rRZHfvxf8mU1HeG/wOFr8bLXyUddeH9Hdql3+8c2qrs6ohSBq+Q0gDUR"); - a("H6v0D6YCsJdy+QLx9QL7kClAfUy6KqJyE1/wcFfcxP/NlnV32LWN1fmcqTcxo6t5F+QQ1snv1W92lcqr+bL4sd81lBH9SmNKuo"); - a("+Jhl56pRAbef2LE+1f31OHrs7s9EyHJfA3TTb8fdwbHIV1k2KjDTNcyGA6uLbHmvWx5tAGSaA2VrQHLcXw9aP9ztPysSMBRMRX"); - a("5b3huWe+4U8yfJKKP/i0JDe438fh/vTRT4N+wKXgkPtt+qgCtxD/EInZ7swFZg7bSmsGZNwFb1vuXuDdSGXtTscVB74vsV6OZQ"); - a("pqj4ZfvU/eS5wf2uBQ2ivBFZtqQmVzvSAvbGTxKoKR30X0x36nFo1WFBh7kCWSw7h5vVq3iDeLaG42ZvPGOwT8mw9XBhXHVztX"); - a("AnkhQIfYjv8IIg7zpDb2K4/2mwX/AGuSHaxS+IsmkvwtNc4i3vLsGbyvm6F+zX8XX+FO06//xD2h6r5RI09yuWqnusf5N7rO0n"); - a("0Aa7wg0FaO8DPUfQUTpqUItA4DHsI5R46QVz1asWW5P2sM5433BetPutTFvk53R/QUFPu7sbmnxaPP0oTac/q/jtB/kB7fwn/q"); - a("hvGTRrPEbyE17WyE8jE7sLlxhtMb0OX1rsLTMWrO59GqyX8gErsNgIq+Y4zSyh77FgHT+gwdpAsJ4Jg2U9rhp4eTzcLkak8a9e"); - a("6SmQ/uf+xR81lSio/Pha/q7m8w+RwaccLTBIxmjfr0fY9+sR9v16hH2/HmHfj0MHQj3XuXJ0JvzqxG8V1S8/qXr9Eai8eX+wwG"); - a("AwRHq462De8O11zVpgZ0Wqup7wp6jrCmTlS3b5yxsqUghUZVlaYJLrQ3wi0ta+MceBq0LSgKsDP9RYmQdpoA4RPoyksuWutkKv"); - a("fbIk3BCYUR8J4EP8WqtfmjvJsmkYhDh9kmXz14PwO770SrogcHu8uChwXoL4/Yh+kyybr04S4XsSxQWChQPxiydLgSQRbjGJcA"); - a("XiO58fRPrMBpzY/m4KXzpaJO/ptfJ0rdhhTg6ag/LpzEH9LVMIHp2Salj0c7uIYohKwlVQ8hYURBAPbAVZN0eqw1uIuaA3cjWr"); - a("w6vxhlSzjXZSi+GK6vmzZB0poo4r+1zH6fFhdWSH1JFH+8Le5Ts8bafaLUVtnuU77MVshLdOUyIyPLi8luIqZ88onQYp1z6fg7"); - a("pY7rVLucf2OZDMYCH5Gy8Df+idtB1ZyVMXZ1ebzW1cAt9sArJO7j1WLkaZ+IG8pg7KbcygcHq9vYltSDit+ZfraXUuQxWtBrHV"); - a("D+yn2GaFV3N0gb6aD2nSf6NebMv6W8eRcWF13BJSxybUUWKUm207KqjTzN9MbSMDaHgfoknr9OJwae28BGzx0Btl4kuqxHl7Mu"); - a("O8IGg611OaNSUCAWmFcH6Dm51qDRnZ+EAN3HPmzwXomQBN3IiXkBcki62uEYiPDh3XSOJCwdMNTeVfk3VVtOejigNi71WPf8cA"); - a("xv9y3Iigk/he0bfusgBjKKFKwNV66HcQ9HVJoQRUATSfDSE+KnjgnxwGf5Ye/mjAx95xSjj+mQL/+X3iP/SEYT88SQd79xzg/n"); - a("RiKO77UBMfKSb2gfnJetgVetg3zGG8lyaG4b02qX98j1f58k6WDr6ZcP9XQijugyXubyX0ne8a/D16+L/JY/x/lqDiH6ykNpHx"); - a("t/e5ggS1gtX6Cqx5IOBCSYDKG0eiIOBsxMfkjxH8nok68P+czfgfiVfxD7pZVxIY/3P0MHlLQjWInT0PmDWbRC9olqX+HKGUZa"); - a("eu1I+olE+WSpKlymLV9QSVWiFLDVLbvyh1UXgpOceqEgc29K0CWkKjw1kS0EAJ6Ex8OCDLczpAjqVhgAYu1o0BFgno2fgYdBxZ"); - a("hFL3yVIpstRGUersiKWUgllkm4zyD5X5vyXyj++tFj4f959HCjNYFhkjioyJXMWJMqNNdOrvoVgwPFw6jLx/5NtqywfxwIAEsm"); - a("nrrAWoelIh0acq1y4AZXebhJ4mymp3QC3CqrTWp4lBnIejCSP1ltbr2D4gjfpWgNLmXSvNjP9YPTDWb1511qbxPhtyB0fKc0WB"); - a("cRFaxGwqMZ5KTAeuwfGb9tCj5WbqwYeN07GDYauFpQSVhCEjwkhIIRI2Sq8JvFswkPxj2d0I0VyG1hSN75rFWuPIP+15p29Pss"); - a("PVT9lbajXlA5ANDuN8VNt2XW3b08Nq23Yp5D0M7ZcisFb5+1IsXZIv6gm4y3cExClP6ESsGKN8XpulZgfbS/5VnOtKijJO1vDY"); - a("TCeoVq1etSefdGn4JOBpVOt3xgb343Bw/7hEnfkvD4K7AeBK5FoAaRz3LREnjXh28G1sdXGw9SdfyNPUDXzpBmslYcKXf7BWEi"); - a("Z8DQY5xXqa7b7lHBPmz9wbagMui+rHC2n2Vv9gNVhLQTXQSrtWiGjTIvLtSsUQsgMPISfY84cnl06ykWFymWNR9y42S1JFz49l"); - a("dWvbTH7zM6bqdoM9HCN+tAvfUlBLszsu2VKwQ/e9nb4xHE+hXwm5AGxS6yUz95VlZqzEEp6Z5M+DwzuFDCbQb3ec+N0uf6fgN6"); - a("QcrBmaA4ppGEwqNFl2Nunx1JvNs4ZUNNM1XwIpUFFBLuUJkwTu3jAFB9MSe1QpjQPRg0COxGGDZ9524669Vp/yHT0k9LzhpXeo"); - a("0MVbs97ez6DPS80yoj+D3NQnZBH2zQW/MvG3Sok/VZfEIJIJanR+zClNFRz4PXUKBsIFn0Lzu5ZqfMoIybKLlzvWT4I6VFwwRS"); - a("PfM69WT3eoEAw8MNij/VZOtP16tDendA4jvbsQbpYqJ9ChkESP3te1+4eVaH7q1MpDMuUvaqhIow5iS2FaYG7e7Qlzc249bMyx"); - a("caQWA7p5vCk6Ie06Gjl2rqVqlkmrUjTkIVrOa9r8o3ShWh1utUbc2iuS7PnXKJHq33dcX3/NUhPobdNl68LxhBhGEszoBcWeJz"); - a("7oEZuSBr8RtHF2uf8mX8Qyzm4afTzWKf5VEdORSBsm3jjYcPDnaTC4y3mPMmToMmSEoz/oOLWFELl0euNCJNgOBnSU/1CNwdWa"); - a("DvzSfk0wCkE9aNaeRWJQUMi/uNiXHFLAMd1ApQRnpbAdedvEcIw2+LG/zltFrLKyF79BGDLRNtiM51Wt2Korx9aj7BwblTYSTK"); - a("/7cdLL9/dnaCre9/019p/RI/xn8M+LlZylppZ/+DIUWYqweV722nJwOP0gRXhds/XO70FhwZaC+GrbSZAKfZgmbOokSgs6MwbK"); - a("j5OD5McsTOI6t46gfahCTxd2X9dnIt41ht9lnwmUJuHvsI2Z1heHCZsRI0p8wXjLxmTri5Y4raxl07/jJNyH5Rbut+DPzlL1gc"); - a("BtW628XVI0HYMsjSTEWnbbwrfEaCXNB1yLBlhZbkUtDbzT8EuIvfNrROhgJPYGY0Uc3pk0CDhJztx9KpBlBGSnuA8hU2UZ3rkN"); - a("COOvJxGWJehhz80TSb1YBmKbg9IVz0VaLO90PIglhP+6Ej2NN02LQWNyCI3wtwOt8Y8CDAFYTH2FXcKprPb3UzR7dcosfQPgRD"); - a("BN76V++1zyUt9CVznODEfFApTSiYVqUfFrW5wn+ZTDWNRGRW9CUZQMWLZWoOSamtvNOK07B7z6/oFBWgl7cTMMOZsDpla3koO3"); - a("1s0mLS24p4NMZKunWV+shXxeiVEPc/0m+6l2TxPOrhFffARn1ziY4Umjm0xYf33asvUOfFCk+2OTxn/lFqwoq45Z7u4ExjjxKa"); - a("YTn7JLd3OLBi4qvV/lEb2vSJbhhRSIp6M/65ZlaYHqZckBK85MrXknKw6APrXQS3l6Jln5jEmjAJgK7MdSWf9Iwv21EFEpbnAw"); - a("rECOpYoVN5xLhGDefsvWN0OTa6ymLWDwHNtJy+ZGGsd/4Sg+UHRKtRhUk77KbsIPK6qyaCCqhFIK9qgd0MfnEyL87SxuKUI7lJ"); - a("xQGoCiSu/R2cwk4v/Uw0FWDQJZjuImx9S9YD0x7CxmmFro0dl6Jrm/DpRmqkmbQ+C5O03NMPidA30OJ93zD3+Cz/2JCcZ6hofo"); - a("FnOs9IOQOMkNVzwXKB3u7jG5srUclXNmuDIkDuDOanLd/d0paOr1Z5EG/UOnPedfjOhfIxrzBqN2SRnuQUuBgQqD5iomgdjBsH"); - a("gVuXERof1IQAMPIrWEaa4xCKEnMJTKRyn/OaRlY2ldFzHPSOQxApVIvkL3vf6axv3cN9BXb5vcv776xGwwORDaV187uZ99dS0B"); - a("eb6ffXXT2Eh99VvnGfrq43PB3u+E9NW7JvWvrx44m/rqsXL+Gd5f/xjpeg1Ff63vvme4snTBDeaZruFqI7oMI8uW5SerF5n9E/"); - a("V5TDidV/OMUfOYfJG78ocuDo4Cz+CRDjoss5enC+7uhI2pvFkn5w8Ru6UWOksp5nT6qplnIlMs91OYwbC77qdIBMU1FNR3Th/N"); - a("1zqnZxIidU7OmfrOSe2YskngSUA2Qr86bVZPb4hilMks4pZnlmXkQc0pauo7Bwu7DU8SlqYg7lsfQXykjvonNBkqp7Gk807xdk"); - a("llGyb5DFeyzT9STRgKfg7VEtS2dVxtW/fItnUFt62/G9qWdWKveucQAhB6R/ahIfTOw4bypolR25WEgXYFAMsJgA8AZGwv7Sn3"); - a("VWpKG0ZHakr3TTc0pV/noSldBj7pcFp3Tp9p2nshsvpCGoprVITmdC7vyUSe8Tx1QVDXW1K0Gc+pXB6M0EwwekGeT6T0TZ4WyN"); - a("PyX8vzRxP6THvzBRHkmTuh7/KsuqAf8qzNiCTPveca5Hl4Vrg8t2X2mabPz++bPFdc0Ls8386V8izNUGU5LUc/5/CP1vpFbQcQ"); - a("ox9KWd2fxvtX8j06QwtXx/AZ/LyjAJ1uXOlM+rLsXGTW9U7nnRupd/IAYR8Bt7oDporHOq8j69qaLg2TgBI8bapCjdY6CIu+gw"); - a("Bv+6lTY8f3mf/rcyPo1Fvj+q5Tubn90KllIyLp1A+nGHSq/KJwnSoa12eaHskx6tQMy8+bXKMjqFU8sEc9kfXqJ+eF6dWRGQa9"); - a("Ch9jMPgF9Wq+1Kuo+vNpdiT9KcrV68/uSBXhCt/GUZuPlabLMrQ/sYlPV0Gub/MxSxUdLPH6HnGlI2CxYg7+r6bLJo/RRRk6M1"); - a("X55PByTrZmp0pon3IruN75myQeE5HKz5g0TLR8CynfHcF8wjRVVZt4oTV5Lr/Qag+dPHju7xBPtiiXBkoOxvszAXAq4ac1XQ3i"); - a("0XwNolZdNHh3ZPK54muJkiEFprkWy09bEzWrJEpcqJ9PVFMjqqkLraYewRCkGgRSFSJ3q8CizoAFb7CfRMPks2UBf50o0RYKv9"); - a("0APypdvyGIJkCMwPch+f3n+xKC93SCAZ4Ro3ZRwZPwDx4DPzPB+w7BQ/5LRP46I7h6HQM0fp43JyY/d5DaxSeo/ByLEmHo9k9P"); - a("lowj+gHcF8IyydEX8vqrd+ZxRH84PKPIGfx1eTH5+eexdF4cL/g5Q+SvMwq4XoB7ajYnN+jqisHPZQT9GbPKz5dn96r/eIcqoR"); - a("srj6r/Z5P+S/h6CdUJmP/GTnmv+nDZ7Jj68HOC/4WJ4asANOiPSOhGjCX8d2bFhH8hwf9Zb/Av1eAj5JvVf/4cHQP4F5h65c/c"); - a("kBoOXdxf+ZYS/CNxqnyfjAIg8RYkRmn7916s19UGQ228z56E2vxrkdd2cTRWJCaJ5MhtYmrseh4ZTX07Hfx0w7Z76ZzexsoJoQ"); - a("vqobphcyHgqLbZrleiHtSyr1X+EZvu3hcrDae3hvc3D8qjgCO2nBPy7Kw7wSXfByQ+b9YdtRUUbNmAVekFuBOuvqP4R1mJo+YG"); - a("eS+9CHZPHUim7DiHLzhp3ZWJ4mQh3I5zh0kXYSOr4+SZALmXsiNDi5Y+RWlBwnzsxE4OWH6LeZTVct/fbh2AuxN5H1Y8Dtptm0"); - a("+Ujg/iVzocky79TOl1zFJ8hdUKn1Ks1R6LGO/jt9KFX+/yHJwZzabpGhUWXqYcZJa0kZzaKWd/pJ2JGO57s81CWZ4MP3UTkIRI"); - a("QF77UGW73r9BQTXuibcQUHoHM5mmjpd+Do6Y2v0TcBYh+Fgw58J8V5K9JiHfn0pvYSrn5se5Ps5tMPg2CD3fpe3AZ9CdGw8rtf"); - a("vvB9xNCezvi/xjsTlo4OwZbXeDqQnMWuNherh/Bok82RnPrcyPK51OFJR9RjK9xQQ7t/cG2NcdLWPOcmDTXPhsSIElSLb3362R"); - a("YMQfjenZbDPee6h3RBuVox+ekeRE848B/x140QJXeyQKAS59DnoiBzk2w6sIuefympXehAEFe1VALLHEPbDPixAFZRLHanQhRj"); - a("NRb3zvBvkXevbhdl6OvXifswa7wUBTs+4oxW30NzE0hr1i6CTec+0nsNobguJXi0xtUpf0dnsIV2UlQOLX8lz6r0+b6HKU0olF"); - a("CncPldHtJw9um2yG/8G3zmgo6fBBeh2lf5/T3ZfcgUCcK1O9479qLHunXo4f6WfWk3gNsnDFv+CKE+0c5soN/qQuxpdRmuH45V"); - a("D9X7+p4Wc8T0eeVMrTwnm8gz+dhMBDlxJDmugghfZ+W2wnA/jntp00AaWXkQM3bE7avak4ck7fzUEbggl7g+9CwcqrvjLFwULg"); - a("EmR5WJ/Fg567/GRc6VQkbOIEJxISb8cnO/xN2I+E7yIkXkmYscZgl4W72H/UXyGX/OtOWu65WbwhgivExOPdmkc43wjmqQc/wv"); - a("kF1QfwGQBIrShZ3Qyg/0hTAPnnc038BAPFP8syx0kF/xI8AD/eQYyyBUdvVBpjythDiEB8C8WvRzyw/StHwUfT8CZU9SRCQrPS"); - a("WJLrxEjXrR0kR5FXJYFdeKxXffo2pY85JvTpnKwQfXp2FNP+5CidPsVlhepT10SDPhnqp/zKgTd6rb9jIun7G6L+5yeG1H90JN"); - a("f/8khd/Q9ODK2/Okb9lQR/oaF+4/0P5LuG8g2jfFI5ae/OdhJC9dhOQqbd55iBS+pe5bKxcXHQt8T170JoQ6nUi/lSuctmwgkd"); - a("l1X9bXeRfp9AUXIOSPqtfHs+2X3uqngP8NVrJ+Q3b05QZXafE1SZprmy1zgXQDVxc3ut196bAUm2brCMKmpJOMx1dyeu/4joR5"); - a("zivStk3OHySPvBUAz4n0KbiH7K59bn0/7lNjT1Ot5U7bNsvhFx9Xq6JT4vTSDFvfCwPe8L14CC50x+a4mP8HoHnGufQPXhTKmq"); - a("oSz7eaZF+O9N3E2livcXeS9spYJJVDDZBw++HQU5gYJq4xCl2UNXJ0oOvL11Y+ybhHt29J5sCt3/akU+MptyF37VgaizlJj8Cb"); - a("vB2xvM+QjnLB2k/J0T4v2LlTtPh2a5U81yw2mRZaYy5UxolmvULJYzIguMLl+gVuzFr2ZcXa+v6ZnoY9jd4JqrIj+eCtdfl8I6"); - a("7GlzeJo0f8NwIawOfpnSCnpIf+WJF32IPRMypOgiRDeavLggu9ee11g2EE9DE/Em0x+PZ5v0unOqo1gWWZRJZon5fe0zJn+K4n"); - a("j3DHoz2jYqqH5bnQdnBwKQFr34Y1davfsLeGpQH/zhQbiGN9WCNITIAYj1Ljw2pk3EQ9LrcSD9siSokf7Rl3xrXQG8en9qHel9"); - a("+aC++ytjPG2elxyeV/BYLQa2zuKDQWzvTQzDNu8Ly5Vv45Uz5mlNmKexIZkb0EFJHxlXMx1h3spi0/N29v/Ibw/uvkpu41aUwP"); - a("/1hMjcvisCt43vc7O/Sf4ydpK7QezyE3rl7jBwt+hwh8pg0+tnAv3mr9eaFsXf46EBfZhfRiWFwazZHQg6yBiTLceF+wyzycj+"); - a("FXj96kqXrgK6gm5+uoRv6644YYIfdEsL5fJdKU+G3vnUFEfN3Ub79dISsfAvRrnxI0CUWoX36zmUl7IZ/f50C78/ipYu/P5UwO"); - a("WPsuIKEESxhqE8nB4F9HTRrTSqVfguUhisSpTCvosU0FSm0tQRQhN3YU5FpUfR09Mh6VEEPV2CHoWyGenpEvR0aOmCnj89DXq2"); - a("FAl6lFj0SH9MffanVRvqjwmZQI5nXpr46vLM48JYAMMxMVIuqcPat2z8DNqS3Zg6Y9ZXCJ2Fk5+KVOEqKznOPwiwxbfBbVaB4E"); - a("NemCOn6H6c/lRH9NsNfpzC18Nea4aH9iG8RcML0YDUOV9mCs/5RuGHpGJYkkT0N5MQw79ROdqZqx39Rwfe9ytyUSqdBstW56hZ"); - a("1+1AezoHsPDLnt1O08nEBGwOYe3xxnETt0Jayo3DvpTw3hXeSvECQ+kZHfbamD1KLJjCU7wubcn7/vmGnOxf04EYJ8U4KcY7gv"); - a("ul7x5V+6VAj+obCXR5QZcXdHnXyQFWv3/ELNKTW+T5FxF5SbyByLmjiKL2SF0PkCWazwVN+AQn2mCPiajMGK1y3eCsnQq3UcAY"); - a("Nu53iI5PXylrq2VTIz5n0GfpEj6tLKfw7K+QVPWY9h4/XkycuybzToLOxZ1Sk0tsjW+O+5T+Fpj+yj/mPZ13q+/vzaLss+FlF6"); - a("tlA6Jsj38F6tOVqQwvM1Yt0yPKBPyTZRk5uXeEl+mkS+nqdo42/va5vy4N6a+pT7XWK2f4/PLQaWEwDi3a0EXPE91wflgXDbhR"); - a("++hjf0Sb3lkYuY+W7VltwHuSuQHXJ/OiLWIDXlOTsMTdYG7qTT++IX50Cn7s/uob58eBJ8CPx+b3iR+WgcyP5IHR+dHUx/ai1/"); - a("2TE8P06t6ZkXU/ZOew0NNwuIM/w+cj6K0OF3qaHJ79uPN9+L28JsuV7ZgmJWOapLz/yhkxJeoOpbioGJLaC9/Zl7FNqG6REAs+"); - a("BmJs0x3jRwAKSjbZD39dmNdkRYViTqaU9lJfPXUOvfqPXd1z5puYb516VptvPTE2+nyr//q6IUxfoak3YjyQmipdKsE63jc1zx"); - a("r5e+js5wVGnQ1vvwNE+x1g1Nfe+L11TIz1RCuvyRuDLHcW76OZOQYT9weoJH0btttCh8HDHXLMHDpBjJmagtdNYwUPWcrSsDke"); - a("pnGcFMkmnSjSO4xHzvNePhP0IztfiE+OlWH25IAk4QaEoZBFpsaiw1/RDPit9wnLT0+ZVFZ42kKaTxxWzEb9j95+5VhyYWZY+z"); - a("18rmH86cWf/Adow9iPPtyR12q5stFe3Oow7fNPk/svQNpsbVSSbdWmIizpHXn7bksu3GJGEHcdhU0qMyJvf03yQcITDbKBH3N2"); - a("gpRWkFKY14AG2YAKimpSi/xZ4hzJ02az7EyzNv4zGb8FJpuprcTmYbAAz6Df1LO4/ulo7fWp099Ie738aa29fj0qSns16Ht2Eu"); - a("t7ZlKf9D29cpxJ1PdRdpT9mVj2pcLnnzOyAVi54WOcTHrexZEH7QzoDy8EaZ85PYqyDmcJ0oPXetVB5LWxjT9FpqdurKTn1Pz+"); - a("0xORFjyQcA0GqujQln51JuC/xge3yLI9zxsr2zNqlBr/DvjIU9GviESlch+dVQkx/pzSr+xk4/zkqRicAUtCPbDlRCBcEB27/T"); - a("17dvj8L9swl4v8ftVrNuz9KyYcjPkvFPux/Kah1brl7IEO71B8ObyjnRR2DDLNr05NkcnVqwaarJgGoYlVvIwK/qf5z0uG8YS4"); - a("Xb2dKLoH7j+Vc3FmIIpuag06v6umT+VmJPFgU9kuqxehN2UI9/SwAvizCeuEwh8EoTxIRW88BFmFDE4FYgDKCxucoo9Nd/4GOF"); - a("41J9LYZFzPaE6XB+udLqOMl8lt+B7h6GXSljG+Xsa1FmzYI/f1cWTrgSm1HzRleLqhD03skNOf5nN6jju96+Ic2L4duARaWXXC"); - a("ddwdsJS9QsepQ+hUfWDQbXPktU/E8a8cDHN1A3HspgLNdn5vefAMLSLhffBm9qLfouJfAPxxWurApqsblqg2zlJL3I4SMB7Xna"); - a("6dTZGjeiWQYHRnsQ43G4P8aINXGO/VqTgPg1P8CW2uqwmqazCSScCKFVB9Ko926Hh3DfjlHyr0WY27EXGyIBr3xSiKa6W3v6s4"); - a("8OVN/HJ9XJzp8lSx56ugPeLXZZi5RezfmTc5ryo3mYmSZrvqwd97FdBuWE9ol5Z4Ex/A19QFqUrPAdS7EUQMV4lYhRjlI/yBbF"); - a("V22REEH1NV2hTwQeXJv9f2CAhzZDeaHy/m/OeCwS3DNQZPjAeDH4k3Mjj1UeLTdf2iD5KuMjF9VLOl6o/Ip+L/wn7gPxIIs4nh"); - a("Ep+Sgm81sQKJ/M5WCuHR78o7pz8junbx65BpiMNVXne3+dZpIKFQR8K3zWTv32wkoegR6IhaxVyq/xf4w8xj4V7LtcL0NYH/AQ"); - a("LuBakmA82x5Hl/nCrP0qUsy/dvYVkucP8w1cT8L1ExeGgf65JrrBJHdf2Vu6LbgjQ/sZZpltKqoUGPZdU0TCP0dhMI/dxkJPTb"); - a("24yyCutP0NTovLjHxAe6g7yDpx/DXKDNP4DuD+HTOxtrFE+3mOKl5p4WE6TM3P3iIwsfjUpOrpyMWD1HrY3HE6y5R63u9y2wgc"); - a("sdjf9s4G/12pLzE3ffjDPOBPQFPupsFAtIR0+DN1P55WmuN/FpqfqFuH9SekWweB7eZcnyG6l8ZlGNM9mbfgO+lW2tWCY15190"); - a("EyUMsHrK0/wWAfuZVobtai7x0c/8Xew5xukkS+t/o4zWFlsqsRrn2TcT6rZkpwflHkY524T3r6hxvJfh8HysrES4yGNjm+4exd"); - a("D1af6Pj9CFqREt89NYKa9qpV6hDa7lPPOTfZofY7395mR7C2uQUjRZO3nU0nEwlSZH/DRyflcHoxI5DTJf5PGS94cdfdofLtX2"); - a("h6Vtaih+R1aP6gEimSck93SdCYTuDF8mxrrZYTvDUfeFf/Ewxrj1Fxj3hY3z4TblkU8N8+Hw/WKH9N+v2iyMvW/885B9Yx9t2o"); - a("LYLyb2sOMjB5YSRCzX/8NGnki3MTRwQakhhNheG4p+I3vE3ofAi5LzDXvE/6s8N0SSZ9pEvTwBxpumvPCJUaQFQnB5YSKNvtff"); - a("9EvQ8UiuQaYGeR468X+Q54MR5TnxHCFPSSiJlVF4eI9BpM+fkCJdHCZSq+DInDCRlkSX6XMPghf35RhlatTvDmX38cj82JFVJ+"); - a("wVtAlDBe38Iy23dkhjAyn2Gr6ArtTjAaX8xsybAd/0JcSKusUtnMS3B9PVT2LG/GT8QrlJaz7TLkP/rksyYRWri6jXy/Vq2Ov7"); - a("q0pyYzoI0lA+BqM12yvafU0QQcWLPIeEDWGn52DlJXOvBgyy5ZI4rFuMMYO9gzPeozEG10b8U+01Y4ci5M9Ejs9OBUehkneCo1"); - a("AxPpEVwxAGvSGgC903+mVMye8tB9cPzuUFobg5uIfniVjkiAy3UIYnkMFaPwdoiMhjlYh8AJEOstdVhoCHAwAx+Po2ej8xjl3H"); - a("X1/keavIOwQXQAF4QVaPHvBIArwExYDSb1NNErKJYuci1uldkCyiPqGoqbKys6iysxHoJA0WNaZvpvmmViMArggCrKMCftywCe"); - a("Kxe2IIHvdQhv35jEd+sNiPKfbZfFHpr+5E4HEE/JMF+AuC+RZTvrtlvlLKV4EAcqn8DKS/vRyIavWNpxIrZIl5VMKJQFVg42JY"); - a("MAhUfVlWJJcZBbTOIEh4EO8d/pKE5guFdpgApEpoJ+9AIIBlUF5PRRPGWmD6dApJ/g3kfJxy/hOJNAXaTzn/joAPKse3ZPVXap"); - a("+X6xyyP+Bpc36/IcNRM/incHt3uWVnqslR3Agz564RWtIPkLSwJsHURGVOjytrMVz4Yf3mKzbqep/NJpeRrY/SITP2k3oP4G8/"); - a("fN9Neitgiut8CTjh+136pqU12aeQvidGO9grpz1ZXA0ecpoazEud9yEE/7IE2my5OxUhTGlLbya4t/E50I/V52tl6kcFfwyEyz"); - a("f+WG7ZXKUmVasf/yHuusOjKoL4vcu95JIQLpBEo4LGDoKaKGpE0BwkkkBi7/WzECsWSLAFOIloHkf07FhQbFiwYCGCSkzRJEiL"); - a("IIrYAgK+4yxBWgrh/M3s3r13zxyI+un9cW9md3a2zc622V1vCLg/BDwYAh4JATTe8j/JOg5lvvJWYNOAAS4YC9gj4AWlgEsE3O"); - a("sWwNcKeD3RXCLg+YADZ4u6O/JWwCMEXAv6wEkCPpfcjxawRvDBAp5B8N6y3glOFPCn4Omjtc29QmPdd79EuX3ZxuUWOD681YSD"); - a("bZlhK1s2r0Xow5HqULi7KNzEdg7nBnU6NM6kzWGNk7o2rHF6ASymsRlb3/5OU+K9HpJDtGwpZxb70VNdSEGtfrTFjNSi/1fp1R"); - a("ui9Yc+sV9bClNo6pNY5WPmfQZnkLJA02nZF2irmZnSUzyszAoetk/y9muMmtVfxxoZX70BGZ+7jTqUhsB+8DyzxPBcQJ7ztrKn"); - a("dlk6Jg/tPHmg3kLPeFAuJZ4QDO27ljaL7iGafc36riBbcK1cb8mo9f5reqoVWZ6JJYJXkO05WFKbF75+vshYUjOMurTV6OyY+e"); - a("0YlPHIhA4ipNlvkqugaxBnwAU6wkCrnwE6seZl3BPeBIY1VFK0Lw64mQ3kJ8iy5QKsQRlVjjHKKH4Nnf/gMqot0lqKpqwrUYtw"); - a("X5ivUFtLiLMAxupOyKv+2wOywDZwd4rceZE7L3LnRe4M+0UI2ZaFbNK5BH0esCrIM7BlZ5DiUM+41Yi85Cu6f2ILe3s6FVtDTj"); - a("qRJN1ikFxHkr1lM5OMkSTgCZEll1HgCWxQJ2N9CWtUe7cjrFVYDXlG00gVjBSYK8YD1F+kfXLEazjbybkSzmYmcj6krzyUjXz5"); - a("EQqn3kiYNx19uHkqJO0XZYx9l1/NSWvEh36BVLn+Ms5JWn/LKaT96RmM0p/N712waqZKzrRJ60aPzbjGVms+lKSnVnccWAN98A"); - a("B453kdnvK1MSiSW4F5U32YadF7IUnDWhRa8NNHviFFN3uX/Fmo7l7L7Dc6DlwOhplgmOt1hDm2/sAcPwBJjb75dYOt8TP4Z4QV"); - a("l54NUmilWDKVDKhsXSpDdk/fNnvX9KvyMI+kQyDU+R7iBaBvRRANTIYScWlvfetrzCK+EQRyVA1fo2Yt+m4Wgls8LfXJTVm+GH"); - a("E7Py/WWuoCrnsRNB6vvdUY01nUZCR/1MIhc0wxRLdPtO3h+xZLta9gQlcEHqEl+1xtrdaOgXEREvrWmyiVemz5Dsa9OnTBDEcy"); - a("34EVpk5lYiotxbu1rzmEXs60PuhJmj1SNhUkJpAIB1o2OGeNHGCP2uXuhFyfz62o54GRW1yzth0iiH292KlwCtgrVvFBW/NqfN"); - a("T935auXd/3N0HaOC4K5z8rmLWNxj4NitZK73VuUzAZKqtrs5VmCpXLjLdu7OIdJqJJmk40lYW1sD9CfDzkCziJx864svc508Vw"); - a("0thIH9k2mz9a979++KfpLURayssm7wiWZpmSeyont6gN88Knng4Geah9ECi13Ad3/P306vrO77t2995G+D7FrG94HFyv8MN+V2"); - a("/lMqujJGUj1+z4ABwbc5F4/Mo748pwH/3r8GrAFvEWWErNp37qg8RkSMT62SwRo30NNBzAdG4Lz+USQMAJU0WGdTGsfPmpIGSz"); - a("XI8pb4sZl4W8Y3YYdGMh73chYNx+4YzuKuQcw/sls4394pig9U0Mq7xVtiG4Hog4r2Odz4qJ7IIWMa3Vxf17rYxhasvvPnNhaY"); - a("uygqzv5f5EYUM2bhwbkevGGFVbHYrrgB18opJg2iUEkf4zoqcA0xpoUkVhsiPDBDojwgg6fS6ClQd7lEGcikPxinud1Pwn5sdR"); - a("sW5vx3KmYN1GrPPQQLMMvg9b+DKRfmk4OZmKDHOEEeZySxgm0vtzWuJc00hP0m7c0VTtffl+DgSoOFWlt2mS6nbS3d98f7Fklx"); - a("xmh8o8LVlvwbEjJn2fSTNMpOs7zKTp+lyQUlSDKar9KapxHFUshz99B4XvZwr/UkT4DL00FFUuk/Y3kd4ZQdpPHxkizeok0kNN"); - a("pKczKcNoFpumB2nbIrG4kd8cV64NpIOQwEKMl7pobkcJ3XdeV1A+yU3NXbK6en2XKdZM8QDgDwikb/y2O/pBEfTZgn4Z0X/A6S"); - a("2i5pVqSusL7eZsOfVx38hsXdRB2drPRHp7uzlb+yJbFaJcj2bSPibSogjS3x6nOlCoYgZSxbgov6vbydFOjkeRY09y/JQdY5jr"); - a("1+3EdR8T1+1tZq5PMFdHmGsPYnAPM4jjpt6Pm5Voq17RVr2irXq5rcrmb+7/X0bmaathySjwciK8+b2tJl6sQCd+M8gyl7uq6n"); - a("KnFjoOwxefwwOFpBcrmnKzm8b2z6tocnuwgVxRF3qPzVOn5FEI12w1uQjjqezm2wLQSZ46u6ejx7hkCzMfOcbn3YP3uu5ZWPqa"); - a("ZYBljEfTOMH6zlldWI9poPsHMb4o1urnH8H6Er70Aq26+hfFNn8kn4cPOTXBqVF9G//xDhug2QTZCHoJEKvb6bN48JQZsskoxl"); - a("bAwZp6N/wxAA1CtWrq7UDYF6PFBC1tDFCf6/1F+keQZn5/yDP0ErjZSmL1V1E14T2DyP5y/+1R+x/jPMwi83tPCCWazeZOCLx5"); - a("HBuUk6LQe3nDVtJyCw9CbA7aEIFZ1nwbdT79nucdqokDqEvlffmrmml0VHx32Zk7k2x0Iw+7MZ5gw92Buh0op7iskzd7Q2Ok77"); - a("bJYRGNMo3zMVb5Kp4ZbXxJfUs+L9yqlb+ivORgnJYzxBrgUy9i6wXZ1NS3YbgM6BBNfV9A/TR1gYAGamo9IBJgfCjgIPc8D++P"); - a("ot4Z14fN7QpWqK+zf9KCdvh5ZlJe1P6/ilWDPpgE9QUMLm+S9xrh3YFqxHmuoW6EjB2XCDkZKZIOtyPJbWxK+dBBAJSxCY3qdH"); - a("jayZMyNg+AJcPh+WKBjc8fOxR5/hjHlhH/d3AOTTfuXqHY2F+/7wVIex2cqkUofda6aOVpka8v5fw9DUDU+TvLm/l8Chu5LfVO"); - a("yLTM2nnpZnx6kVZLtmQPVis2Mm8JpsV9rtB+GqwKxu9XoG0izxLh2cpnVn5qZn9okDHPdAmLDimkM5ZLIZWO4dPS/Qohm0Whd/"); - a("vYjpyCQKlfjyBaB8u0fj8kmcy8SEDlKZ1OUnDGYRdDHi357W4+UYj9XuOgt7Y41zsmE4meN4MEoQQG/ho94Km1423nXG2jSMJJ"); - a("SELhVa0F5b/a9UkgRB5OoLWDcYDL224v3TdXu/GQjCI2hJKbvhW8rN7g008X9HH6vfy+eKHW2t3MotC8TS3P3y+XZxTpfCLeuq"); - a("wZl+LWagsr+87AkuwIbx9vXvzqYt+UmrEtuTRPlM9CxuV5C3YUfO6XL0YCzQGqw4vqIq0XajEkeypgnTYRrFJ2tmG50oyAhq3/"); - a("MZSzo2DaT9+qH6maU4xLJ7yJIc6zm8H5y+ewtJMgXjTrWAHRlNpxd/yXgpa+50XnP4r4P2bi/6SZv+jPUACCPcvgPs1SBsPsUG"); - a("b9IOTy5EJBWPR+W6bAoEDUe8rMsOgZvVS3/Ocv+6v8H1gmbQBEFHOetUZh8A+/JABe0PAEhlJ2RzfB5G+X4U0xHx+VBYdH2jlc"); - a("roblCjALxRx8xhqse3pTTIufiRKTVd70d5Am84qT1X9sN/67bS9jzoreXkTdmJ9XDbWUn5YYLeUbwPqszmDU/k0t4LO3qn2xQt"); - a("iHAushsKQuxmIFdrnAbAJ7W2AdixiL2cnYFoEdJ7BfBXaNwHSBaQJbK7APBfatwJYI7EuB/QBMxlcfeR66BjpQ92wQmxx7R25y"); - a("9F9DoeoD2eFlK2+sltvNcn36hcai5os1CLlMhOQl3aTX5sLlyBjeKoMN113p81NAujn/JV+oFnOs5mjGe9HrRcpi6YYcXuTPBf"); - a("9u34+429+Cj/8T186gGf/Cgq+z4I5vgpH+VnxVJL7la8Zl+g6D3YGu0ND9Wz/f3fOSKOlnBrNEnBBkbCYw/aktoDpsK/42bSP6"); - a("7Uz/6c9Msf8wI1fW97Af2gjyvvTXVkNh0h7cxCWdkAOuW3FlJeCJbsD7LO0ieDLBSQKeRbAi4NcInrKB4LSTf2cWL6+FTL/DLN"); - a("IGCKcXyelZwXU6hahfwiFKOth7JXl7RIjrdrDTsHVwGiOc7hVOl9Ps4iLB5CqCJ4KJ3F637Cf42nm9YTp/Fszkz9xX2nm9YQ7v"); - a("+nw2NS+zsHJGDSMp7obhThv+4vHu5PCEvIrhofcuK6cQReGJq8ZnNEyZBxC7pTAWn0vg/IVC4vyz7Xx3LmzxT1KvPw2mR5JW6Y"); - a("Z2EtO6PXclYHCfN3iUc0JsQXkgOfBoUeXwZLerangCMjwaTKY67O6KnHj31OFOfJ3wyomH10XwclXDz1V9dmL/5toWUH2S76pu"); - a("ElenrmgpODgGjcQ9NSd+CJ5zjUN0uKrwgIFyb4++LkV8J+Hr36BQesBteGJ5jQMxJSKmMxIhRM1FHFMydCucE9yeGxIUymP/Vd"); - a("QCa9cmw8S/QLMVuKpzEtkirAPmQGtj4Jpf22aH82KiW7ERtTUarJDG1F50z/wD4xSa2OGUJe4RvEbc0SXi1yPiPyMcvxKK326K"); - a("f+MexL++0BT/tM02I/6fbKb4axQZPxhWpjUXipIu152h+B3m/DtM8WOVyCFWiTheDCBX6PR+hYjXoeCyZLzNbIr3ZnO8ekS8F4"); - a("TjdYTidZrz/RfiVU3xlsXJOAvK65P9A/jZDdEwvKJheEXD8HLDMLUmqc+N5rSIVyn3gUhBNiugvMN4rqu6hx1/6o1AsAl3KH14"); - a("M+IG9Fcgu64mP5YNzQesUfAZYs+vxKt2oUZhJkgAgWcIbvh0VvS9DGyKfbhNircI4Q+NHn39v1W/CQaE4n35hXs2X+HHdXEcSy"); - a("9DQGOPke3AkvJxfYL+MDyQsSGA5X3bWFfroPswBwBGDVaot8CvQdXwj89D4vMUPkGxSOtVgyqVyhlOXqt1ggcn+sIviDOAOVh8"); - a("oLFMbUsGrCgzqH9GABk4rQ4wB4wLBcwIBbzNFDBGnQ9ChH2ewqqd+Kdxi0fdBEjhcPmwRnRVqbWcmrSRI2nen1rHXm/Ai5a7jW"); - a("vTyndCiSwlS1i246A7vmiuNTU3G7PhpcQCtT4LX0hirJDEirTxwBHDW/jgpQpXVdpojivpe1w+UOHo5apKOocd1O/gMDXtfBXO"); - a("qU5wShsiCKdASvUM2IIgbH/htPx7zNscDyK2bGJbgwI/GsAQdeLhlISDI5IA1s+D3tvD90FwEirpXLDy5Z+40/XASWIc5xmqII"); - a("BtQjLDK5GMSa5pX6GXbVBfARL0qM/ho4DPYHyRiof5k7SYEpyaPDjVWZaOHE5wcBkez3FN1pfS4wH7wX20cN9fuIs0fA5Pz9CR"); - a("8FHLZjaoborG51FPpHgQ5Bh8jVbg+F60AmGrAe+UCO/13yn48DN56tcxdhJV9XN8ga7GR3YVp+RjMMVXR6UNcnAhHulgIdLXN9"); - a("KWuToDtMkIOouCem3ovV4fgd7rHQSIEQF2wEcshm7cjjy8gXA+z9ApcFVd004J8o3CoF4JB/2WBrmYcw3afJQJNI9vjCGJMR5B"); - a("cn3buVVpSIJekswd/xvCaRY5XQEnwB/YEdWUT7sIvoyivQOwL8KemSMJWw+Q6cKjaLEw9PCc3Lv0BK1tSrDsYDr5v3+xLwdX+1"); - a("F/WygbASaHr4JfwA25kPM/oLD3yyzA2n0vN3ZLlf5fBbDuiN6njp41wUwNr0xMCU76GX2Q3OHcsDS0vmKxD/mzfVxoZ1Q0OTlb"); - a("Le3Bu1L8CAP0NjxpLUss3A0Gb0pmnY2zlJf1C9N6Tupdmk0LBN6k6TQ0Ongir57HZQXZTkf43Es+8ezjmnIpnPmdlcB5RVDGvQ"); - a("JZbNO8SZiWba5DNGCQ4Mb6mHLNsMoh/dA/xRYqrXTKB8sP9LJ/OTaLY92ek22ljQT2lAsU9+GZU63Rp7V1a5Jl/Fiyz0Qjc9vR"); - a("pdVHKx+csTPnf0mXyBKPzyi6eWyiQi9F9Ibg9wYrSiKZ21dOtGMx6Xg3lFjZiXlZ6+j9pE8Q3+kDRCZ7ikyWHA2xbcOoYwACDg"); - a("iHb8zDhY5LaV3Fr6ceTHHVk73BtCwkKkrW5P6tq2rYETAyKG+JKdmXrKomS1us8f3wV7K3f7w4u+8dlo6jhVPT/cWMA+Wd8Ir6"); - a("wAUGBzoLkMikGm3/4iCAkh8DzCsXBWhOLKhjy1uUkmR+IQ9uQWQQnHqaENSv8Qph1PNEKNHineJqRNfH5ydjoBODJkRi/dujXa"); - a("F7rYgqR1BZyp3M6V3v52HB+JOC8k/tgRO5nsipX375kAZbaQ+GC7WBDSxv0A6i3F1VNhOL8p8VnJ6bhNbbrj9+IBc+ieN9Fot7"); - a("pN+SdlguBJHw25PzYYjYB9c6yAzoa/qQ1cleRBMLicG0r5F6i8irHsP2+/pZHdTOajHk4vvVLOsCFvuYeL0+aEzho9s3vYIhxx"); - a("wMOeZhybAGS4ZNhTDxKsQyIsxks75BDiihTZgUk/RlrnMvoMHd1LghEKEGOXgv5m/JSL5/3F5y0cB41+TX2G38EcBPhvtRRDdR"); - a("0k8W38n3iu995I52sMCJr/9W/AFWCB4tYDvBFxJMRX8JVHnu1Ozcijbwjx1oH58QSBb0ASdoBS/oUDoCCGPFEoirw+165JPAvq"); - a("E43O8pgSQJI0uo82LvqUcUHxpjc00bS3MhBN2n+EgF6FVAGbq/nRJxDtC8e9aJ0wm5mk4X90+7D47UiPaiv0PJLHIQxsklw/03"); - a("2UWbOtVJOspVTRLjvxCOhtvH7JZndruKnY6JCOtNx/j8ALsRZ0q0ODsUUzhXFfPaEOH2PrstJzdLnNXKn+KcDSdT+RQPVWylCU"); - a("RBttuBngXe2PwYIF4b4ZAcqKxTRbtHPZebCul7+ahBGv31owSfRAk+zf8p1av3vAzauQme20qGJJyYN6zuQeH+aKQ7BpnkOknM"); - a("XQx3OAL3X2NKwsUyCb3p70BKQiYl4aRAns8SeeBYhLVEHDgAbhGRQoaMyIp9LBd3meK7WcaXQH+9AlchPISgnkKez/DHBPsCIy"); - a("PuIzl1AIqSjf0chrVkTq6x7rQuSPsnS4JBcZSqVh6lSsMpLJ/YJoBBH5q0F03aiybtRZP2oknTGrz1OJzVvhPZmsA2nlAGcrhS"); - a("KIYrDX2oZ0R+eqJNjY0t11U0q3FO90dOanix7o8otUQ4ozvCsYPJa3IfsTP0JDZ/p5J2SB1ovy0j/+6f+GTWR3bi1MtHuI1wRd"); - a("SpkCg79Vzp3HORLwH3jgXg3yRMpFq4yAciDPdn9HcQVfGRVMXZ/hQhx5BcvKiWmp5TMdhvg1MIL9YG+1ttBg50DfFlXEFJZKMt"); - a("LLOkh/vBBCbhxkAXH8QAEY2BbtNwl+9wlh4ZbhIQPSmgBRqJjX8COBKKLoHQm4CaiF0gdmttUsYCZ2sdITB/d/LS6jbk5T0yGT"); - a("h/kVVe1o/mwyCoci+qnAUEVR7tPii9od3SmVj8q7oM/2jyZdz3JGXLULtoN6x2ewu1eyNQgib2DlxNykaBWGf7n2HdHkUXyeJ3"); - a("morfXJZmzdAYON8Ej0Kd7q48a3KM8rx6B8oz7jNreT56Nbe/NvPtT1yce1AeaGsmae/N0j5GjtNSA8XFvrA4yrLYA1m0FIYhhY"); - a("HzDBH8K7rokVOMsrigE2XR2WQtC+0qlEW0gmB5IVvGlAjzXqt9Jq7L1Gu72OybDnjvQ5MRnLnqSaOfJzZ1YY29VGU7O0xUzEaa"); - a("Uh4fM3b69qj8xQwr+2fMsLwjpHDeK4UzTQjnbSHh7Ou/kRvwCAgo+stkhNV3BjAXmEE5Q3iznIJKVg31mUBk1XCfOSI8Vs71js"); - a("hAFkMt/TwDttTNiO7qJv1ko24+oh3/yxutdfPLFVHq5q+Wzyb9g70wArQN6ema3IeWbXuWJA90uu5ZR9o4UbHq7FSW4rukFO8v"); - a("xndCz/ZIh9TpizeixFbssW6NrlXvi9SqtwPdbfseYpTbPW0ot8MbrOVGrwT4AkfxGZQ17Qb5kidBnv4pyCNONt8L8uLuylnK57"); - a("Yo+2uW83i8PwwA8S/ZzXkFn7BnbOLPAusxPa47eYIgbAAqhH0UzEhoYP1jKldrnGvymbRCH1dy6UC7657rFB7cx6Oa+/uz7aEz"); - a("J5ymW1W++kSXawxXLkVNpoHEJ2g4A985maZF0kxcAZpNCmiM9lUV2b5eNtrX0wDRcNAlZ8rw+1cj/NvK321f/dG+WFbk6UQIiI"); - a("Qk/+oF4H8m+O+K6AkiorGGtT3yeQ0pV82Qq4rBhqAM3Eb7hfVWubr0MsiV/wch/39V50SoHO+7SA33B/+JzrHm8cUTjTzmb0Ue"); - a("A3XWPN5x6U55P+IBYq2/SRjydXOm03oeaWkzy3+LPvezPZH/uc0mwc9rCx1YMs6qQo1t7hWS9yKTvI8xy/sgu7jbh1OQQmc3cY"); - a("JVLinlogz8KfzeDdNwcg/4nGlWSZo5caD5LYpOfFfqxIP8r1KSpEpEaGkP9+MHqNd3lOj9vG7Rizrd8GDSiwMkLza7pELWfWBZ"); - a("WDmFYKEzW4Pn6v7TEMefSEeDFFJPcIjuME6LVZc2o1CbpDw0QR5KTjDkIXsz8vFNjVUerruYZP4rW/flclu4rxhjKhc+7j9zDo"); - a("rkWRHu75VJssw35Rd5CpxLCHgzkr+7vE0/3sjbJb+TfcjH1rxVXhSS9WPNsg6BlEK+a33//RKp7497azf7RR7kbB765xo056bd"); - a("6fjzPxM6PtgzJPNZCst8LyzQJEHeCyDvh/r7KBH6/TkM+qV+19MWouh3gKNJtysxYd2uzyXl/y38/964qWqhHDf9LzqsZZCp/2"); - a("+l/r/6T/3/BaF6HcUVirL3ouy9KHuu1Sj12XOxrM/Rb/xb9blJPzEpVItHi1pMQS26UIunoxYH+PfldsrXx9Zw3AsbWCvpUit9"); - a("BqN2/1bBrINT+Qd7VxnjRBCFt6UNxdLC4RYCxa24BooXL+6kBAnuxaVoIAfkgAQLrgf8oLgEOQiB4sWdKxa6HFLcKW92vrLtQP"); - a("HAHybZ++abeTO7M/Pe7t7s64ztRMSt7Y2W+ZNI0jdtU3yPe35Ytc2/8X+JOIbvS6pjmPCIxrDzbnEMn7QMjWGraGMojl+Vgxi/"); - a("Vev/pD3mP87tsV+qKPZYkEaylmiPaV+q9sieh6I93nxH+bBH57HfssfJx/6lPdpLqGP5/AGN5dxd4ljmbfFL9tj3AMbz/No/Z4"); - a("9rU0Sxx+I0ivW/tMfhngh7rPhKtMfuRyLs8TKN60/b48Ej/9YeexdXx9CSRGN4doc4hp2a/Yg94v3Owb9XzKPhWNrNONaZwMeE"); - a("NoktM5VURJ1LSo4p/KxczV9rQlP4y6k2WdZg0J4n57ORqe8Eg5/3UM1NRzHspdpI1mNenk1A0ea4Fvk5FQan81rkOwI/F8Ztxk"); - a("IS7Xd2SN7H3/+Qnljgegc/CdeiPx31F5MkRYjy5blc7sfnt1griqEVtW+jFdnpym3sK0t/9nVFyxejkSvxutXBdZpgjtSugHKf"); - a("wWCHklKwfvqKvNKkBxLk1aTL0jfkd38pv1aQz49MapwvsY/vegcf6yQf66RN9yXek86IapjOJfa5dL3DJSZ5iUlOgWRSo26YV/"); - a("/2+5y/iKqj0/yko8W3iTq6x046SnXSjZF0L5bpXj9nAvRTvF8oH9LClJPKXfhi/jpRg/lrRR9Ph/Sxi56P5KibYfqYj46SdFSh"); - a("o6n8UAMbV/St7aFnxrSSfIkSP6eltcgege8Im+cmpSxC28pp5RWR8+GsfU+NbfQ2WZJIpmgCkxmr+dl7hzL/r+PN2OpDM7LRpd"); - a("dhCtkPCjmXUM7NrDJCX6hBJzGyso7rIyVdCCU9+Zp+0XU/YZnnuGIg6SlL2v8t+ZVfys8U5LMqmegXi5/3i5fd+3qiZCgzhmU2"); - a("oE5jmQ1/6HuOvZCqd+nZAhfbN4t6V6sRn6dTPuSE6dyPfK85nIw/osiBNOIFYBFeADLzO+OM0AtAaXmCBH2oY2gw3WyhRSOME7"); - a("ezlwtaRYL2R6pLHhd0G6phIJnQM+VfzG+WL6j227U7bP3FTWK/pWkY9bvGT86/Z1SsdTSesGZ5kBRhM7bY5GQlvN3VDfxd6def"); - a("s/SMDeuTt4j/iC7pCqh94rlNfdJro9gnb+pHm/MV13/nm4Y5C7Pnt1mt1z+J6i3lFic5l6He16hP3H8M6hibZkd+Kj+b+2bx99"); - a("VghpWUJuwWFrX8FFa+GZXnhZWfYA2OUt42vYnBNqGi5ExGCyWxffpitchF/oQKoby0lEeg38l818Qlg5NScH9ritIuaOmpR2Yx"); - a("sc5e5mdbt1Jqk/Nu2PeGbUG+97+uxJmkGLribiTLHSB15NijIR3xYro33B/srOIo5d9Jf7AWZ7u4BrH52JotKRrGdjG/ZpvC1i"); - a("XHk6QK1M8ZaalmpcJYxc2upplbEvtN4eHWim+VURWKraxlvkUPFI8oPTmujN479bXgAfZd/zfrbWX4L+dl/m+y4uB2ncXnLWbx"); - a("DJ3uKNkjrmnIn5Gyo+8nQ9sHxhQlMjgL9U1Kivm7dmdurfq3RbiUul4bvjcKzitR19dY/J31ydV1GaizuJ/sTrPy++IN3J0sM/"); - a("32ja/Hc4SatPgdZbVZQv52qbFOj78wnYLv79U2GMRv8oZi/ylh8fLv7m9DLhIB+PbSBl5KrQsX0TKgJV4yh7DmJYKhz95WZU5R"); - a("Xfo6Iy3mwdaV0zymtULHxNBK48oPZ5W8rG7mD8hUxdb5UIMKvlF6knHuoz8NjI1f8fXQF9I/FFMDX9uapoGw0VoQQZIE/j/8kS"); - a("D2pcOtNWkIA0DJxzHXRnAEXyYJHCEkb9EpaIK8QTif421kucB7cCG4PkSm51rL63MP42gazjEunuNSoO+Dhpf7yDFuHPKBWha/"); - a("y+OtiyT74twhbr3AZL4f+qO9OnbNiLuS0fWVVuNLy6lxSyU1nlBFjdurUxzX50DcwOoPi7sQ17F2hcWXhsVNtVT5XGFxixKHfB"); - a("Me94uNgezvBK30b4M4ZiVjhIQsorwQjh33HLl4ynPi5NVLVy4fvXb9RqLv5u1zd+7K95MesH5fBL38weBYCvlfDCaBP1+Q/fLs"); - a("ysbqK5Ltaxdf+EOen61PJya4vidhAgplhIw/dX/WSL8Xkv2kvKVEyVKly5QtV75Cteo1ataqnZI0OC3VkkHSKUcMOyjNTKjUX7"); - a("dvt4jzNerUN6K+YYM85uMdx8/5yPnqIPSw6fVcvVMVuHUa6TuQ3jCnc2Vbb4GDacCPAs/OGtRjvtm8ri74NWDyDjlmzXg0a/Yk"); - a("8EdABNd+cDVYh1TslerGe6SnQ+rmDMmPjDw5N6E8uBnYtHej1dbKqdcMBi8LrF8xx/29xjtxbnAbsP2SeSsGLjj0MiMMfwvSJ4"); - a("5/MO9evVsPe0OdumNgK1U9dCbxnGdirw+cN8B1jR9b0lpg4L6pGd5xPu9jpE5ogpJGQ3+IqC2kKFgQcqCRISUdXejws/tyfrr/"); - a("TdZI1upGyTWHZqNuvtBLRxdU+lzj8CX2mJpnq4b4AG0Uu3Rzu7Zv4hjYDL4F9r6NYy7waMG+EuVXfF1uSkwfazh3H4U80HqMow"); - a("PoAiaE8AZHL9AHDAClRI4mYC6gBWgF2oEOYLT3h6XveL4b6AUGgKb3qB9oB/YHxgHdQC8wFBzt1GdaQI2TIqrx8NDcXtsSzn3Z"); - a("8MzPzjEX0Ap0AF3A7wWNvkgxbdGKRfq34vJxQDfQB5Ra43xAK7A7cAowHugB+oGGNhwLAG3A7sApwHigB+gHGtpytADtwP7AOK"); - a("Ab6AUGgJnbcSwPdACnAOOBHqAfaGiP6wbagN2BU4DxQA8wAMzcAecFlhSfr0j/W8H1k+fLC4xDua0oPA/8OfhS8INazuPBveA7"); - a("wG+CJ4AnxwPPA94U3AveHPwSeCtwH3hrcD94G/AAeFvw1+DtwQ0dOe8AbgLv+Im9u4xxIorCMDy4u0tgcAlSHIK7BtcQ3N2h+O"); - a("DuVrxYcCjuUNyCuxd3ggYnwLlvA5xgP/jJTdiP59zpdK5Md7c0AcfH9bCN6+O0uAF24YY4N26CC+GmuBRuiSviVrg+no/b40XY"); - a("wevwWLwee3HI0KwHjod9uDP24y74OO6KA7gbford2Kpn3B1Hxz2wjXtiF+6FC+HeuCL24fp4FW6Pb2AH38Rj8S3sxbexD9/Bfn"); - a("wXH8f3cADfx0/xA2zVN64UhvHjI5HYTzh6GuYDx8AuHBMXwrFwfRwbt8dxsIPj4rE4Hvbi+NiHE+LjOBkO4FT4Kc6IrQbcHzg6"); - a("boBt3BC7cCAT48PXcSlsl2e8yu1xMuzg5HisshenwD6cEvtxKnwcD8MBPBw/xSOw1dB4JI6OZ2Mbp6rA+HFGXAhnwRVxDlwT58"); - a("T1cW7cHOfD7XF+7MZFsINL46F4Dx6L92MPPoC9uEEl5hM3xQdwf3weD8EBPBbfw4vxU7wVv8F7cPhGXA+Ojs9gGyerzHzjFLgQ"); - a("blmN+cYr2zG/2Ifb41XYwavxWLwGe/Fa7MPrsB+vx8fxBhzAG/FTvAlbjY234Oh4K7bxNuzC23EhXLoD48f7JjN+nGEP48cZsY"); - a("Mz4bE4C/bibNiHc2A/fr6P8eMXOIBfYauJ8WscHr/F0fF7HB9fPsR84ABOix9jFz5wlPnBnrPMD15ylfnBS3F7vAw7eDkei1dg"); - a("L16JfdiH/XgVPo5X4wBeg5/iex+Zr6bG93F4rN8fSEu9FNmc/O73ob5/+Q4Hx+t+Hk87QNbMzPweDyl5kHohl6m7T5v6Ier+gh"); - a("xP/UjwfNl5HaR+lLovBz8PnjH1Y9TfZDX18ydN/Tj1QDZTf8PxJ6lXLMbxp0z9FHV3Ec5/zNRPU2+fm+MZ11nqT/Pz/Zb6Oepp"); - a("s3CfnzD18xaN4z2c/wLlRYUYL+e5SP18Aa6HebhE3ZWX52W8l6nHz0edcV1R9dzUr6q6m+e9puobmbeAqp+nfl3VPdRvUq9flP"); - a("lnvLeohy/JeZif28HxluJ5Ge9d6mMLczz1e9QPlGZ+GNd96nYJzkP9AfWNZbhO6g+pLyrLPFB/RD13ca6f51VNv9tYyAph+fVd"); - a("FFK93yd15adXt05zV88e04jjQ3xpIb+0UF+aFSLk93/CRIkSIVy0aJG+/gkbNWpEK4Q5LDTNihQr6s/e+PR0ZV7I8+QbMtjid2"); - a("O/kDVJN+khN5LnyTdkfDePJ2uSbtJDbiTPk2+C9e6Sv2x2D173u5Nk3Qntw8t+ob+mytGdB0WR+cZ+lXvSrZHHN+9pnFZl1rc5"); - a("ZWne4EUq1yTtGEleL3oZu1RWWfEhojw/XqQyZtJSkeV1qDePUxmzQnrpd/VhnqgH84z/slyfh/7mKlenuyTjC9/X+Dj1YDZyV5"); - a("Trd9NfSOWElRPMz3V4kcqToRLI9VV0jG2VVedGlmX1Y0dll5YJpN/uZ/zUIcn4c+eZ1wP6a6q8MNuR9bX6Gx+gHswkVc1vfg79"); - a("uVXODCyKLOuDN6rc/dC8g1xzAPtC5dxlO+X6N+KhKhc/SxRWxjeQcVEPZughD6Tfob+iysZh9oaT/Yc3qmz8IryMr/0g9o3KSD"); - a("nfRJD1w4tUxt4SyoxvMOumMmW9PDK/B/BYlXtfXZP94xpibKlcXfKInN+Lm6vcMyVKGHn9GWp8nnowJ+aZEVHWn/76KlcP3GTW"); - a("f5ixn3owq+aaIfPnpr+QyvKfroWR9ccbVbaN4JXrTzvCuBTZnPzbNvQPx3tH/eF8o9nXo0hyQOLWZv3pz63y6O4Ncv3n8SKVod"); - a("3Xosr6jTEOr3L+oGwhZP5xfZWZlg6LaG5Qrot6MLO2eSL7uzn9uVW2iOZI/wHsUZmyYy05f6FxzI/KeRMWy/V7cHuVsc+3N+uL"); - a("D6jMMO50BNn/441tlYsmJYgm9zceqrLghwzy+PgTjO9RD+aCzSNkfdz0l/qWnD+U7M8A9qks5h8YRcY/0Ti+ypeJysn8eXB7lS"); - a("tiNJH78w0+oHJtnTNhZH0mGbtUTox+Web3OPaqzJEqpHx/yT2ZfaOyW+nX0u/BzVXuybhQ1jf8FK6LejCL3HfJ/Lanv5DKlL7j"); - a("oeX6sFflnv6f5PEuj7Gl8tXh8+b+w81VZv3YXM7/Bh9X2fhMdpn/+lON06q8US2yjO889qhccWVkNFnfacybyqPNm5nfg7Bb5c"); - a("sH5h+A7ensO+rBbHv6k6zfIvorqsw0arqsf6kZxgHqwUzSoqFc/z36HZWj4/WW668509hWOfrBLZmfjXioyg+pd8hypJ1l/JR6"); - a("ME+drS/736G/psrSVT7J4wPYp/J1/IGhZH5nG0dXWTfrKfP9CbdXmfxNHRn/G3xc5cI0q8z6e1l3lVXfJTI//2CPyqwFQ8n9EX"); - a("8O4/aSZMzYu+X63fSXUlnl9dqosj7Yp3LtkZ2RZH3msi4qzy0KLY8/gIeqHD0mt7l/5hm/oR7MXdU+yPp46W+uMnTaxtIff77x"); - a("eerBTNC2nMyvQ38plX2LPpL9qZuf/l+1+mf5PZnj/tTiL/j9cSUqFrWzZcqaKatdO6sra9bMrjyZs2avYzdt19F2585ZL2d2O6"); - a("Ndo0XbnNmt/+1ftDBk/OHsV9I9yqRDelhfL3mAPE6WYl0rkr7QIX/4PFAUnqei1cDqZDX68rW1ZVtVvnxtZ3W1mlgd6Y8ToUi7"); - a("Bh0bF+neuUkISs4ts8ViiEwLW6Vd665Nvv5np4EfP2f4Rn3+yHNd+n/dbtP/h+bvxecTepus2Mek45iM7v192v1MWv1N+oaY9J"); - a("PHyWALV7VCw5ZNGnU+wPiCzc9tsohxpe7pomX89qUof6Nlz9nb8nN8fM5zj3nyUvd/5u5KY5opwnDL54GIUm+84nrjgRZBKZ6F"); - a("shUUZIWixCN2LatUy3btFuXTGBs1indj1KAxpj+MIWpijZr4wx/9oQne9YrXD+sV8cYzeNYp+wxtt9t30SiubjI8zPHu7PPOO7"); - a("Oz7850P6D1MFVHT8smucycC/N+Wk8u5AvAv6qnHUKDalJJXCBHlElDY/Dj/YzrAEpALvskeL+F6/dwvSB9jZ8p3hOaiurC+VFV"); - a("TmwWpmRdUOOCnkxE1QuFSFxlJqlH46qgz2haPJFkSdNaNKZMClEV7+kuHFWQKCSnFEHWtFg0IidLQpdFk1OCLMyo0STLk5NMSE"); - a("/KsZhuJEbikwpqmpZV+UIlwQqsnkRLxC9MyNPCjK7oQiQmMzzChWP70Rk1GZ1WBCWRYGOoa0uBnfgA5gcT2N8S715dVxKr9V8g"); - a("ly4Vcg1Cm2GHhwuxqKoILp5+iHHqi5WEqsQ6j+LpY0oyNJVQ5Ml+RY8kolrpjKvltzMeW8RS9QzdW6BrY6mWhs7tbhybYhpjje"); - a("lKVfrQ55C/05Ys65iurZCcgvletYD8Hbfui8djiqy6q72Ai8jfpqlX1aNjq/pbbWekt1h2NIwxm/WkMl09TmzfODiuXqzGL1N5"); - a("Mbe5a67JbWKjnxdyLbWGyk2rDUWqauT9zf8oQ9SS/bLBdcblRlHhwd+LbSzEWEixcAcLCyw8hSAgFFjoeogh4v3s/y9YaH749+"); - a("KvDH99kAXEWxkm2Q9ESM/9XpxnyMO1z7JvNzxnpDc/awT2fzlA5hyW3sXCwyy8zsJTiwa2sbyP2P9cW5nDN7meeMzgwePPPG7E"); - a("m19hcix8z0Lo1d+LGgtPsTD3Wjm4XmdcWOh6wwj+11lA/C0ml2FhrzdYQD7PK7xm5K+uoy2yOhDy7qKBDWw83KIcft2yWGxsLB"); - a("af3sUI6R2KxZu3Kf1vlE97isV7W0oBZRBWtioWzeNsqh3z1SV6nJ3dZ5Mj7kfZs6qvs1lkfUeRp3k/nvjE+n7iAz/PpzTPrEN5"); - a("bicGA4xnUgFR/xLNc8WG55JDeW4rBkc0RQVLZpef0jwLn9E8BcGxPNldLbHG0/OZNc9lpC9+TvOccCjPJnGU3XxBkx0rNjyzX9"); - a("A85xzKc1vxzESU9052FD6nec5/SfPMOZTn9mIgJuv6afFkMD6jTroW0V717iupr2ieKw7l2czstsyyNMeheU59TfP07utMnk3i"); - a("UFRPlvvn/Fc0T2mZ5hl2KE+PaMyxq9my+r6m+fq/ofnOO5Rvixhgj3NxVVENutoyfy4/5pjOwDHezkB7Z5D96QoEjm73HcX+6w"); - a("34vN09wZ7uHvHoK10T39B6mfiW1kveoXrZRhw5X1cS7IEY95NvrP003P+Q+Y7m6drPGTzzwLTbvYqF31G+aKAfKAD5eTNFIMrn"); - a("gB6X28AGnG+T2+QHMubdGuygDelvmfX3vc246DD95a4xeAqQMyM/tgqtzt9c2e/A3w3+vxv8F8A79wPNfwH8wzZ6kO50byj/5b"); - a("vQ3vOIo/783bCLe4AoV7jPbB+leZ+SyEIPc0ifLVbrJ/+jzfx9f7wvsNFP+M2N0Y/rXaMe6W3YyTsG5lB/geM7Zn2szg8TedhD"); - a("GOkZ6GPuN8wLV2zGVehDAvJj0SQnxa314dXdlvz9mvsv6SM1AfuIgu/FBnrPhh4uqj5vDvE8T0d5gcsB18ojLsXqXPc08oE8PY"); - a("y4XzWdD/w1pKeBwiXABK4DmEJ5fjSF1u6rq3H/b6gfGAZqwAaTX3cB7TRRx6/btsMmy3ITSOdH4Ufab77yk8087YD1jbv+VvcG"); - a("v18ISqU5WhuuX+B8zfx+pvml6/Br/aVaTth7Y/jx8vk9YU8C6gXyY8tQiT2r/zfkAzPAGk7gw+0gZZqvNkJPfsRzJj0Kv9o8h6"); - a("7TTqT9NtZOtg0Zbn1DW6y+X+j+4P3NZh6/vzXPCZNcdmJjeGJcLc/TEOfjahpY1oekJHSmDAxMWdhLDpivYz9+8PPUsR8f7MOH"); - a("+KLpfpX/ndar/0CsFzDZUcEkl9vp39Vrbmfod0f0tx0MzALzQC7H/hrn2wm4K3AXA6Vdze0TiMdiSoS/f+JHGnqUEM+a9Cu46f"); - a("7nOQjrFaFnfnjdpvgRf69+80e7Sf26DoYeEQ93Vdtt4aDqebanrTruRVwDeg+1vv9n25EOfkIP6j0S8xJgoQPXdZSB/k6UAxba"); - a("ref96W7w9OH6cX7pWJznOMgdXy1fQDx7AniciHo4+nF9fTh/AOfrhxwwHYT+BtzV43rI8Gfo5vfe6FdpxDXuL4c9ZDfR9uQ/yD"); - a("o/Z5Y73aH2dBrygRowBeT2lEXcO4J8ILenvAS7CuF8p/81e1qGnHcU6UBuT/lx2p68Z7j/UXuSBpE/DHlgZgjnAWZCON+ZiJ9h"); - a("Ht/K/rUqe4Ldebh98uc/7lfZkrbH2YOc5R9Yr39F2wL6BnqBEtDjAm5p7V/ZLjQgq5MxxfCysPrR/8zzGw/0N7AVracV6DFrp8"); - a("9G9/9Kj9syP01Zi0x/0Jf5uYLbY3prWj/eg51pjxrajesxzOKUvy+FfLO/z7WNtR53CgVm9GR8eliZjic2l/UZht2Z/X8L0ONS"); - a("I60vbZ361JrcjtSna1t3lT79LE7pM72NuZ9XazQLvXmRnzfp09tE62thnfqUWpypz79qny3M36jHZxIR3te32UT69Qvb0noqOK"); - a("yfr5X/jyM/dgn1nq8nE3IkaSw6M7zF7D7WZD2erKC95rej20VoW1+75a/bWL9P6nrct4AZYIGn34Dx43b0F8RzwAJQuBF2D/QD"); - a("PTchDgwDU8AcMH0z5G9BOWAB6L3VwCwwfZv5PtC3usa0utXY0Uz3t4EWG/99m7P625+3b2f103r9zHgLwfwF21n3szDaacVjs1"); - a("9xne1VeHZj+pn0HOwcqAEzzyMdWADy8y+/jn71Buz8BfRHYBqY5+kvQh6YBeZfQvmXEX8V/TGPcsDwKwYuA6VXqf6F1mLHFNrl"); - a("/cWvTnJ9dMApTz28j/vkyZ5HW3fYhPf6nUFRDPjEjnaxi62y7+o9qqu9L9AbaO8Ieju6uo/p6uzp67jS5d3B9Dxm9pPuaONvOs"); - a("RZ/bR8/x+Kqhcrq/7gwaQyHd6BHo+EnWgeAw7jae7XO1bwPSOqR5NY0TLA2o/yg7fuTPNKrZO359yN6dfhc8zPc+ANP4N/J+v5"); - a("sp/b8S40n9ZD4T8t8XZAO/Nj59C4mlD00m6iyVHlAiWhqBGlxBPtZ/bHt4Lnsg3fiUOdZdf82D00FI/IsXF11Ewa87pdrJ/beT"); - a("sv7Urzml8n74K8Ye+xMN6XKQ+W9tWAceuu1uO0D/Ze2I3m89Z6+V7g/lfGrx1CfTPRWM3w5WrczZr3CtLfaqV5eQ5zFu/UhdXj"); - a("V2sIrb1m35w+L2CyczP/3Wl+C+AvldAB/F1KNf/dGP/puAX93en71uIeNJ+lw5w5rjWHBtVo0vDlltp4xYZndk+ah3C4M3luF5"); - a("LiesXSmMJaexl/izg2obw4EixBTf5WSB3bPH1+PEbkY8ecOX9r5Jc2tbGtiDX5WyI/GIvLSYv6m5B/ZnRSQR2W18m5HwE86Iq+"); - a("QHdn9zFib3tHT09pXe1Rve2+Y3xd7cEun/fooPeYno5A75U152ng+mui62HZZP52wHr6wNvCuu1xWjRWbkyL5wyz3BYoN6RckH"); - a("QR7RyKayWo2w4jZ54mjjKsp5f2E12kfFCO6QrDetcXSswo1PWplbyJ85w2E4tR+j/PTn58aIjk0Ts0JlI8RsdFisdpg0O0ni9T"); - a("lQTR345AgZaqDXV8N91cjPfmrVe3fyi6eV9gS/UGNb49bWGfOoJZLle54avtU0IK4yWXq9xA5fnMVk4QIFexIWkFYpJQKzbBy1"); - a("du7Cl8Xl8AxxyXM22UWfyCFs1xuaqNJ9kv7fS/wuUqNnLMf1VfyrsvytdsiEh9TdUV5nK1GwvIS5zncuWF93PfEBJ5Xr5mgfnH"); - a("DZYq2A/lsSA7+x1d3MvL8wXK1AeGVh1h2JDd6K72V/LzmBc6TyDDVPECL4+FwOuu12+a15vPk/+BrFfYH+VNC1fXU7VQkS7x81"); - a("QuNPP9SinbaH+L+vna1UXkNayJNdTU7a072fFtcZo8reRQvg2pHN01vLybQvKFrjy/nvJCU5JD+ACUNxZmNv5swzjNy1cuUJR+"); - a("sdVTjsvVLhSzbyhvOXnF6jxYZAaFW9bP1+lt3zKIqULvpKwx+wrjmt1dR96rfzGa3+G+B1zCIydc/U75FA3sbjIL+ZbywiTi4h"); - a("tYyELChzROZqCq5JM1513+nSLjOQjlKxek+N2o6qD6/Llc9cILvuyibb86krNczrTQYF3t5iknZ63OwxcrLNS/7hUuZ/WCPrwV"); - a("ffVYzwDelZL8NfTUwXUkNS5X++KVlFzgctYvANnrP7qnFLi85YuoZjxctdWfB7RB3vrFCHstQtcf5vJWjnrupJ+vX38GWc1rnX"); - a("Yrk/27M8Y/4Mvrq3Vwk1fqOQRyFo5i+IgtRQe4XKWjFU5WavxKcTlrxyU9FtSM+jzeVh4HyPNzr6j/EAvFw88L+fqORu5ilA61"); - a("OMkEl7dy2MFZR1TvmufytY4v7vKatZJ+i8vVdxzBY9R4mOV4iNSWeo6XPztW4ZBsz7s7dVmuBS5f5SCBd4QwtCUuV+1wKOxBCp"); - a("b9JtknjQIHFNnvx7DwOgsHsPtXkoXXWTjAzf5n4WkWDmgoFq9l4SMW+jcVi/ezsMUWxWKMhXr+G63d5j13DENUCR21L3Y2omjl"); - a("SUeG64u3t3n/7xH09adjzvBT1fIUZ9lIrcoxPK+1W/OcAj//kTbt5Fieg3hAw/36CGueEvi1eWkeyw7l2ST2Ry/t23yWkojjex"); - a("Q0T08HzaNt2pk8txVHZfVCZa1F/V6a54oNz7BDeTaX7HaEeQkuiMUvw3c1qP5ZOIrmMe9Qnk3isJycKndQz1HWPJeRvthJ88g7"); - a("luegeqkci06OaPhuC80z20XzaFSdyXNbsTQEsbGIvTfAd2hInvNH0zz8DuW5jcg7J/9uD80zdQzNQ3MozyZxXJ2sIJo92vRe1v"); - a("z7P900jwWH8tyW9c+RmfJMYf4Ymqfko3kU/irPsxv+4d//GVBkzXBxVP3+T7fN/K+H5tMad2a77rg2z62e2Gs+6/adQrr3WJrP"); - a("RNyZ7dvC7zNSPKoy4uEemmfrcTSPtEN5Noust45cYBgyiw+w9qJ+p8l1PM1j0aH228zbMyDrSXz/jBqXlmx4ujRn8txOPENORG"); - a("U8q+G7asR4lD+B5uFzKE+P2BuJKLp+RjQekyvfbZxgzXcJ6bkTaT6aQ/luI/bN6GhTfDeQbNeFk2geGYfybBKlBJv0xthiG3y/"); - a("kOaZ9tusW3Qoz+3Z63I5cvHa5Dd3Es1ztpfm4bnEmTy3EQNxNZmIxwL8O5X0/SXcR/PwO5TndiWerDH5uJvupXkOBGgesw7lub"); - a("2I11wgOttH8/T20zyyDuXpEdc+GBCs/F5AOEDzFUSaz5JD+TaLxovHwJQSuRjft6V4NgZpHkLCqTyNZRT8VuoTaZ7LNjwnHMqz"); - a("URyLXnj6TDSJuBCkeb51Ms1jzqE8ty/5dy9gk3qMR40n0/P63ADNI+dQno3iyFiln2H5ZLo9FwZpHssO5bmjOCZfoETkmMnP8N"); - a("YAzXf+FJqPV3cmX494WtwYkcaMb+mUv0tN8p07leYz5VC+OzO+5bXw4IzvalN8Z4ds/KEO5bsD49u/WR2Knq+DLP9eOL1vdnGY"); - a("5jOQdAZfen/7+lE6toHM58c2IVGNxCfX9lHMD1mP929Bf20jNvNsh+kxdzx+z/cEA70nGpgDugLAfgO1kwzMcOwzMIX8NDADdP"); - a("kNzAMzvQ3m34/pC4yVdVwYttavD3qdk2zm9/8z/WpBxIFZHu9HXLTT73go2F3Wr3/EWr/z0OvS6TbPE/8z/aZOhh6BOWCex4Pr"); - a("0K+vrN+MZD3O8vHBN0brT5hxln6FAegVqAHTwNQpyD/VwALSPYNIR34Y+RowzeODpvlJaNz4JN+aSnGMWutVgj7TIZvnJofqtc"); - a("D1wPU8BL0OGyidBn0hPQcUhq316hmx1uvubLnvhaI6GZVVSwVPQI+jN3uuuG3vd4fufe/MwiW7n3DSkyH++xzdfR1eX+Doo9o7"); - a("+n1Btj+wv6+9J9AfbD+6W/R2d3T0dPZ3Bq905VF+ib9fRDsJH+K7kOM2613qtJPvjOr0vNSwId/DzEGf/DggNDwTS0ZX92DNRm"); - a("IzevRSZXXx9NhmNTKViKvRy5VE6bpm0X7AMFADpoBpYAbI61rk9gzeBaSvmO18nJ7H+s+0Gc8d0i9qnrNDw6PimeVnMg16qLd/"); - a("8QAXvc9y8sjpIzdb5Ht4/uR+wn7T7GCwmR1Irruvs3eYzpeG6euZmjpWVS3yGyvzj9V1ROvumzxFVsn8oHI+mT8sJ8j8Xi1hI7"); - a("+Zvr4/aDuXXadhIAx3AQuWvAEbJFgYOU6cy5LboiAuUkEsK8dxG9M2qZyECh4ekcSTuplSV0LCm9Hn+W3PeOI0PTo5p6vu+Pf+"); - a("9but179SR6//k2y9/o/1D6//jZI330uG/e+E+XldR7f/ZhR4rk+ogyxv+KEOev8PdXjg6qD8/v3PW++zQx26pr32P3J1aNUhV8"); - a("bzHjfUo7YqtF+uHvNpsM7VZdL5r48719+H2u//0imv/5sq/OPLzn8+jfbHL1r/3xnoqsKWHvun/MCP6+Hya6wA1dXlV40KTz0g"); - a("TwOym/FCvqBC87h8OwMK3/X6Qm62C+/nwbzp/EDDZLTRYJevPnBKFwvRHGqS0HTSvfm0Igmjgy4BfZLw0aacgmXj+JT3/fKY8n"); - a("gB/VZPacphPquLYVwc2PnTmNn+EPwRWDtfPM0XZ7Y/6cefdFXUp4akSdR7R10flmtNqTft+rtugLc5CwPm/LtmLdc8pgEJsrSP"); - a("M9dbDvsSUBaPcQc0SkBuOYjoRR4DB4gZ4hBxhObjiGPECRqfIs4m7toNCcbRwPahdrPZqJGn/QoYp4gDxAxxiDhCzBHHiBPEYw"); - a("7v6lLkw3lcvh/jOwipq7ZuyunnQqTvId/FUVSqURPLUg/YGlFMic70u9ooUTkWRuRaOi5VbtTJ8dYotbsYL38avd9ridZr9OH4"); - a("1/VMfRCVFtXE3c4IPXQAt6XQl3qp5uO1VHtRFVpO+s7sdFM6valF209n6xuyyb56u7iK57WNdf3642pkiJ3IqrF8ZJTSYNKvQU"); - a("/etqq61CvLoA9BP3GEmJ95+ZLP4tGCk60y/Qad/WR1UsWYH/DH2pzUdkiwa4hopNaL2fwsDhBn7nywJASbgE2tTSlYex9hKbc2"); - a("o2CtPmIUrL3vRCy6jP/tq9dvlq/J+/GSGn75sipUMehtVaHtap0SY+9PSWAtrJ9Ruy6lmZv57dfX5N3nKZ8shCM78flAy2NAGQ"); - a("eY/H1Xcrlu5/y6qUma8owEiBniEHGEmCOOESeIU8QZjociDhCHiCPEHHE81acz9VFc5Z8SPTGjjJHv9uTKZrn6NHT0m4/8c96Z"); - a("837znm26jl19spDOrneVy0K7W5aoiq6RohKFmPQhWA42ATvMqTrZh2KtrEZrQ4FW/iLbnLjPsG0epBQigPM2HB9SqDnniFuBGP"); - a("lFM+fazHmHxh8Qb7s5H4X7fErApp7nFAn2ln9zx/9kcd1+w+MdNO/4p2Af0qHd1lGwD0Dmjcfjf3bH//yOn8z/18NV/v/re/vj"); - a("8/cOUexruXtSqFbJVhU31vvDyPkzpw0DUJzL0GZISzL0jrsOVZdeh15CL+2VS/8BDSRN27tcQ5qMuKAUl8T22SYHW8aMGTNmZG"); - a("RkZGTsyMjIyEcoJnpYkm0JT5H1fpJO5ECW39NzfP9Z9fn2EAleMdM6+U3PbJeSIv1jWvOKBP6A3S0anlkrXVLLPzFMv2y75Gxu"); - a("DyKmRZbZitqc9+TONPH9PAvHGTQUN8zgfuJ87RC23i5YpGU1DKse4BT7NsSu1VquO7tl+CRYk68wYKMUSuZGINbOU2J6xLJ9Yp"); - a("+RWpCAJgvhZlD/QuagN8jcbn0PBVL1c8jFVn2r04nWr6F+dpH6K4K9oJVGQ/mctmNZyv6wm9OkrkXPtxfr5j3q75pes+xSeuQY"); - a("NVpqF+59Q+nKD9vyG8EZMQXXNTpVGIqUxy2k8n/Z+QyPKyeUNhc4FtIP1XjqivGP0pWy7V4Y/hH1ff44lDbEfAiHP2dI6mBdKm"); - a("dQ1hyZgHJWKucwDjbQvFS+Y+U+K2NHFeWcOP4Bu/1EGDhA/L161PGOffPcS/WaTP+gUuz41ENrV0y5gYYFKpUaMy6NoPqSp+PI"); - a("9ZnzSDuIuuPsAKHjKvRhcByRcZxfJehvoA8D2Ihe9+P0A+i5IDMyzJMYANcUHB8Mzme1IPLNaSFo+/K1DqyC44KryKz2FeO8Bc"); - a("cFQZEBHV4kc//A8cHK8bYWXLUYFwYVh28UVB56LvDXe6sfnwOOD9AhPHedPCFdcJFA2tU7FTwGFxPscnL6zyFjMz4pKLVux8Kn"); - a("4ITg0f6OAkJ+ChwX5Mm+103QEJwYjMl80IEO46JBk4+q2cmBCwMbiGo0nBjAgZ4LPow+6ef/DpwUJBh8VrMjcKExv5tXIMgVpE"); - a("WD+01BM395cJJhvF1Ug21wEQN29YuK7IETjMyHu7qPeQJOMAbnSjqOuIxbGG1JWcWcQi8ZVlf31D1dg1sYQKdKYgB9jJFytJ9M"); - a("4pqCjxgTh19VdNZjXKzBr3+g67kBPmqY635TwF1wkjEsUCnP6/bkdcZ64KRhK8XoiiHjR/q5/a74nd+HXjRUwU7l+AkT0QYnGo"); - a("VgE+omcT2By4GD/WWcxE3ARY0eP1VDJS3GJRsZYGE4bMU0cAp+uRf4x8zlG51qyaeQll5UO7/U/3kTxq2llluRk0vosZBekfVj"); - a("Xn94qX5PXtc8X7c09a6m/j9zV87rRAyEEYIOEOK+ZQFB3AIEEqLilpC4xCGgoDBZByw23ijeBUJFzdFT8l+oaBAlJT+BkhKPPZ"); - a("MlXnvechQI3ntJ1t/32eNrdux1yiXuv08e59frTkMC/jrLf5rjB/0TafwKwmMC7jqbvxPH/0v95XN91j7Av9R13v54mYkj9Ypn"); - a("rZrfCK5k+8fZGfWPVzSusuknmD633nnrztULN67fvnM7k8/dFEcyQ2XraopBipF7tXtgd/tQxAiOPj6axm+nflSXw8rY2h61Eq"); - a("kc1CNZ3AVpQMJp6sdGSDGwoq7836NJ3KauXsAqmNu76TeQDhQrKlKKf0uX31skKkwHt4906AS8oFVUynpBPZ6Uakyfd/F7ErpE"); - a("BSSmnjMk9U9RPK+ZlHooayWMHKsz4pyY0/hPipAvWYJnMhPqhXZa/exQEDXw5OwwWDjfXpSOvjWCLJ2HLeY8Kd1tjK5lzv8/SO"); - a("uqZakey1Jc16Ww/gBU35bxUGjhOafNEA9a7FUPajypZ4FLB/apJ/ujfMDU/M/y8dyTJfEP5/tPxLNw3yZscAd9PibTagI3B8oe"); - a("FTdLJa0SjfupnyhKbkVjdA1h2VnVeICPTkpTiKmCNqVLldDdlcj3dGoqZMU8dHGbEedbJ4VAjajwjPJO+q0ZnZoQcJHJ310jH5"); - a("UKxpqhPyVfjLR7C+pnxMAijtcbBaQfeNSLjN6Ojp4zvInV0vaI9QCJatnx5wrEEEZyqKLx54l8psCgV65cdF0zmc9YTxOVqbQu"); - a("LKC6uI2Iw6BC29Yh1tqvXDpA9Vg+Vtn5CUoThcajkS1t/01ZPcTw5aGOMhMTF2Vj23vMT0gA5sc50nG/G+W7JuGY9Q1WzzNl8w"); - a("nn3DrDNc5o+wfFAVE1fmniEcxt9mivdg9jumfAKTeZz0O0Py7wj32YSjx/Au1evZhIA3c49LGlU7p7tcsAChifBW4e97f8wiX1"); - a("egML/7DP9dUjw84Xgbj1tHDothcUnH02dHUAAxC2n92k9qitFzlSmXLG+FcRP6RuGxjTP+kQ8chl4vsX6bTeUpbf+Xe3lXq66B"); - a("upLv/OLr91OAdbRMW4vdT+XFF92LF1QFQh3FtbTR3SOyjL+vkhAQEArKUUTqTHw2qeDSz4b7S/QIG9HArP6d7Clj6aVmOnhUMm"); - a("zv1oKra8sa6psPPw8yn4NaBbVxnV/nrg1WT1ti70axsW88jKVr/MrT9vyek5CoSx88dd89TlzMxH5zORH8+UqwlQQvL5i3WEm0"); - a("CUGGTrbdeSekCQ6h+kN6+kVhOdNdJO6R5I6LZUxIREwJPJ/7rFcdN7tILpXxu7uh6DkFy/oPvMxoKnZ/wI0JhoDGD2PUR+JlAY"); - a("pYpfxgS2fkgfy1dXra2hGR3l/f9Wd+hZPEldEQXXn0kX+nBXM2UvRhdI4lb8/RM+9/N5Ofvczo/XSzwn+PY/fW7nEs64eErlfi"); - a("zH337/Gf/9dcz+9gc3r1y/fKNz/dhifVtVi1vn7om5Dx8mhCs4vLSfpw8r+Xi2b3z2+xuMG0eGAjtFXyp1Zza5YkbVYn2vXn3n"); - a("UpjGz5VaWqJd23cPwX3k2bhugcfvESGS95AGbUWvKTcfKB8Ob5oxzNKq8BRqycx8BWy0UPKN8rO5w7eYqf3v2kz514smOoYffc"); - a("F+9d3/ZZ4zeHDbx/nwbdqPIv9fm0K9SPj/zLxkZ9aPB8H99wQ45DJ+DOkN5UQOdT0LkuBHq0IVR5m4YKRHBCjJzNO0WCrGqn5S"); - a("4f4vxg9tdSQiUSNKv5r4/WK2KJTRqkjnI+b1CATkntcj3mftcYy8/xPzt0D+vvGathY8Jjl93PhwpDZ4s44OzZJ6hBwHJpLLlG"); - a("tgXaXbw6LURglX+7lybezqwPI11gZjN1rkxn2Ev2E3QiKQj8Odb2xwS4T774ouS4g5F6KQtRShClj/ptV91Ni2UNl2hpsLjlwQ"); - a("T3Tdi3cYEEPiTa8HwOY8cRm/PLMXb+EQIwBw7aqNMy70POHAE1kPn/Tof5QUjZOpb9h4ZKG6H82EW9iscvW9PsH/7NEMIGz7u+"); - a("UdJWlrocBLHPlIXS9+l74aQWqWnzYL/bKldPCi1zioEDkHsvt6L0OgpV1ZUUXvfgFFcMAlcGtincz9/qYcfyb96pgXgp6MPTu8"); - a("mfSbU7w+3qbNT8auWCeOGIhenYQ2Shc3SCmSbeiiNChFRBGhcJf0m9072AK82Bzo/p5n+xmL9XmYCgF+M7bXM/M8M3s37x/qeC"); - a("nJB4yoOl429SDSAiLc40R9RDfsouQbgGJ9Rvu8mVgoQNGeznH3uIGFT4OxbJlS+nNQzowQnk/JXy8SCPX4Wv5u6H0jfp8u9olR"); - a("jFyoioL6fYOgKGIl99lTb7pSh2mq4yD1ENPcN8of3YREv5+3w7QD4VDYI+VHYOO5L86XSW3xjbqucL4E3OeFHj6NvBBnmHBRnA"); - a("PqiwKa/oV6svXr94mA1n2bdYpQaiEAP/NXn6v4NWEFpcozwqz6mAqbLZAl36iPj9RrZ9FvUF9Ss3WVIvX6KAD/UukjuZDsR9YH"); - a("AQWm1vfm+j4K+uxcj//B8ak1cJEm7cxVLq2GZM21Cxkx+FvzEEbTuF2n8+uQHFGU3pj/ZeZVBzj/aQBP/++w9K12ZuMr3KFMsb"); - a("KPen7AAuap5Pj8fpfv/2f93+CN1B6WkdjNI8h7qKw2J9jP+HV2E+7hGdkJ/qfMj/ebp6SV0OZ5W1/8+vP3YmNAmsDRQol8i40Y"); - a("oUqOC0UfkPf8vFnBz6fmXMjPX5I5+dBjoNhvG5FDaOtliJT88PqASHpr4siv5svl2vy0Y7zBfT95d+oV67Feqn+dHKsPquIhmJ"); - a("DdcbzA8xb+kMxDcd/JQ2V7f2k2h39nKwechMbPzhkpnov4EomJT0uuI1byXUAS0ubtsem9bIsirvqAyIBmvqe8zgZK5dlBzSuh"); - a("ji9kkHzPec+/TkA9cod0+xMRzf358Mo/U7DqXCZvS0DzHGysDW7oUNpAfCN/X8m3NgADjjCxv4WJ3qv93bfNdMuaikHp+6w7G1"); - a("eK+w7LSA6FfuBb6/p03N72+d0dPf8oEInvnN8xJAddPjmpcFqY/ulWKjvh+uiipP3/Rx7Qh9wt06SGKB3/ABGIYKZYhfxcrS/V"); - a("XfD2KruUxpVeX0LI/LHoiz2Gz7RdS6vTQBT+JjYmk8ZHfWHEggUfwW5qra9CQa8PFBUl6koUxW50JdqVuBMEQVDci+JO3Ii/QP"); - a("D+ANGiuHPRjTsXBcGNfqYTJ53EIQouDie5mXO+b85rQi7cu220iU5Gl9m6fH9NvVT/XkdcctVGxv7K62RofM6pkLdfy4bq//rp"); - a("7+IrP1Bbfu9y8sDZo1TYpNbtV3oTpYMd6GInetiF3diDvdiHA1jAQRzCYRwBbN/dzybnzh47cQYAqvz9nusK96HSwhVwF6ilA9"); - a("kVpxuNpWgMKT0X8oY4/fkbkPl4uQ5Yx8F8aV1u/bIalvVqhbX3uO4NpUPJMKKaQI3661TZrxKnf2tvCbwF55K4DoilDpZ2RSe1"); - a("e5bZa5vsvqCFgOgAma/0OlyKsOu9dV8vueRcFx3tW9n4NfjJ7Fl6/Wh2rX1UwK27qItDmFma9wpjVQnGoIHBdCUGkxUYjJdjsL"); - a("gMg2GIwaiOQS9AKLZCnFY4DnVrOVoTidbYR2vRQ4t5ao1ctBh/+Yr82g20p8vQnoRoj+toLwZoDyXaIx/tnkd/62f++g30pyH6"); - a("kzr64wD9RYn+0Ed/5KHfY7zExtm6tBYc1oJIcz3DD4lfJ35AfEl8cqFv+Y7PzfVxA/G0jngSIB5LxIs+4qGHeLQUcc8lzhriqB"); - a("wluRw5Dn5FXtWYjruZO50jXY9RgIg4EXEi4kTEka/ma/MBO/EjZRNFrPSxMql/lZ9z+JmvlH9A/pL8ffL3yJ/cRy7518h/Vco/"); - a("7zs6Adw6BTw9nuPUDNGkfZP2Tdo3ad+kvXw0zwv09YXy8pSxt8BFsEB2+XrqKq5mfadYklg+sTxiEa/npljzPVvs7x1ngeeUz2"); - a("eKfWPloPJi2pj3s77YrPtig4cNQ0pac9vTWBo4OobW2pvfx53zgLwAdKgtcaw08zoXgSuUrxeKMcns0/0nOg4asxrG+0tA6zLw"); - a("kLp63A2c/LXiodfqninnrJ/b8TWO9Xq5h+UL+Y76+174cRV4fI29cNXYT1LGS/XxKqOPK8R+003WPOXzDc2xMN/X+ljLOl3LXl"); - a("qrfIishxJe5+Nsn3lqZhSx8v5scy6ind7DTM7dBu5SXlD0Ws3fjFXm38xTee7KZ+R8jNSaG8aa1RKrRQz9U7OGjZxa54fGrMxb"); - a("LoHkvMnHohjT8pjZtcXmf2jzXSuZr+FP94GvlKeU/83FPIuVtubRzE3pvEqMeWa8E9jvy2fvn3r0j+8TQQ2B2AJaG/Vt1FLel+"); - a("I+hyWdVEfhkt/nWr5fjz0BvlPwVOe2eJ4W9b/mquzd2l7/lnOmYK96v6u63JJzM2f2s8V+npm2dl92v4Yu5W7NTzFm5Tn7yap5"); - a("hv4UhXH8eey9R4SQn+y9905GRNmrv1227E1WZEYoI1FSyi6RTVmFvEIo8YJIVrwQn64r7nPPPa5x69tzzv0959xznvOsc84vCx"); - a("rqxr/an0uf/w91ydtTDnl9/jDR9qZR9+Z18Vj4r5T4Gck1gOy8JHISnAF/kyNOvixyCNQDafgLXxHpCW5fTjtuzz42dVxKv+7h"); - a("/mtK2viT94ZITXD7eooYFuT8+cj58+Iba8X2T8/pZ8JNXCP0R1uvr8/6Za5ZJufZG895DHX6NrN//+38V98T2Qt6A0+/zn2StS"); - a("efDfr2uDZ/Pnhf5MsDkRFQu++y9UTbzqHB+lh9CKnb7xfNI0WJoeG7WI6H/UXkB0SeiRQDVYBLf517lGkm1mQZf21knobHt2+K"); - a("6Frh3FJYj0usrz4/dGfrL7LNJnl0y/e5LI3k0iZPrmXy5JB3k+H15gT/Lb5YP/jzfZDTVEMvTPlv4lbgI3NK0dCmvp+HcQZGPG"); - a("hNPGhNPGhNPGhNPGgdnF81iH83sIXc2AJ2wF6yTHgWmeocBGp98/HsKlfBCJDGl9o5ROLM0aieT+W3s+Ap+DGGgO/td75s4Riy"); - a("cqlsya3yBj6lPpD6VeovgTeXQf+S5OGai/uc1PiaJoWlCevRhPVowno0YT2asB5NgvWoF/PfdQuo1C2kcj6/OmVwhN9KFVZpCV"); - a("znJDFfuykqm4mcWpcsSv+0F56y1CtQf0Ld5zt+niORX6APldCHSsF+vE5sDlOKqeQuTg2auO6hb0SHYvHgE20LllDZA/Wdr1uf"); - a("nbOkykCwgbY/+F39v4DnPdgArB/wr/OflxPPtDYZnUqRE6Y5y9heTuU1KF7erGeQN+Qhb8gd5g3ud2lz98g7M5+ksc2ppPIc5K"); - a("/sX58V/L4bVAT+/NXK3dqD9VVRWyifwU+Bw1W+fzkf5WngNnXTV+q8YVxVlQugIvgxxsidRTiO8DdzPpuPPB774hu/2pg9nz1c"); - a("TeVLdZV2UBNnnDmFK2a65GN9xeNaKutrqyyGCs8j6Dbqe6BuuafX0891VLLqqqwEzvzJjtHa/tHoWPfUUzlVX6UeVHi2Qi9S7w"); - a("21srY+0q7h2AYq1RuyhtDYOtn44Gifl/ub8mAEffhi5U54ejVmHaFWz515q/f+Ktr3qiYqBZoyB2iatT4H74JmjAUqPCegK6iP"); - a("gP72/Ay+bM3RC6hz3MH5L2e/jLUk7WM5A20LtlCZAk3bZhb8r0A98CdrM6WlymdQBHj0LrW952+tsgacb2V1xb3m1dqotAC3ae"); - a("PjOwDPRdAbJOov1NrBprYqg9rRC1R4hkEXUK8IdbW3uVOR9uROHYiNtBGeXNR3UT/cLp0ele6osgocpo3wFKS8Edzu4J/vO3jy"); - a("dkKHoD6+2fBsAhWBkcsf2UezzipFuzAu+knT3vrgB7Qt2RV7gf7OPubAtx+0A+Ede0jt+YTfZ/vvI/znaUm5RuJdQthX+rzG87"); - a("2kcWeKSIb74QwyzyDzDDLPIPMMMs+Ea/ZH/Vt9iOQ33WJ56qn+KkMG4HegYdu/yJk8Z0uRceSiTc5w32XGMVil8RDGAXXFyp38"); - a("dh98BSnWw8rFm2vdHYYeD8feoT6+2fDcA/WA0w/0ifqB7iOQLXgDv/B0ozwaFAGRdg2i33nI7x/BYuDSGzPv1PFiX5ZKoZHYIN"); - a("Tl68s4fFmDUSpDwXnaKfXqlNeBYyApl7D+uNlo5j2GPmgjPBWoT6P+hLrnbt2ztuZdAvXcxdi81O9b3O/DfXtucrFcgdy+75vz"); - a("EivzECuJl7xHFvYcxanftyaxB52s0hEkfT+NH/Ddk5lyStl75BFSKwe3zdeI2fywGdj8TOwBmmZvux/eorPIx6B/8l+dJbR5Bu"); - a("oBMxfnWnyYTbyfo3IURGzD6HWjuSo9wHn4DjzLJgUp9wNjgC9+X+P3h2AKiMoqJ7LK4fSPLeZhc+DNr21+OTeysuoyX+UQeEKb"); - a("SExLabOzF6pkX0QusuB7j1nUC1A/v8DMzXx3LTynQT2QlLM5xx/KKPuP7y9ROQKeLP7e852lrP0yyrwL/BLlpaAi9fAeyH+/k+"); - a("W6twErVHaAc8B79mPjiD9ux3SwwiqVzGrkt1JT3b/9y51Mkj9X8GCNyrC1+F8gPPepT6e8B6o/c7d4ztHHf4cX1adcMb24s06l"); - a("73piGvR3/yE7CN+VjdgH9LsPXx74cP95rD//HL+ZfTyo9419swrBIoii8PnHLuxE7O7u7u7u7tYXxcbAwsDu7m7sBLuwu1FUDG"); - a("yszxjz2i8+uHA4Z3ZnZqd28i74md+b+Ik8kvk7bLWZ9jyLNCqgrMCol1/f5/Xp+Mo26Ot5du4xrB/AltE/GHO/WsNkGRdQC7CU"); - a("cOKqNDagAbgP4f4qXfZ8zsf/bj89LPvpYdhPZy+d8S03fnMzvuV+Z3NX7Zu+qu2EgDpP5l3jjXe9S2+Id2Vq2UT9ytln7qnM1Y"); - a("DAr/i/g78C0ygL+Ed7KzEjBFOEd3mKJp+nYCIe8Hw648HMgA4A3GoyK6DL4BXArbPcHzgnoCVAXDfwvwwtWFzj4HW488Gftxm/"); - a("B2yNE0/mUofz+GbgQFjGhWbv9+e9/sre5Qs/Vtl+3f5+af0QI5RiNALs18d41z6ifFPfWszabinpXOTrw9utZJL3G0RSu+tOtZ"); - a("YFtGpFQNtX4h93Htw70VoFRN3iDqC3LP1QTr3fp+/LswTOEWiLWWiLWWiLWWiLWbzN8VdpS7+GfZUN9CWrA98dh2JGDqbI5O3z"); - a("9Ab15+ybGHdBOeIQV87N9AlbiA83d1RnY0DJcJcF4sqFuxx6C8/NebkxVh/F/4GtxAn/yjyo3DbSsJ25wNZff8dI/DffQf8Hf6"); - a("zjd+cYrPMpv/iU3w/2v386xvqzI6u/jLg7oPngIPilNpcszNd20ub88eUexq69jF2wlS7bnuar78ewG/P3fqVvObQ/oIUH6I/g"); - a("H8+zf38f/fQh5seHiRv+9THYp5czdMOu+d6RgPYfpS+EfXnY8/vPx327XocfDyjFCdo++FG9WmHLn2TeBTaDH9o6G/P54acCug"); - a("nSgV/xX/90QBuBgDGf+uF8dsAZvk2QDvyqLUv2swFVAwI/8zsPPztBO/B1PVg2Kn688GyeWZynT7rAOgkW13E4Pe52cCB0EN7h"); - a("0n0Tx5Ev48h8iXUMyEc4cdW4GFBb3IcuGHX9t/aoRtsfciWgcyAf+O764V2/HfKLOYhfPzx6GFDfR6wtr76Pse5j1gug3Ad3uO"); - a("u0iRd8W7h/Na1Gv/jT+o3xOqCM4OKrX5urDMXvIlAOWOdYRvv9yubK6KP9/d+0ny8bxOkBEHg/nwCMFVH9vobvJ41+5+tvMG4w"); - a("p/T4vxjUfdXPY99OmGTEm+zdGJTrm34+dAinQ5GdyhHev9OzWWfOu3/+j1mO6E6jYxIA9nYvvzb3tdPaKpZT5/TkkzjftZdtRn"); - a("vx65XlP7ApJm/WM3st/+M22DCz01gQD/xof/M6zyNmcVoK/2r5DcT/mazUDfyjuLNkc6oPBH7kbzXPL4Ge4GfvzpPd6QAQ+OG4"); - a("/6n/NPdOvo43aC6nXmBpTvdL3+wV/MbM7TQV/p3xfThhLoF84FfeUzGPU38QAfzOe+7jP39e0gf/rK1swN910BNY43b2fE4jwB"); - a("pgPQ+X36kB6A+s55fePi/Ac/BNG7PW98Z4nqGg0ylwkTjMcwe+HWtf72ZhpyxFnGqCH+3FPuN5kaJOLYH3Z9nof65/Vq6pijtV"); - a("AfeKOfOd83j2HMQtYX179j7JFPxGLelUD/46nV/PE36WvrOlCFeaNgL7uH53vFhO+LugHPid8+juZZxugHjAp9+fDZr1U5Y+u5"); - a("zTevBV/f/CuvcX3L9kJ22nLXVVpy5gCvjRuUqCak6VwFL8BURc6H5gAbDifcn9MtWdOoIfxfuA50lr8P3C79o8XAN3D2DsNZvr"); - a("qlP4TVXTaRjs82rY5L5fNzQw1g2/sA7ZV8+pfH3eAX/0HzuMYjPGxiZMbMbY2Iyx1v+xpwjXu4FTO9hYh9pngA1+zD/ea/39by"); - a("F9E6ch4GJj36Z/3RYkfVPyB+4R/lfDXMJ/hmZ8v/CvzMcG4rdwc75V+LP52Nf/GprtYw3h0rWm34G/3mP35f9lGkKRhpDfpCF8"); - a("W6eZ4FAbH4+3dY7u3V/lPxT5h438DG3vlLoD6YLf/w8SBhuG0NgwfLbH8dV5nGkzQB5+kX9sc9DB3tf3+Qm8K+uglHUQytpR1g"); - a("HK+gBl/cG2Hv0+hl8vg9zdndr3os11+7YP/2ptaX7P1j3fdu3/Dez+8f3/q+GUDJvfZEff5jM0+QxFPmlbpNt/0+Z56RHD7vzr"); - a("fOPHumd8v38exydb38//JzJtfQeNcHo2kvELNuwuzDB9RzldG0MY+Lv1++Crf4TGOm0cx/wP/tUwecczl51Amxj362Fe47/0JP"); - a("oS+FfDHMR/xCn0yXAgJnXaLPj7ev1szzgQLaSiNQuqaPQv0ahr4jDPzO26+cH/0l7/yhm+/X/2z+2X5jltBflA4Ed2qnyT+n/9"); - a("k1eEaFJJUG1WENWDe4F66GFwquhSM3Q6uBYYhq4HnwRj0Rfh+2ADWjGksGAH+l4cKUxc6RA6ApwEnESXiydNBhfRU+FE8aXb6H"); - a("RwLfAQXQ8eCV6gp8L7QdDZQXQIvgHCou/BIRNIUdAR4PggNvoi/Cwh8aKVSMoGUqHzwUUS40aXg3uDYuhh8BpQDn0RHpaEckDD"); - a("iplUaoSOBzcD7dDt4KGgK3opnCyZ1Ac9FV4LBqPvwdGSkwd0PHgamIheCqdPIS1E54ODpaTc0BHgBqmlXeh2cJuM0tG3Gt4IXq"); - a("C3wFczUQ5ziB9elZXsobfAM3JKpdBL4au5pE7oe3CRPKQNXQ5Ok1eaiU4HBy0orUTnKySlLiKdRaeDN4Pb6C3wLfAQfQ+uVZQ0"); - a("oOvBM0HQubwLPgnCoi/C8YpRF2hYpUA8dDn4EUiGVnHKoyRli54Kbwet0IfgmWVJM3opvAesRB+Cw5SnfNAR4ErgHroefBK8QF"); - a("+Ey1QgDfN4F/wYxECronQaJENfhINUkgqhI8CbQCn0FnhZZer0rYZDVpV6oiPADcEwdDt4CpiIngoXrkZa0eXgcNVJJ7odfAzs"); - a("QF+Em9ag7tDt4OQ1aa/odHAJ8BRdDk5bW9J87sOtQDZ0uzcM3Xl0HVMAgPFBUU4x59hqf/ateAiKYFAEwaAogociKAZFUIy9Kh"); - a("gURfHsRfEQVBtMq6gqXq0Rxdhjf4i9lt8f3/m+pmky986997VNOuU5GKYbvPjhxqxDPhttOuXoCPdUR3wMxuuEv8ZE3eCNK65T"); - a("l/kiTNYZP4gpusZbeSZKriOegT5d57ajXKeu8AwMfMjb+cSj3V+d8M0o6Sr/gCG6wfM9wqxJB8f4u3NEOuYz0KJT/hOxDo41Vo"); - a("zQMXegolP+F+06OM5+QofOeC7G6oLXaTd2XeZ2VHXCjxxvvLrGs5HrOj9/gv2lc17sRNeqQ95slPU82Tzw/Qh1jd85zRh1wX+h"); - a("SQen+zho1jlPGO180FV+DKN0znMxWsdnGC/G6OBMaxWZjvlCTNQZv3uO7+nWBS9+rjNTh7w9enTEV6DQGXfjO53zx+jXBa88xr"); - a("h0iZ/CwIe9D/+D9XRwXhCsiSad8e7nG4uO+WS06oQHXmDt6ZAfRruu8ZgUuso5Mp3zB5igSxe6d6hq/wdPsNrF9ogucYI5usbP"); - a("XGJcOucDLnVm6Qr/hH4dXGb9YMAjfi1/jEG64Lsvd190nRcdayw65I0R6TLvghYd8/WIdZV/RZsOrnBOoF2XeAckOuIj0KEr3I"); - a("lUZ7zEOGtPh/wQMl3jAVe6jzrk9XGPLvPumKxjPh1dOuW70a1r/BZm6oL/wBwddPqncXhbl3gzzNMR74fPdYVPw3c65evQr6s8"); - a("FfN1zgte5foedW28CdbTZY5R1jEfhaE64QyRzvgutOgaz0Cs6/wpRugGL3i1PatDXgPtusy7ItExH4UOnfBFSHXGd2GsrvEcZL"); - a("rO32GCDq+xNjJrSVf4OUzWdW691hzqmDe6zn7RZW673lzpCl8x3lzpjBe8wWuHDvkiBDVv5wVvtN91dpN1NMG60hF3Yj2d84o3"); - a("+zld4osQ6YwfRauu8e8YroNbfB/Era5DR7zjbc4HHfOxSHTCl6NDZzwbqa7zgbf73LrCt2CCrvKrqOo6r3mHedBlXrRqXekSj0"); - a("CPrvAldzkrdMZP4Dud82fo1w1e4m7rRIe8BgY85mPyThikYz4Ky+iEL8LKOuO7sJau8QwM0XX+FE26wTve42zRMfegRVfutZcR"); - a("64J3v89c6ZjvR7sueN37zZXOecQkZ46u8C0Yq6vch0w3+LYH7EFd5esednt1lR9/xP7SOS9Vs6d0yKfgc53wNDR0zos8Zk50yP"); - a("dhwOPGyLs8bp3omN9BSRdcesI+0hyciGadcA0tmoPvMFw3eOku49UxX46ROuPfnvTaoYOn/H4Pqc55m6etBx3xAxiva7z8FOPV"); - a("JT72GWeOTvioqT63TvhjTNEFh9Oc1zrkLTFLR7wf6rrCp6FHp3wdCl3lx9Gnc34TDV3wz/hDB93OKwRPuB7eDAN1xOMR6io/jp"); - a("V1zm9iLV3wzxiig2d9HDTpEm+GZh3xfhimK3waWnXK12G4rvLjaNM5v4mRuuAlnzO3OuQ9MFrHfCtSXeVedOqCl3jevtNl7kJV"); - a("5/w7Jusgd16iS0d8B7p1lb/CLN3gI6abW13hVWeYW13iZvyhI94fQZf34dMxUKd8PUJd5RcxWNf5M5R0gxd/wRmlQ14TZV3mnT"); - a("FUx3wkIp3wC2jRdS7PtNc0B3ugQ8f8AlJd528wSTf46BetK53whejRGd+JQtd4Ovp0nT9BQzd4gZeMV4c8AcGTxsXTEeo6f4XB"); - a("usGLvmyMOuRzsZ5O+VY06So/hmad81wM0wX/hFYdzPLnLwzXJd4UbTribLa1oTN+EKN0jV/DaF3nbzBGNzh61XmqIz4Mk3SFz0"); - a("JNp3wjpugqT0Wucx47x6XojCehX9f42NecM7rKb2PQU66fz3vdeatTnoaSznnQG+ZBh9w51/3TGT+BSOfcQIvmoPVNZ6yOeZe3"); - a("nKE65j6M1A3e6W1j1zGfgDE64S5conPufMd164xPetd4dcLT0K1zPvw9Z6yucD/m6KAnCK7GPJ3xo+jTNe5437XqlA/stTZ0hc"); - a("/BgKe9nVeaZ8y6xFejWWf8L1p18KE9izZd8C0fWc+6wcHH7qNOeBzG6IzvwiW6xjPQqeNP/Bn8U+eUDvmzz4xXN7jzc2PUGYdf"); - a("uo865B706YI3+MqYdYUzzNcZz/zaWKZYS3zmN8aiU2771hmoK1xDWbMXCXtWB5wh0hnPw3Bd8JDv/Xpd5rMwUqec/uA+6hrP+N"); - a("H86jrPbfg5XfBGPxuPLnM7qjrhPkzSDV7nF2tYl/lR5LrGX/Ubu27wm7+7Jl3w338auw7+Mg8Y+Ixx8cS/zZeu8XQM1nX+BCXd"); - a("4CXnW8865NVR1mVuwVAd85GIdMIXokVnfCdiXePpGKHr/AkqusED/zFOHXKKRKd8LVJd5dK/9qfmoIrxmoMnUNU5v4VJuuDgP/"); - a("dMB7wSpugSb4FcR3wDZukqh4F/E6dDvsLXbD/XGYcL+nrGVG/nOzFY1/hAz0Qp6wqfg1ad8vsYrgte39esR+sy74NUx3wKxuqE"); - a("r0amM/Z3uMEEHfLamKTL/ANqusGLe/5JXYf8m2eg9GhfaAp2wcBproF/wTI6Wsz3iqGkMz5pcd9PpxOejkjX+U+06sBzSrbGcB"); - a("3xVFR0zr1IdMHHeW5Jh054V88a6dIxP4C3dc69KHTBf6FPB6E583yShubgWqzVbT75FZR1nf/DUB145sgQRLrMG3iGSIsu8/7o"); - a("0BU+A6lOuYqxmoPHkOmc91/G3OoKX4opOuMnkeucz/cMkVk64yfR0DkvtNwCwR865J0x+Fnj5XNR0ikvvLy51SHvgCYd8XFo1g"); - a("nnaNE5Nw02zzria1HRVf4Ao3TBy6xgjLrENyDVVR644gJBpw55HMbrnIetZPw65nMwWaf8ELp0jV9Eruu8+8rGqyu86irunS7x"); - a("A+jXNT5v1QX8Yc7H4dbVXJOOOcd6mm1OY9QBb4UWHfE4xDrjP9Cmg9WtMYzUES+3hnWlS7wbMh3zq5ig6/wDpugGD1zT59Yh74"); - a("NZOuZjUdcJv4seXfCpa9nLusaz0dB1/gZ/6AZfuLYxPO99ePl1rENd4m3QrCP+GMN0wb9itA7WdSZgjK5xuJ61p0NeG5mOeBQm"); - a("6ITX3MA90mU+Dz065eM2tEd0wud7Jsd8nfItCHP3nadisM75/o2sPV3jjxHrgpfa2DzrkDdAuy7zM0h0ztdt4pp1lb/ARN3g9c"); - a("vOHF3mPdClYz4B3TrhHs/hmKkL7sd8HWzmujBgunnjbTBIR7zt5taMjng4huoK34BIV3nbJmtGR3wIOnSFT9rCmtcJT0RVV/kN"); - a("TNJ1Xm5LZ6Mu8c7o1jFvsZXr1BEfgvm6whdjwAxrkm8Y6jp1laeiWee8/NbutS5xO9p1wuMwWme8/jbmUJd5D0zSMS+2revRIW"); - a("+OeTriFZqtQ13iFMu84P5yN0o6514M0QU/tJ0zQtd4JkbqOn+DUbrBu2/venTMJ2C8TnguJuqC+9GtA8+MWBEzdYm3wRwdcWdk"); - a("7+uMH8SAmT4v92KQLvjhnVyzrvFsDNN1/gatusHVnd1jzcFUXKJzHjzM59Al3gaTdcR3okvXeCbe1nX+BfN0sIvzZFfzpiO+GC"); - a("u/6Dp52xavHTriQ9CmK/w0Ruqcm3a3H3XMLyPTdV5zD/tRl/lfVHWwp33R6t7pKk/DTJ3zBXuZK53yI5ina/wdPtcNXn5vP9Yl"); - a("Phz9OuXJCF7y/rzGPuZTl/l8DNYpz4iNRdf5P5R1sO8CwQEYqiv8GYbpBpf3s981B+9jhC74xv2NXVf5PSS64KWGW6s65Ntwia"); - a("7y9AOsGV3n9Q90xuoyX4+Zusr/oK6Dg1wL5umIj8LnOuFx+E5n3DHC2HXKt6D0srHzKgd7vdAl/h5NusHdh9j7Oud1DnUfdZlH"); - a("YpROeBxG64z3bTMWXeHFD7PvdMhHYpZO+CG8rWv8AQpd8LKHO2N1iS9Gv874YczXNV7vCOt/lmvgvbCWjvkrDNENXrxizeuQN8"); - a("JwXebRaNMpT0KnrvHCR5pnHfKe6NIxP4puXfCmR1ljOuKj0aMT3vBo169j7sKgV8wV92KwLvi5keZZ59yLWBf8F0bo4BjPZvKc"); - a("gorOeC7G64LHHGf965QfRU3XuAfdOmj3e0vM1DGfhLpO+Cr06IzfRqELXut486zL3ImGzvghzNc1fhUDZlt73IdBusHTTnDO6I"); - a("L/RkmXT/RvHLCezrkXQ3XB8SivIzrm7U/yY13hLU82Xh3xkejQCY9DqjPe+xTng465OXHPdMRHY4pO+EnkOudVT3WPdIkPR4+u"); - a("8Gf4XDd45dP8vkJHPA0DXvVrec3TvY7rMqdYWaf8HIbonFccbVy6xHuiRcd8LmKd8cJnuKc65I3Qrst8wJn2u67weZioU97Qsw"); - a("Lu0WXeC3N0zIt0uGc65IsxYI6Pz8+cbf51zr1o0gUn55gjnfAEjNJV/gGjdYMXP9e60iG/iYm64EFj7E0d8kuo6zpPOM9c6SpP"); - a("xYDXfF7uxSBd8OoXuB5d5j3QomOejVjX+c3U9emC/0GHDi505iDVJd4OY3XET13stUDX+c9L3EcdXOpcRaE5OAR9usJXoqEzzv"); - a("GHznn2Zc72130c3utya1XHfC6G6JRvR5Ou8pNo1jn3YpgueJ8rnCc65mMwVifchUznPBcTdcF/4x4djDNGTNYlbkaXjniJK+1f"); - a("HfK2mKUjHo66rvCp6NEpX4tCV3kq+nTOl3Yau874L5Te8Hmv8iwVDNEV7sVQXfA6VxuXLvOZiHXKd6NN1/iYa5zvOuFxGKszfu"); - a("9a49UFb3+dseiI17revOsy74F5Ov6fYrsMlSKKAyg+dhfYhYKFCDY2dtfY3S12K7aiomJ3C3aLLWI3drfPbjGx4zcfDucg+9y7"); - a("996dh8KfV+Kp3sZnkfCSs+Ccc3zXdAGuMNf+65DXo6HexqfRVl/il+iqP3DKee6SjlwYQ3Q53o3R+jA/wQz9gTfOd4/1Nj6L4/"); - a("oSf8Y5HZhXX7zQd02v4BNIeNlrOMki76dT8jmk15c49mJ7q1Py3mXWrw9zDAboyMFyz24deSDG69H8FzN0sMLzBKt0Nt6ATXob"); - a("n8U1fYlbrLSfui3/QNwrftZsdyGk1OW4A9LrPnxprTugIw9f5+z0aF6GOXoFz17vrkbNCTa4hzolD8dpPZpf4pr+wG02+my6Lf"); - a("/AWx1sspcIrnovLrjZenQ5bozMui33Rw49mnchnz7Mh7bZt6j5LzrqYLu/Y5dnl2az1H7f6ch7cEAf5soHvLcOuTuCa17Dh5FQ"); - a("R/6KlDowJ93tsP3RfXgJ+ugV/PKI+6M/cOajzkJn4/zHnIUuwC1xTbflccedhZ7B25DwuvPifye8lw5O+n8S5NGX+Mcp33kdnP"); - a("bsQiUduTVq6bY8Aw115DNoqS/xnTP2RMdw9bPujw65M2boPrwgQq/g/VihD/NSs8rr9ArejXv6MF/FUx3DH/FWB+f8ux5fdMhj"); - a("ENywHj6PhPoSxznvOa9Tcl1k1iGPRx49gzeggN7GRy945uhLPP2i77KewUUuOV9djqdhiJ7BGzBeb+MGZpGn6rb8HAf0B65yxf"); - a("3UIa/BNb2NzyJGX+In15yr/sAZrjuXm86UVyG93sZ3kEfHcJUb1qxDbn7Teem2vA8t9WGOQVcdOc4t90en5LMYoi9xrtvOQhfg"); - a("GlilQ/6HTTq44/uOazobX8U9HcPBXd/rW17DOZFUF+AaSK9Dvo9sOoajed9yOnJGVNPZuDtC3YcnY4CewTcxXMdwx/vuie7D17"); - a("BNx3C9B55lui33wnHdhxfhnF7B0YzuNR35JOLe9tk5eYx91il55CNr1qO56GNr0+W4KxrqPjwDLXXkHeioD3MMeujIwRPr15Gz"); - a("YbiOXA7jdeTmmKrbcoKnnm86JVfEXh3yNBzWM7jWM/dHh3zlt2eljuHgjzXficPeK0JHLoc8OoY/ooAO/rrDKK7L8V2U0zH8Ew"); - a("118M/nRksdcneM1n34JCbpSzwyMJejR/MyHNcr+A/OaQO1QTbc0pGvIEbHcIrYZpl0Si6LD7oc/8J3Hc3SZkRw189y6rjmHaLm"); - a("TSitt/F9hDqGf6KpjgZbq8Y3d6FDnoNJegX/NB87Qwep/TmO6xVcOo0163K8Ftf0Nv6MezpIGzuojqc65G94q4N01okvOhuvM8"); - a("/6W2/jm8h2z9r4D/LowNzr3oLmL/Rh3lgotvvu9fwG4/UHzl84djBVF+CxmKNn8Cqs0Nv4EdbpD1y5iLPQIffHAT2aX+G4/sBZ"); - a("i5oh0dm4JG7pcrwBMXobn0fc+86Xc5tVTaoLcHnk0yH3RBHdhz8Ws3c6mlfNgrY6Gw9GVz2al2KSXsHfMEMHJbwe23Q2jsFeHT"); - a("lzSXuus3ElPNVt+SXe6g+8pZR7orfxZcR94Gd5UWlr1it4P4row1ywjHXqctwcHXVbjmXWs4dOyXmxRBfg5VilV/B+nNOHuV1Z"); - a("d0OP5kWI+9Br+DuSapc4OIoC+hLPKu9+6hU8q4KzjpqvYYaO4Z9YoIOK7j9WRF0pdjAI1/QK3lbZPujInavYB92H5yJpjLXxoK"); - a("q+J3o0r0YRfYkzVfPZdQHuikp6Bt9CqD9wYjOVLXVK7oqOug/nreHsdAFuhHW6LQ/DNj2ac9d0droAt8U9PYOv4amO4fy1rFkX"); - a("4Mn4olfwfvzWhzl9bfv5yLlzZeTRIfdFAT2aU5l9LK6zcXn00CHHN+s4QKfkhlil2/IubNKH+aQ5yJ36EverZ316NM+qb516Bf"); - a("dr4Cz1aO7c0DPnsX3grI2sT2fjno2tTffhJSiuV/BBlNOH+Tmq6Q+8oYl91tv4LProS7zbrOIQfZhHNrO3ejQvwmm9gic3953V"); - a("M3gDgif+Hq7Wwtp0yL1RRPfhv62ctQ5bW39b76v78CS01TN4A7rqbdylnfXoPjwbC/QKXtEeOnLRDvZKl+NhuKdH81o81dv4Hd"); - a("7qD1y7oz3UIa9C8NRr+AES6hhO3sl8jk7JDZFet+W+yKZH8x7k0Yf5KoroGP6J0jow97cVlfQ2fowh+gMn7mK2U6fkZZikV/B+"); - a("7NSHuU5Xz0kdcne81H24RTe/j3RbHoH0z6yHm/e0Nt2WR6GhHs3xevnu6JR8CR115NfooT/w/t7upz7Ml7FEx/DRPvZIX+Lsfd"); - a("1VXYAbYKduyzX6WacOOVl/69QpeSISPnem/B4p9QeuM8CadcgbkU1v4+QD7adOyZVRQIc8CcX1DD6Ecvowf0I1HQwya4tQZ+MS"); - a("aKrL8Xa01X0Ge5YOca90Si6MAXobJxoaOxiuU/IrjNcfuNgIv+N0Ob6KdTqG44z0PNEpeYo5vcN6Bi/BW72C3+OL/sATxnqG6B"); - a("k8c5zn4Qvvyz3+s1v3vAxFcQDG6+UDGMQgTdyhG0OFUaJJV0MtImLoILFWYjJVgkjjpQiplrjES5n6EYiRoYsQi8tUYiAxivj1"); - a("e/QmT55naXL/555z0iWz6xz3Lts/OuAXjOiIkyvtsTHd9DgmdZbnkdV5XiyYSxf5ZM29rWt8g6qu8ytq+ou/172/jm3Yq7hv9q"); - a("a7GZEOeBoNneU5/Og87xXNokP+2/JNG3677d5DQgecxoDOcHzXXDrgNGZ0httK5tddPISSTvHjvnOtI+4oezfdxZWKM65DvkXs"); - a("3Vw8e2iP6RzvYFiH3H9kDXWS746tj67z6Klzp1O8cOZ/i85z4dze1kV+xrWOuOfCO+iAJ/Ck6xyrult006v41EU+wK8O+Q2dH9"); - a("ac+y59dx3wILp1iqcQ11l+QEJHXL6yt3XraT3/7MitSwMBAMbhQw6DGBYWRNRkGgYxiJhMi7JgEDEaLl0WkWEyH5dFjg38OD8Q"); - a("kywtikFMC8ZhWhCjXPLgHlzZn7C3PC+/6cxaWfj/aw9hEHXD4Lczbstlq12FwUJ33BplWy/bpJ3pCTt8Yp8fHPKHM9eVdTa4wz"); - a("1GbDPlJXO+8I2fHLHg/E3lIte4zRYPGfOE50x5wZw9vnLAIUcsOHdbucQNNnnAmKdMmPGRPQ74zdm8coVb3OURY7aZ8p59vvOL"); - a("Bet3lavcZJP7jHjMhBmf/wSlj0DpG1D6FZT+A6U51kDjE0rrgGkEcILyw6B0Gpp8DZTfBaXnQOl1UHoPlD4Hpe9A6XdQmmkty2"); - a("i+GM0Xo/kCR75AAPfUkuCSFI/EvJScVCjfOT+vGEA31e62DcPAvJrnuliAeDFqY/6t2NdUgywZFFXUe/pJFoUlQfpLvCPFj6Pk"); - a("DFo378xgfCR/KxOQ/SfluSFylLz9A35T2qP5mrCydjYxzZfmjtwE70s9RRzWo313Vam4LLGDk7YoTCCCLfeO8x07fBDUHMlnsa"); - a("mH6BXUYnG05bg4UDB41Qa/1BIL3bK7AJkbSfMeJZnEPNTGeYnLcydH57RlFCUaO5/fE12U3TxjSYNGfHIqTnghRdso/tRkNc+U"); - a("2z68EiARCTlaFLfRp67Yb9QElVsb7zZ1DrwGrjvJem7aYhdRfkKtiUlnZYybxE4VZcc7LbbQ0erL5kv1rH3Zq6B9ukkZySFIsv"); - a("QGWNMZ/Ao7y5WkrQ/LTb4BtGh7W2JUmqMKvbbXOOTlDybOOueIjrQjzbLde+7xvUiN8wr7Hx39Cy7hegV1BA/LZUo0nxFVh9wl"); - a("eIdlx8U+Ws1aGf0XNUUrDtxjkkf/AgN+wjeWQY900gvqE0/4gbZvrrTBsP6xMQY36hn1h6LIFnNwxS9/tqq7+9+d8Rv/I6OMeh"); - a("UGYSjsX8PtmtyEp+udeybamUUF0o3M/XuPtCTiHs9HCxR6em9cnBMT8EzPWZgN4ZbiIfl8Gm7Aq0afRljX3Tu/jP4iTMXPM9eX"); - a("HnixkPhM/2ukyexqmq23pdb5a3JXXTlgu7Jiao3RYtRLheR/wS+EoRDtwFvRxVuqizt7bBuWqR0Zrxp4NcpPxBPKlpMwmqJjOs"); - a("6MLiwRub1JBphW0gD4i2OFdV6/yVMC077VZwdLDMixJhLTTcQtDQ6/a5vfNte+inflKEs+s+xhQaL/aBOls2UfpFL0TRcj8T4N"); - a("Q79TYsNSEY1BwleGqTIqJevVTHzJNxXojuRiBiRXgEqJ7NSivNQcYyO9lJwcBmAqTSwtgXJKgR6HMocp0NjAAj7bhwmKTYB8Gy"); - a("B2AeJgf58w1yCw78FnwASIActvoHgYSA80XPNzylKLQNmLAcwMKK2qykk1NGUYBQBm7I7vcSAKw/iDweJgMVgMFgMLxWBhIVgM"); - a("LBSDhYXgmZfMnJnMSzCwUFgYLAYWisHCAwMLO9vffog9X+H6H7n/45vzrpkD7oDAHkqooIYTNHCBKwyAMMMCd4jwgBWesMEn/A"); - a("ZCj/QLbehXeqHfaE+/U6CWLvQnfdBfdKOf9MDPvFJHVauTatRZXVWvZrWou4rqoVb1VJt6qaQ+sMAdEtxjiQc8YYNnbPGCHV6x"); - a("xxsOCDjjD4z4woQfutA7TXStT7rRZ93qi+70Vff6pgcNGvWsF33XUT/0qp960y+d9IcpzM4QszelOZjKHE1tTqYxZ9Oai+nM1f"); - a("TmZgYDBs3dHKZ26qZ+GiaclilO67RNaSossaWtbG0b29rO9nawaBcb7Wo3m2zhiCtd5WrXuNZ1rneDQ7e46Fa3ueQKT3zpK1/7"); - a("xre+870fPPrFR7/6zSdfBBLKUIU6NKENXejDEDAsIYY1bCGF3Omed9f8lAWQf5UaaKGD/l1pgQhrrpOgoISWtKJ17tPSLtcZKO"); - a("Y2ka65TKIFI6xkFatZw1rWsZ4NDNnCIlvZxhIrOOElr3jNG97yjvd84MgXHvnKN554IYgoRSVq0YhWdKIXg0CxiChWsYkkipGM"); - a("h7EajyOO83gf47iOz/E1prGQO7mXpazkUZ5kI1t5kVfZy0GCnOUio3zIp9xkkh9qp4gq1eGvoLefi+qyoJsChW9F2dBbUPbz1n"); - a("PACuvsJ+t52/lDmd3yyAmGURgmqaEOuRKJRK5EIpErkUjkJDUkNUjkypev7bvDpxyJRCJHIpHIyp59OJmk2512+w/Iw3XumcxQ"); - a("yCd8iAy6EBWHCYoYzxeYWM7X83rezz/PRmM1D43duM1j4zVB89SETQwvSZNBjGpGmJmaBWrWZocbo7Ugx25d2PHaAHrCNoafpM"); - a("0gSLUjDE3tAkVru8OR0VmQZHcuLHldAE1hF8NT0mUQpboRpqZugaq12+HK6C3IsnsXtrw+gK6wj+Er6TMIU/3S770FW/bgQpc3"); - a("BPAVDjGEJUMGY2oYoWwaFjhbh/1N2oLf/d+Cro4iuLDmSRFCFcNbojKIU0cXWIUd7ozcgjw7d2HPywPoC/MY/pI8g0CVjzA45Q"); - a("sUrvkOh0ZhQaJduLDoFQE0hkUMj0mRQaQqRpicigUq12KHS6O0INMuXdj0ygA6wzKGz6TMIFSVI4xO5QKla7nDqVFZkGpXLqx6"); - a("VQCtYRXDa1JlEKuqEWanaoHatdrh1qgtyLVpN6if6rCO61Od1Fn9XCtYvkDzctNsvNhw7MMwbrXifw3czFSs6HE1KWmJK624js"); - a("PL+LxNxOukucJlNtzDLJzbJSLeIuU1dDHKJTZewi6TSuH5Vzz519rBs36rv8tzRthK9pfSPkplT+iqRlkvekJbF33Vq97YWPv1"); - a("8dXDdu6vxpSW+u/rybXM5wVbMbEUV/YRcSEpN6JlJVfZxwNW4XMXEZeRchuTrMLoHK7B5x4iLiLtNLYwo6/HBhyuwOcOIiwhQ2"); - a("XHfkFhjcEcjiU43IIvazjJDi7Qvx3+d/wfj84a6v3bjGA/VZrmN6o36R7vF282EetTvtG4SeUOnftFJG9VU/ZG2yZ1O/TtU3hE"); - a("4ymUa/ie0eDDtUPZPm1H1J3Ct4aMudrg+jDtULVP1xFlp7StoXuG600a7UqhfWl0KJU+SaczKbWWVk8v15cdpX74YbPSgXQ6kl"); - a("In0upnqfU/P/Uh0tP+H5/91Ck2N3FpfUKmITX30PHonk7WfEPL34w6KLkvSlPWe2a/NxbcRMNdURq3qcjU7PbMcm9st8l6i1V+"); - a("D1CdhtHl1muzv6OV3U6PcovbSz/1m8iF2Vu9I/Y7ZcE1Gz6z4nRs4L/eLx859lnziD1PWfTbd70PhD9KtU55Bt2aLZ9Z87vW77"); - a("WMbZ//dwMs/VyuWIF5zz/7rln4mY2XNcgSsIHf9bPtM+u+se+/2juz0JnCMIwfBh1ZGkVOpCypIcufLCdLja1EMrZMoZALW7IU"); - a("QvYsyXYhU8I5M2dmzpnvnBmKsu9ZUxPRlCXhYkppkCX7872+rN98thsX5mbu3+f3PO/zfk0N94LBGws5Ik4+SIB83lNK1FQq1F"); - a("V0aiutqa+YEi+4nH+Qryae2u73qQzued81/6DrRqnLrPyRe9FjdNFkIqLLDGUxRVqTK+AG3mZMSVb/xBGKDN9H7qgEv+OJi0j0"); - a("Uv4evFGRJPtkcof1vR/C/Leof+eHMFI+Tns7oeA/StSvVHJuEtuLQbMrmstF0V3Kor3oToToBtcKoj917biC5jDxG5NluCBZI3"); - a("qjyux+RfSaKl4/sxpV0QpKOaE1RKc8o0tEqKFg8hRbV9iC3DtZuAB9nxfe8fuodUg7AH0Nq7PVE4pOs2ZDyx3WbusQ6Vex6tmN"); - a("oV8/ezA0nG8vQZZ59n6oeMt+AP3qJ5vwu4jU24iU2p88DN1qIZE6pLohi5YhfdKpADrdTj2EQhGkzgxnHvJmp7MXulx1bkCP9l"); - a("BjRHoc9utG6HA//RQbtUWmLfJjRGYcEmR9ZiumfwfJUTfbCIkxJDsCc1+RXY95H86exo58mf2QNdyebn+kwyJ3BWZ80D2OJHjq"); - a("vnF1r43XAfOd6E3DdDd7OzDVx9573DBdcr1wvSzILcUkg9xBeP1R7hk6WEfWHVPciJmdZpew016w9+hcXf3e1LngWe5WhU9X0t"); - a("VxKihX3V7TyZ+uwpEx2ljbZDuqJqRN/KprmeTExYpd1Jo69GS0ZlwV0l2k0wYaqtg5lSR3YI1stwg3lsiDhmK7nCIHaopm5ZIH"); - a("y2mxQyStahv5sKjYIYvJiYcUvWm66ErfNnh6JUFbing1XpycmPirTREhL06XbATRk7AXIuhIMcVOeOVzwsyvs1/ctK64asvEV0"); - a("SR/UXiKyzau6wNHSK+6L0kGtIWg63qOW9xwsCWaPCSC20DEXZR0W/mEmH7FD0mToQlZAkvLtShxNcGSbrzq1THXVpDfM1VtBVD"); - a("dJRqGX/vF1K+THxFFL2kSISFKePlb3CniDBN8dK2T9yH1buHxekCV7p4O+Fkmd/ciduIraKyYcgpK1GOGX/cMUxxM1Zv3VospA"); - a("3+hZ6RoIQrfbkgFS8EkqwDkZxG84/6dYxyb1uV3qG+L/eB0Fd0V5pgUn5LEp/fNmjKPrz5EaGuokHHspjd5JBm4WtKbiaosXIe"); - a("culJrhZrwtqwbmwAG8WmsHlsFduOLDrCzrMSJdAg0DHLX4D82eWnkDxX/OvooW/9OqCjZ9AfVMwJFoIGJ/DROW8HD5E3zfKtsM"); - a("eG58eAg2X5tdD/YP44dH+af42c6VToAb1nFOYhXfYUMlD7ZuEuV3luSDvH/6vFag5th1mjoelSaw009a0DVpG2lW63tNtBz5H2"); - a("eOgIDaHfGfsydtQL+71tJLskeyE/piZnQjmoBsUuJ69BqzqphlBoYGoYttPy1DrspKOps1Ao7LSFGmOcCdBhvbMVbfCkcwE58d"); - a("L5gBbYPd0HaixIL4UKJ9LnkQu4YDD77pm+mPvUzCz0v9HeBLh1tbcJPuU/SAppY/GFDUBOnay4lHVW22/gG+TDmL8e6X6MXr6b"); - a("wnWjgknCaZz5kNYUX9iQlGM8tbT/n3/68xHeVZKEADYEAA=="); + var shift = (11 - Hole[n]) * 4; + var a = State[n] & (0xFUL << shift); + Hole[n + 1] = Hole[n] + 4; + State[n + 1] = State[n] - a + (a << 16); + Move[n + 1] = 'd'; + Cost[n + 1] = Cost[n] + (RowIndex[a >> shift] <= Hole[n] / 4 ? 0 : 1); + } + + void Up() + { + var shift = (19 - Hole[n]) * 4; + var a = State[n] & (0xFUL << shift); + Hole[n + 1] = Hole[n] - 4; + State[n + 1] = State[n] - a + (a >> 16); + Move[n + 1] = 'u'; + Cost[n + 1] = Cost[n] + (RowIndex[a >> shift] >= Hole[n] / 4 ? 0 : 1); + } + + void Right() + { + var shift = (14 - Hole[n]) * 4; + var a = State[n] & (0xFUL << shift); + Hole[n + 1] = Hole[n] + 1; + State[n + 1] = State[n] - a + (a << 4); + Move[n + 1] = 'r'; + Cost[n + 1] = Cost[n] + (ColIndex[a >> shift] <= Hole[n] % 4 ? 0 : 1); + } + + void Left() + { + int shift = (16 - Hole[n]) * 4; + ulong a = State[n] & (0xFUL << shift); + Hole[n + 1] = Hole[n] - 1; + State[n + 1] = State[n] - a + (a >> 4); + Move[n + 1] = 'l'; + Cost[n + 1] = Cost[n] + (ColIndex[a >> shift] >= Hole[n] % 4 ? 0 : 1); + } + + public FifteenSolver(int n, ulong g) + { + Hole[0] = n; + State[0] = g; + } + + public void Solve() + { + for (; !Scan(); ++maxCost) + ; } } diff --git a/Task/15-puzzle-solver/JavaScript/15-puzzle-solver.js b/Task/15-puzzle-solver/JavaScript/15-puzzle-solver.js new file mode 100644 index 0000000000..1904d1d75b --- /dev/null +++ b/Task/15-puzzle-solver/JavaScript/15-puzzle-solver.js @@ -0,0 +1,97 @@ +class FifteenSolver { + constructor(n, g) { + this.Nr = [3,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3]; + this.Nc = [3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]; + this.n = 0; + this._n = 0; + this.N0 = new Array(100).fill(0); + this.N3 = new Array(100).fill(''); + this.N4 = new Array(100).fill(0); + this.N2 = new Array(100).fill(0n); + this.N0[0] = n; + this.N2[0] = BigInt(g); + } + + fY() { + if (this.N4[this.n] < this._n) return this.fN(); + if (this.N2[this.n] === 0x123456789abcdef0n) { + let moves = ''; + for (let g = 1; g <= this.n; g++) moves += this.N3[g]; + console.log(`Solution found in ${this.n} moves: ${moves}`); + return true; + } + if (this.N4[this.n] === this._n) return this.fN(); + return false; + } + + fN() { + if (this.N3[this.n] !== 'u' && Math.floor(this.N0[this.n]/4) < 3) { + this.fI(); + this.n++; + if (this.fY()) return true; + this.n--; + } + if (this.N3[this.n] !== 'd' && Math.floor(this.N0[this.n]/4) > 0) { + this.fG(); + this.n++; + if (this.fY()) return true; + this.n--; + } + if (this.N3[this.n] !== 'l' && this.N0[this.n]%4 < 3) { + this.fE(); + this.n++; + if (this.fY()) return true; + this.n--; + } + if (this.N3[this.n] !== 'r' && this.N0[this.n]%4 > 0) { + this.fL(); + this.n++; + if (this.fY()) return true; + this.n--; + } + return false; + } + + fI() { + const g = (11 - this.N0[this.n]) * 4; + const a = this.N2[this.n] & (15n << BigInt(g)); + this.N0[this.n + 1] = this.N0[this.n] + 4; + this.N2[this.n + 1] = this.N2[this.n] - a + (a << 16n); + this.N3[this.n + 1] = 'd'; + this.N4[this.n + 1] = this.N4[this.n] + (this.Nr[Number(a >> BigInt(g))] <= Math.floor(this.N0[this.n]/4) ? 0 : 1); + } + + fG() { + const g = (19 - this.N0[this.n]) * 4; + const a = this.N2[this.n] & (15n << BigInt(g)); + this.N0[this.n + 1] = this.N0[this.n] - 4; + this.N2[this.n + 1] = this.N2[this.n] - a + (a >> 16n); + this.N3[this.n + 1] = 'u'; + this.N4[this.n + 1] = this.N4[this.n] + (this.Nr[Number(a >> BigInt(g))] >= Math.floor(this.N0[this.n]/4) ? 0 : 1); + } + + fE() { + const g = (14 - this.N0[this.n]) * 4; + const a = this.N2[this.n] & (15n << BigInt(g)); + this.N0[this.n + 1] = this.N0[this.n] + 1; + this.N2[this.n + 1] = this.N2[this.n] - a + (a << 4n); + this.N3[this.n + 1] = 'r'; + this.N4[this.n + 1] = this.N4[this.n] + (this.Nc[Number(a >> BigInt(g))] <= this.N0[this.n]%4 ? 0 : 1); + } + + fL() { + const g = (16 - this.N0[this.n]) * 4; + const a = this.N2[this.n] & (15n << BigInt(g)); + this.N0[this.n + 1] = this.N0[this.n] - 1; + this.N2[this.n + 1] = this.N2[this.n] - a + (a >> 4n); + this.N3[this.n + 1] = 'l'; + this.N4[this.n + 1] = this.N4[this.n] + (this.Nc[Number(a >> BigInt(g))] >= this.N0[this.n]%4 ? 0 : 1); + } + + solve() { + while (!this.fY()) this._n++; + } +} + +const start = new FifteenSolver(8, '0xfe169b4c0a73d852'); +start.solve(); diff --git a/Task/15-puzzle-solver/Mathematica/15-puzzle-solver.math b/Task/15-puzzle-solver/Mathematica/15-puzzle-solver.math new file mode 100644 index 0000000000..3a7bdde6e4 --- /dev/null +++ b/Task/15-puzzle-solver/Mathematica/15-puzzle-solver.math @@ -0,0 +1,178 @@ +(* Constants for the correct ordering and board position mapping *) +correctOrder = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0}; +rowOf = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3} + 1; (* +1 because Mathematica uses 1-based indexing *) +colOf = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3} + 1; (* +1 because Mathematica uses 1-based indexing *) + +(* Function to estimate remaining moves using Manhattan distance *) +EstimateMoves[board_] := Module[{h = 0}, + Do[ + (* Skip the empty tile (0) *) + If[board[[i]] != 0, + (* Find where this tile should be in the correct order *) + correctPos = Position[correctOrder, board[[i]]][[1, 1]]; + (* Calculate Manhattan distance: |current_row - correct_row| + |current_col - correct_col| *) + h += Abs[rowOf[[i]] - rowOf[[correctPos]]] + Abs[colOf[[i]] - colOf[[correctPos]]]; + ], + {i, 1, 16} + ]; + h +] + +(* Find the position of the blank tile (0) *) +FindBlankPosition[board_] := Position[board, 0][[1, 1]] + +(* Generate possible moves from current state *) +GenerateMoves[board_, movesSoFar_] := Module[ + {blankPos, possibleMoves = {}, newBoard, newMoves}, + + blankPos = FindBlankPosition[board]; + + (* Check if we can move left (blank goes right) *) + If[Mod[blankPos, 4] != 1, + newBoard = board; + newBoard[[blankPos]] = newBoard[[blankPos - 1]]; + newBoard[[blankPos - 1]] = 0; + newMoves = movesSoFar <> "r"; + AppendTo[possibleMoves, {newBoard, newMoves, Length[newMoves] + EstimateMoves[newBoard]}]; + ]; + + (* Check if we can move right (blank goes left) *) + If[Mod[blankPos, 4] != 0, + newBoard = board; + newBoard[[blankPos]] = newBoard[[blankPos + 1]]; + newBoard[[blankPos + 1]] = 0; + newMoves = movesSoFar <> "l"; + AppendTo[possibleMoves, {newBoard, newMoves, Length[newMoves] + EstimateMoves[newBoard]}]; + ]; + + (* Check if we can move up (blank goes down) *) + If[blankPos > 4, + newBoard = board; + newBoard[[blankPos]] = newBoard[[blankPos - 4]]; + newBoard[[blankPos - 4]] = 0; + newMoves = movesSoFar <> "d"; + AppendTo[possibleMoves, {newBoard, newMoves, Length[newMoves] + EstimateMoves[newBoard]}]; + ]; + + (* Check if we can move down (blank goes up) *) + If[blankPos <= 12, + newBoard = board; + newBoard[[blankPos]] = newBoard[[blankPos + 4]]; + newBoard[[blankPos + 4]] = 0; + newMoves = movesSoFar <> "u"; + AppendTo[possibleMoves, {newBoard, newMoves, Length[newMoves] + EstimateMoves[newBoard]}]; + ]; + + possibleMoves +] + +(* A* Search algorithm for solving the puzzle *) +Solve15Puzzle[startBoard_] := Module[ + {openSet = {}, closedSet = {}, current, children, bestMoves = {}}, + + (* Initialize the priority queue (Mathematica doesn't have a built-in priority queue, + so we'll use a list and sort it each time) *) + openSet = {{startBoard, "", EstimateMoves[startBoard]}}; + + While[Length[openSet] > 0, + (* Sort the open set by total estimated cost *) + openSet = Sort[openSet, #1[[3]] < #2[[3]] &]; + + (* Get the most promising state *) + current = First[openSet]; + openSet = Rest[openSet]; + + (* Check if we've reached the goal state *) + If[current[[1]] == correctOrder, + Print["Solution found!"]; + Print["Moves: ", current[[2]]]; + Print["Number of moves: ", StringLength[current[[2]]]]; + Print["Open set size: ", Length[openSet]]; + Print["Closed set size: ", Length[closedSet]]; + + (* Format the final board *) + Print["Final board:"]; + Print[Partition[current[[1]], 4]]; + Return[current[[2]]]; + ]; + + (* Generate all possible moves from current state *) + children = GenerateMoves[current[[1]], current[[2]]]; + + (* Process each child state *) + For[i = 1, i <= Length[children], i++, + child = children[[i]]; + childBoard = child[[1]]; + + (* Check if this board is already in the closed set *) + If[Not[MemberQ[Map[First, closedSet], childBoard]], + (* Check if this board is already in the open set *) + existingIdx = Position[Map[First, openSet], childBoard]; + + If[existingIdx == {}, + (* Add to open set if not already there *) + AppendTo[openSet, child]; + , + (* Update if this path is better than existing one *) + existingIdx = existingIdx[[1, 1]]; + If[StringLength[child[[2]]] < StringLength[openSet[[existingIdx, 2]]], + openSet[[existingIdx]] = child; + ]; + ]; + ]; + ]; + + (* Add current state to closed set *) + AppendTo[closedSet, current]; + ]; + + Print["No solution found!"]; + Return[{}]; +] + +(* Example usage *) +startingBoard = {15, 14, 1, 6, 9, 11, 4, 12, 0, 10, 7, 3, 13, 8, 5, 2}; +(* startingBoard = {0, 1, 2, 3, 5, 6, 7, 4, 9, 10, 11, 8, 13, 14, 15, 12}; *) + +solution = Solve15Puzzle[startingBoard]; + +(* Pretty print function to visualize a board *) +PrintBoard[board_] := Module[{}, + Grid[Partition[board, 4], Frame -> All] +] + +(* Visualization code to show the solution step by step *) +VisualizeSolution[startBoard_, moves_] := Module[ + {currentBoard = startBoard, frames = {PrintBoard[startBoard]}, blankPos}, + + Do[ + blankPos = FindBlankPosition[currentBoard]; + + Switch[StringTake[moves, {i}], + "l", (* blank moves left *) + currentBoard[[blankPos]] = currentBoard[[blankPos - 1]]; + currentBoard[[blankPos - 1]] = 0, + + "r", (* blank moves right *) + currentBoard[[blankPos]] = currentBoard[[blankPos + 1]]; + currentBoard[[blankPos + 1]] = 0, + + "u", (* blank moves up *) + currentBoard[[blankPos]] = currentBoard[[blankPos - 4]]; + currentBoard[[blankPos - 4]] = 0, + + "d", (* blank moves down *) + currentBoard[[blankPos]] = currentBoard[[blankPos + 4]]; + currentBoard[[blankPos + 4]] = 0 + ]; + + AppendTo[frames, PrintBoard[currentBoard]]; + + ,{i, 1, StringLength[moves]} + ]; + + ListAnimate[frames] +] + +(* Uncomment to visualize the solution *) +(* If[solution != {}, VisualizeSolution[startingBoard, solution]]; *) diff --git a/Task/15-puzzle-solver/Zig/15-puzzle-solver.zig b/Task/15-puzzle-solver/Zig/15-puzzle-solver.zig new file mode 100644 index 0000000000..e566437561 --- /dev/null +++ b/Task/15-puzzle-solver/Zig/15-puzzle-solver.zig @@ -0,0 +1,187 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const ArrayList = std.ArrayList; +const PriorityQueue = std.PriorityQueue; +const AutoHashMap = std.AutoHashMap; + +// Constants for the puzzle +const CORRECT_ORDER = [16]u8{ 1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,0 }; +const ROW = [16]i32{ 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3 }; +const COLUMN = [16]i32{ 0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,2,3 }; + +// State struct to represent the puzzle state +const State = struct { + est_tot_moves: u8, + moves: []u8, + est_moves_rem: u8, + allocator: Allocator, + + pub fn init(allocator: Allocator, order: [16]u8) !State { + return State{ + .est_tot_moves = estimate_moves(order), + .moves = try allocator.dupe(u8, ""), // empty + .est_moves_rem = estimate_moves(order), + .allocator = allocator, + }; + } + + pub fn deinit(self: *State) void { + self.allocator.free(self.moves); + } +}; + +// BoardState represents the entire game state +const BoardState = struct { + order: [16]u8, + state: State, +}; + +// Find the index of a tile in the order array +fn findIndex(order: [16]u8, tile: u8) usize { + var i: usize = 0; + for (order) |v| { + if (v == tile) return i; + i += 1; + } + @panic("findIndex: tile not found"); +} + +// Estimate the number of moves (Manhattan distance) +fn estimate_moves(current: [16]u8) u8 { + var h: u8 = 0; + for (current) |tile| { + const ci = findIndex(current, tile); + const gi = findIndex(CORRECT_ORDER, tile); + const rd = @abs(ROW[ci] - ROW[gi]); + const cd = @abs(COLUMN[ci] - COLUMN[gi]); + h += @as(u8, @intCast(rd + cd)); + } + return h; +} + +// Make a single move (swap hole with neighbor) +fn makeMove( + allocator: Allocator, + parent: *const State, + order: [16]u8, + dir: u8, + idx: usize, + new_idx: usize, +) !BoardState { + var new_order = order; + new_order[idx] = order[new_idx]; + new_order[new_idx] = order[idx]; + + const rem = estimate_moves(new_order); + const mv: [1]u8 = .{dir}; + const combined = try std.mem.concat(allocator, u8, &[_][]const u8{ parent.moves, &mv }); + + return BoardState{ + .order = new_order, + .state = State{ + .est_tot_moves = @as(u8, @intCast(combined.len)) + rem, + .moves = combined, + .est_moves_rem = rem, + .allocator = allocator, + }, + }; +} + +// Generate all children from a parent (takes *const so we don't double-free) +fn generateChildren(allocator: Allocator, parent: *const BoardState) !ArrayList(BoardState) { + var children = ArrayList(BoardState).init(allocator); + const hole = findIndex(parent.order, 0); + + if (COLUMN[hole] > 0) { + const c = try makeMove(allocator, &parent.state, parent.order, 'l', hole, hole - 1); + try children.append(c); + } + if (COLUMN[hole] < 3) { + const c = try makeMove(allocator, &parent.state, parent.order, 'r', hole, hole + 1); + try children.append(c); + } + if (ROW[hole] > 0) { + const c = try makeMove(allocator, &parent.state, parent.order, 'u', hole, hole - 4); + try children.append(c); + } + if (ROW[hole] < 3) { + const c = try makeMove(allocator, &parent.state, parent.order, 'd', hole, hole + 4); + try children.append(c); + } + + return children; +} + +// Compare function for priority queue +fn boardCompare(_: void, a: BoardState, b: BoardState) std.math.Order { + return std.math.order(a.state.est_tot_moves, b.state.est_tot_moves); +} + +// Hash an order into a u64 +fn hashOrder(order: [16]u8) u64 { + var r: u64 = 0; + for (order) |v| r = (r << 4) | v; + return r; +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + var open_states = PriorityQueue(BoardState, void, boardCompare).init(allocator, {}); + defer { + while (open_states.count() > 0) { + var item = open_states.remove(); + item.state.deinit(); + } + open_states.deinit(); + } + + var closed_states = AutoHashMap(u64, void).init(allocator); + defer closed_states.deinit(); + + const start_order = [16]u8{15,14,1,6,9,11,4,12, 0,10,7,3,13,8,5,2}; + const initial_state = try State.init(allocator, start_order); + try open_states.add(BoardState{ .order = start_order, .state = initial_state }); + + const stdout = std.io.getStdOut().writer(); + + while (open_states.count() > 0) { + var current = open_states.remove(); + + // goal check + if (std.mem.eql(u8, ¤t.order, &CORRECT_ORDER)) { + try stdout.print( + "Open: {d}, Closed: {d}, Moves: {d}\n", + .{ open_states.count(), closed_states.count(), current.state.moves.len }, + ); + try stdout.print("Path: {s}\n", .{ current.state.moves }); + current.state.deinit(); + break; + } + + const h = hashOrder(current.order); + if (closed_states.contains(h)) { + current.state.deinit(); + continue; + } + try closed_states.put(h, {}); + + var children = try generateChildren(allocator, ¤t); + defer children.deinit(); + + // ↓ Here’s the fix: shadow each child into a mutable `var child` + for (children.items) |child| { + var my_child = child; // now `child.state.deinit()` sees a `*State`, not `*const State` + const ch = hashOrder(my_child.order); + if (closed_states.contains(ch)) { + my_child.state.deinit(); + continue; + } + try open_states.add(my_child); + } + + current.state.deinit(); + } +} diff --git a/Task/2048/BQN/2048.bqn b/Task/2048/BQN/2048.bqn index a73e95c7b4..cb0a27ed3b 100644 --- a/Task/2048/BQN/2048.bqn +++ b/Task/2048/BQN/2048.bqn @@ -15,7 +15,7 @@ Spawn←{i←•rand.Range∘≠⊸⊑(0⊸= /○⥊ ↕∘≢)𝕩 ⋄ (•rand Lose←Left∘Right∘Down∘Up⊸≡ # Losing condition, no moves change the board Win←∨´·∨˝2048⊸= # Winning condition, 2048! -Quit←{•Out e∾"[?12l"∾e∾"[?25h" ⋄ •Exit 𝕩} # Restores the terminal and exits +Quit←{•Out e∾"[?12l"∾e∾"[?25h" ⋄ •term.RawMode 0 ⋄ •Exit 𝕩} # Restores the terminal and exits Display←{ # Displays the board, score and controls •Out e∾"[H"∾e∾"[2J" # Cursor to origin and clear screen •Out "Controls: h: left, j: down, k: up, l: right, q: quit" diff --git a/Task/2048/EasyLang/2048.easy b/Task/2048/EasyLang/2048.easy new file mode 100644 index 0000000000..410f4010a9 --- /dev/null +++ b/Task/2048/EasyLang/2048.easy @@ -0,0 +1,161 @@ +len brd[] 16 +gbackground 987 +proc newtile . + for i to 16 : if brd[i] = 0 : break 1 + if i > 16 : return + v = 2 + if randomf < 0.1 : v = 4 + repeat + ind = random 16 + until brd[ind] = 0 + . + brd[ind] = v +. +global pts stat . +proc show . + gclear + gtextsize 5 + gcolor 222 + gtext 10 94 "2048 Game" + gtext 60 94 "Pts: " & pts + gtextsize 7 + gcolor 876 + grect 9 9 82 82 + gcolor 987 + grect 10 10 80 80 + for i to 16 : if brd[i] <> 0 + x = i mod1 4 * 20 - 9.5 + y = i div1 4 * 20 - 9.5 + gcolor 765 + grect x y 19 19 + v = brd[i] + h = 2 * floor log10 v + gcolor 000 + gtext x + 7 - h y + 7 brd[i] + . +. +proc init . + for i to 16 : brd[i] = 0 + newtile + newtile + stat = 0 + pts = 0 + show +. +init +# +dir[] = [ -4 -1 4 1 ] +start[] = [ 16 4 1 13 ] +proc domove indk test &moved . + moved = 0 + dir = dir[indk] + bdir = dir[(indk + 1) mod1 4] + start = start[indk] + for i to 4 + h0 = start + dir + for j to 3 + if brd[h0] <> 0 + v = brd[h0] + h = h0 + while h <> start and brd[h - dir] = 0 : h -= dir + if h <> h0 + moved = 1 + if test = 1 : return + . + if h <> start and brd[h - dir] = v + moved = 1 + if test = 1 : return + v *= 2 + pts += v + brd[h - dir] = -v + if v = 2048 : stat = 1 + v = 0 + . + brd[h0] = 0 + brd[h] = v + . + h0 += dir + . + h0 = start + for j to 3 + brd[h0] = abs brd[h0] + h0 += dir + . + sleep 0.1 + show + start += bdir + . +. +proc handle indk . + if indk = 0 : return + domove indk 0 moved + if moved = 1 + newtile + sleep 0.2 + show + if stat = 0 + stat = 2 + for indk to 4 + domove indk 1 moved + if moved = 1 + stat = 0 + break 1 + . + . + . + . + if stat <> 0 + gtextsize 5 + if stat = 1 + stat = 0 + gtext 10 3 "You got 2048 😊" + else + gtext 10 3 "No more moves 🙁" + . + . +. +on mouse_down + mx = mouse_x + my = mouse_y +. +proc handle_mup . + dx = mouse_x - mx + dy = mouse_y - my + indk = 0 + if abs dx > abs dy + if abs dx > 3 + indk = 4 + if dx > 0 : indk = 2 + . + else + if abs dy > 3 + indk = 3 + if dy > 0 : indk = 1 + . + . + if indk <> 0 and stat = 2 + init + else + handle indk + . +. +on mouse_up + handle_mup +. +on key + if stat = 2 + if keybkey = " " : init + return + . + indk = 0 + if keybkey = "ArrowUp" + indk = 1 + elif keybkey = "ArrowRight" + indk = 2 + elif keybkey = "ArrowDown" + indk = 3 + elif keybkey = "ArrowLeft" + indk = 4 + . + handle indk +. diff --git a/Task/2048/Zig/2048.zig b/Task/2048/Zig/2048.zig new file mode 100644 index 0000000000..2f59b71609 --- /dev/null +++ b/Task/2048/Zig/2048.zig @@ -0,0 +1,228 @@ +const std = @import("std"); +const io = std.io; +const Random = std.Random; + +// UserMove enum representing possible moves +const UserMove = enum { + Up, + Down, + Left, + Right, +}; + +// Game field type +const Field = [4][4]u32; + +// Function to print the current game state +fn printGame(field: *const Field) void { + for (field) |row| { + std.debug.print("{any}\n", .{row}); + } +} + +// Function to get a user move +fn getUserMove() !UserMove { + const stdin = std.io.getStdIn().reader(); + var buf: [2]u8 = undefined; // Buffer for input (character + newline) + + while (true) { + const bytesRead = try stdin.read(&buf); + if (bytesRead < 1) continue; + + switch (buf[0]) { + 'a' => return UserMove.Left, + 'w' => return UserMove.Up, + 's' => return UserMove.Down, + 'd' => return UserMove.Right, + else => { + std.debug.print("input was {c}: invalid character should be a,s,w or d\n", .{buf[0]}); + }, + } + } +} + +// This function implements user moves. +// For every element, it checks if the element is zero. +// If the element is zero, it looks against the direction of movement if any +// element is not zero, then moves it to its place and checks for a matching element. +// If the element is not zero, it looks for a match. If no match is found, +// it looks for the next element. +fn doGameStep(step: UserMove, field: *Field) void { + switch (step) { + .Left => { + for (field) |*row| { + for (0..4) |col| { + for ((col + 1)..4) |my_testCol| { + if (row[my_testCol] != 0) { + if (row[col] == 0) { + row[col] += row[my_testCol]; + row[my_testCol] = 0; + } else if (row[col] == row[my_testCol]) { + row[col] += row[my_testCol]; + row[my_testCol] = 0; + break; + } else { + break; + } + } + } + } + } + }, + .Right => { + for (field) |*row| { + var col: i32 = 3; + while (col >= 0) : (col -= 1) { + var my_testCol: i32 = col - 1; + while (my_testCol >= 0) : (my_testCol -= 1) { + if (row[@intCast(my_testCol)] != 0) { + if (row[@intCast(col)] == 0) { + row[@intCast(col)] += row[@intCast(my_testCol)]; + row[@intCast(my_testCol)] = 0; + } else if (row[@intCast(col)] == row[@intCast(my_testCol)]) { + row[@intCast(col)] += row[@intCast(my_testCol)]; + row[@intCast(my_testCol)] = 0; + break; + } else { + break; + } + } + } + } + } + }, + .Down => { + for (0..4) |col_idx| { + const col = col_idx; // Convert to immutable + var row: i32 = 3; + while (row >= 0) : (row -= 1) { + var my_testRow: i32 = row - 1; + while (my_testRow >= 0) : (my_testRow -= 1) { + if (field[@intCast(my_testRow)][col] != 0) { + if (field[@intCast(row)][col] == 0) { + field[@intCast(row)][col] += field[@intCast(my_testRow)][col]; + field[@intCast(my_testRow)][col] = 0; + } else if (field[@intCast(row)][col] == field[@intCast(my_testRow)][col]) { + field[@intCast(row)][col] += field[@intCast(my_testRow)][col]; + field[@intCast(my_testRow)][col] = 0; + break; + } else { + break; + } + } + } + } + } + }, + .Up => { + for (0..4) |col| { + for (0..4) |row| { + for ((row + 1)..4) |my_testRow| { + if (field[my_testRow][col] != 0) { + if (field[row][col] == 0) { + field[row][col] += field[my_testRow][col]; + field[my_testRow][col] = 0; + } else if (field[row][col] == field[my_testRow][col]) { + field[row][col] += field[my_testRow][col]; + field[my_testRow][col] = 0; + break; + } else { + break; + } + } + } + } + } + }, + } +} + +// Spawn a new number (2 or 4) in a random empty cell +fn spawn(field: *Field, random: Random) void { + while (true) { + const x = random.uintLessThan(usize, 16); // Random position 0-15 + const row = x % 4; + const col = (x / 4) % 4; + + if (field[row][col] == 0) { + // 10% chance for a 4, 90% chance for a 2 + if (random.uintLessThan(usize, 10) == 0) { + field[row][col] = 4; + } else { + field[row][col] = 2; + } + break; + } + } +} + +// Check if fields are equal +fn areFieldsEqual(a: *const Field, b: *const Field) bool { + for (0..4) |i| { + for (0..4) |j| { + if (a[i][j] != b[i][j]) return false; + } + } + return true; +} + +// Check if player has won (any tile equals 2048) +fn checkWin(field: *const Field) bool { + for (field) |row| { + for (row) |cell| { + if (cell == 2048) return true; + } + } + return false; +} + +pub fn main() !void { + var prng = std.Random.DefaultPrng.init(@intCast(std.time.milliTimestamp())); + const random = prng.random(); + + var field: Field = [_][4]u32{[_]u32{0} ** 4} ** 4; + var my_test: Field = undefined; + + gameLoop: while (true) { + // Check if there's still an open space + @memcpy(&my_test, &field); + spawn(&field, random); + + // Check if any valid moves remain + var validMoveExists = false; + const moves = [_]UserMove{ .Up, .Down, .Left, .Right }; + + for (moves) |move| { + @memcpy(&my_test, &field); + doGameStep(move, &my_test); + + if (!areFieldsEqual(&my_test, &field)) { + validMoveExists = true; + break; + } + } + + if (!validMoveExists) { + std.debug.print("No more valid moves, you lose\n", .{}); + break :gameLoop; + } + + // Print the current game state + printGame(&field); + std.debug.print("move the blocks\n", .{}); + + // Get and apply user move + @memcpy(&my_test, &field); + while (areFieldsEqual(&my_test, &field)) { + const move = try getUserMove(); + doGameStep(move, &field); + } + + // Check win condition + if (checkWin(&field)) { + printGame(&field); + std.debug.print("You Won!!\n", .{}); + break :gameLoop; + } + } +} diff --git a/Task/24-game-Solve/Dart/24-game-solve.dart b/Task/24-game-Solve/Dart/24-game-solve.dart new file mode 100644 index 0000000000..38d41aaba9 --- /dev/null +++ b/Task/24-game-Solve/Dart/24-game-solve.dart @@ -0,0 +1,226 @@ +enum Operator { + Sub, + Plus, + Mul, + Div +} + +class Factor { + String content; + int value; + + Factor({this.content, this.value}); + + Factor copyWith({String content, int value}) { + return Factor( + content: content ?? this.content, + value: value ?? this.value + ); + } +} + +List apply(Operator op, List left, List right) { + List ret = []; + for (var l in left) { + for (var r in right) { + switch (op) { + case Operator.Sub: + if (l.value > r.value) { + ret.add(Factor( + content: "(${l.content} - ${r.content})", + value: l.value - r.value + )); + } + break; + case Operator.Plus: + ret.add(Factor( + content: "(${l.content} + ${r.content})", + value: l.value + r.value + )); + break; + case Operator.Mul: + ret.add(Factor( + content: "(${l.content} × ${r.content})", + value: l.value * r.value + )); + break; + case Operator.Div: + if (l.value >= r.value && r.value > 0 && l.value % r.value == 0) { + ret.add(Factor( + content: "(${l.content} / ${r.content})", + value: l.value ~/ r.value + )); + } + break; + } + } + } + return ret; +} + +List calc(List op, List numbers) { + List _calc(List op, List numbers, List acc) { + if (op.isEmpty) { + return List.from(acc); + } + + List ret = []; + var monoFactor = [Factor( + content: numbers[0].toString(), + value: numbers[0], + )]; + + switch (op[0]) { + case Operator.Mul: + ret.addAll(apply(op[0], acc, monoFactor)); + break; + case Operator.Div: + ret.addAll(apply(op[0], acc, monoFactor)); + ret.addAll(apply(op[0], monoFactor, acc)); + break; + case Operator.Sub: + ret.addAll(apply(op[0], acc, monoFactor)); + ret.addAll(apply(op[0], monoFactor, acc)); + break; + case Operator.Plus: + ret.addAll(apply(op[0], acc, monoFactor)); + break; + } + + return _calc( + op.sublist(1), + numbers.sublist(1), + ret + ); + } + + return _calc( + op, + numbers.sublist(1), + [Factor(content: numbers[0].toString(), value: numbers[0])] + ); +} + +List solutions(List numbers) { + List ret = []; + Set hashSet = {}; + + for (var ops in OpIter()) { + for (var order in orders()) { + var orderedNumbers = applyOrder(numbers, order); + var results = calc(ops, orderedNumbers); + + for (var factor in results) { + if (factor.value == 24 && !hashSet.contains(factor.content)) { + hashSet.add(factor.content); + ret.add(factor); + } + } + } + } + + return ret; +} + +class OpIter extends Iterable> { + @override + Iterator> get iterator => _OpIterator(); +} + +class _OpIterator implements Iterator> { + int _index = 0; + static const List OPTIONS = [ + Operator.Mul, + Operator.Sub, + Operator.Plus, + Operator.Div + ]; + + @override + List get current { + final f1 = OPTIONS[(_index & (3 << 4)) >> 4]; + final f2 = OPTIONS[(_index & (3 << 2)) >> 2]; + final f3 = OPTIONS[(_index & 3)]; + return [f1, f2, f3]; + } + + @override + bool moveNext() { + if (_index >= 1 << 6) { + return false; + } + _index++; + return true; + } +} + +List> orders() { + return [ + [0, 1, 2, 3], + [0, 1, 3, 2], + [0, 2, 1, 3], + [0, 2, 3, 1], + [0, 3, 1, 2], + [0, 3, 2, 1], + [1, 0, 2, 3], + [1, 0, 3, 2], + [1, 2, 0, 3], + [1, 2, 3, 0], + [1, 3, 0, 2], + [1, 3, 2, 0], + [2, 0, 1, 3], + [2, 0, 3, 1], + [2, 1, 0, 3], + [2, 1, 3, 0], + [2, 3, 0, 1], + [2, 3, 1, 0], + [3, 0, 1, 2], + [3, 0, 2, 1], + [3, 1, 0, 2], + [3, 1, 2, 0], + [3, 2, 0, 1], + [3, 2, 1, 0] + ]; +} + +List applyOrder(List numbers, List order) { + return [ + numbers[order[0]], + numbers[order[1]], + numbers[order[2]], + numbers[order[3]] + ]; +} + +void main(List args) { + List numbers = []; + + if (args.isNotEmpty) { + String input = args[0]; + for (var char in input.split('')) { + int n = int.tryParse(char); + if (n != null) { + numbers.add(n); + } + + if (numbers.length == 4) { + var sols = solutions(numbers); + var len = sols.length; + + if (len == 0) { + print('no solution for ${numbers[0]}, ${numbers[1]}, ${numbers[2]}, ${numbers[3]}'); + return; + } + + print('solutions for ${numbers[0]}, ${numbers[1]}, ${numbers[2]}, ${numbers[3]}'); + for (var s in sols) { + print(s.content); + } + print('$len solutions found'); + return; + } + } + } else { + print('empty input'); + } +} diff --git a/Task/24-game/Elena/24-game.elena b/Task/24-game/Elena/24-game.elena index d4170cfc82..b363901a03 100644 --- a/Task/24-game/Elena/24-game.elena +++ b/Task/24-game/Elena/24-game.elena @@ -3,8 +3,6 @@ import system'collections; import system'dynamic; import extensions; -// --- Expression --- - class ExpressionTree { object _tree; @@ -18,13 +16,13 @@ class ExpressionTree var node := new DynamicStruct(); ch => - $43 { node.Level := level + 1; node.Operation := mssg add } // + - $45 { node.Level := level + 1; node.Operation := mssg subtract } // - - $42 { node.Level := level + 2; node.Operation := mssg multiply } // * - $47 { node.Level := level + 2; node.Operation := mssg divide } // / - $40 { level.append(10); ^ self } // ( - $41 { level.reduce(10); ^ self } // ) - ! { + $43 : { node.Level := level + 1; node.Operation := mssg add } // + + $45 : { node.Level := level + 1; node.Operation := mssg subtract } // - + $42 : { node.Level := level + 2; node.Operation := mssg multiply } // * + $47 : { node.Level := level + 2; node.Operation := mssg divide } // / + $40 : { level.append(10); ^ self } // ( + $41 : { level.reduce(10); ^ self } // ) + ! : { node.Leaf := ch.toString().toReal(); node.Level := level + 3 }; @@ -97,8 +95,6 @@ class ExpressionTree <= readLeaves(list,_tree); } -// --- Game --- - class TwentyFourGame { object theNumbers; @@ -121,7 +117,7 @@ class TwentyFourGame help() { - console + Console .printLine("------------------------------- Instructions ------------------------------") .printLine("Four digits will be displayed.") .printLine("Enter an equation using all of those four digits that evaluates to 24") @@ -137,9 +133,9 @@ class TwentyFourGame prompt() { - theNumbers.forEach::(n){ console.print(n," ") }; + theNumbers.forEach::(n){ Console.print(n," ") }; - console.print(": ") + Console.print(": ") } resolve(expr) @@ -149,19 +145,19 @@ class TwentyFourGame var leaves := new ArrayList(); tree.readLeaves(leaves); - ifnot (leaves.ascendant().sequenceEqual(theNumbers.ascendant())) - { console.printLine("Invalid input. Enter an equation using all of those four digits. Try again."); ^ self }; + if:not (leaves.ascendant().sequenceEqual(theNumbers.ascendant())) + { Console.printLine("Invalid input. Enter an equation using all of those four digits. Try again."); ^ self }; var result := tree.Value; if (result == 24) { - console.printLine("Good work. ",expr,"=",result); + Console.printLine("Good work. ",expr,"=",result); self.newPuzzle() } else { - console.printLine("Incorrect. ",expr,"=",result) + Console.printLine("Incorrect. ",expr,"=",result) } } } @@ -178,7 +174,7 @@ extension gameOp { if (expr == "") { - console.printLine("Skipping this puzzle"); self.newPuzzle() + Console.printLine("Skipping this puzzle"); self.newPuzzle() } else { @@ -188,8 +184,7 @@ extension gameOp } catch(Exception e) { - console.printLine(e) - //console.printLine:"An error occurred. Check your input and try again." + Console.printLine:"An error occurred. Check your input and try again." } }; @@ -198,11 +193,9 @@ extension gameOp } } -// --- program --- - public program() { var game := new TwentyFourGame().help(); - while (game.prompt().playRound(console.readLine())) {} + while (game.prompt().playRound(Console.readLine())) {} } diff --git a/Task/24-game/Perl/24-game.pl b/Task/24-game/Perl/24-game.pl index 071bb8e2b8..d4dd33e728 100644 --- a/Task/24-game/Perl/24-game.pl +++ b/Task/24-game/Perl/24-game.pl @@ -25,18 +25,21 @@ while (1) { print "Expression (try ", $try++, "): "; my $entry = <>; - if (!defined $entry || $entry eq 'q') + if (!defined $entry || substr($entry,0,1) eq 'q') { say "Goodbye. Sorry you couldn't win."; last; } - $entry =~ s/\s+//g; # remove all white space + $entry =~ s/\s+//g; # remove all white space (newline is whitespace too) next if $entry eq ''; my $given_digits = join "", sort @digits; my $entry_digits = join "", sort grep { /\d/ } split(//, $entry); - if ($given_digits ne $entry_digits || # not correct digits - $entry =~ /\d\d/ || # combined digits - $entry =~ m|[-+*/]{2}| || # combined operators - $entry =~ tr|-0-9()+*/||c) # Invalid characters - { say "That's not valid"; next; } + if ($given_digits ne $entry_digits) + { say "incorrect digits"; next; } + if ($entry =~ /\d\d/) + { say "error, combined digits"; next; } + if ($entry =~ m|[-+*/]{2}|) + { say "error, combined operators"; next; } + if ($entry =~ tr|-0-9()+*/||c) + { say "invalid characters!"; next; } my $n = eval $entry; diff --git a/Task/24-game/Rust/24-game.rs b/Task/24-game/Rust/24-game.rs index bdcad8b01d..8e9e7f0ced 100644 --- a/Task/24-game/Rust/24-game.rs +++ b/Task/24-game/Rust/24-game.rs @@ -79,7 +79,13 @@ fn calculate(input: &String, list : &mut [u32;4]) -> f32{ fn main() { let mut rng = rand::thread_rng(); - let mut list :[u32;4]=[rng.gen::()%10,rng.gen::()%10,rng.gen::()%10,rng.gen::()%10]; + // each from 1 ──► 9 (inclusive) + let mut list :[u32;4]=[ + rng.gen::()%9+1, + rng.gen::()%9+1, + rng.gen::()%9+1, + rng.gen::()%9+1 + ]; println!("form 24 with using + - / * {:?}",list); //get user input diff --git a/Task/24-game/Zig/24-game.zig b/Task/24-game/Zig/24-game.zig new file mode 100644 index 0000000000..4c224f1030 --- /dev/null +++ b/Task/24-game/Zig/24-game.zig @@ -0,0 +1,153 @@ +const std = @import("std"); +const rand = std.Random; +// (hint: errors cannot be handled at comptime) +var stdout: std.fs.File.Writer = undefined; +var stdin: std.fs.File.Reader = undefined; + +fn opType(x: u8) i32 { + return switch (x) { + '-', '+' => 1, + '/', '*' => 2, + '(', ')' => -1, + else => 0, + }; +} + +fn toRpn(allocator: std.mem.Allocator, input: []const u8) ![]u8 { + var rpnString = std.ArrayList(u8).init(allocator); + defer rpnString.deinit(); + + var rpnStack = std.ArrayList(u8).init(allocator); + defer rpnStack.deinit(); + + var lastToken: u8 = '#'; + + for (input) |token| { + if (token >= '1' and token <= '9') { + try rpnString.append(token); + } else if (opType(token) == 0) { + continue; + } else if (opType(token) > opType(lastToken) or token == '(') { + try rpnStack.append(token); + lastToken = token; + } else { + while (rpnStack.items.len > 0) { + const top = rpnStack.pop().?; + if (top == '(') { + break; + } + try rpnString.append(top); + } + if (token != ')') { + try rpnStack.append(token); + } + } + } + + while (rpnStack.items.len > 0) { + try rpnString.append(rpnStack.pop().?); + } + + if (rpnString.items.len > 0) { + try stdout.print("your formula results in {s}\n", .{rpnString.items}); + } else { + stdout.print("no input available.\n", .{}) catch {}; + } + + return rpnString.toOwnedSlice(); +} + +fn calculate(input: []const u8, list: *[4]u32) f32 { + var stack = std.ArrayList(f32).init(std.heap.page_allocator); + defer stack.deinit(); + + var accumulator: f32 = 0.0; + + for (input) |token| { + if (token >= '1' and token <= '9') { + const digit = @as(u32, token - '0'); + + // Find and mark the used digit + var found = false; + for (list, 0..) |val, idx| { + if (val == digit) { + list[idx] = 10; + found = true; + break; + } + } + + if (!found) { + stdout.print(" invalid digit: {d} \n", .{digit}) catch {}; + } + + stack.append(accumulator) catch {}; + accumulator = @floatFromInt(digit); + } else { + const a = stack.pop().?; + + accumulator = switch (token) { + '-' => a - accumulator, + '+' => a + accumulator, + '/' => a / accumulator, + '*' => a * accumulator, + else => accumulator, // NOP + }; + } + } + + stdout.print("your formula results in {d}\n", .{accumulator}) catch {}; + return accumulator; +} + +pub fn main() !void { + stdout = std.io.getStdOut().writer(); + stdin = std.io.getStdIn().reader(); + var prng = rand.DefaultPrng.init(@as(u64, @intCast(std.time.timestamp()))); + const random = prng.random(); + // only values from 1 --> 9 (inclusive) + var list = [_]u32{ + @mod(random.int(u32), 9) + 1, + @mod(random.int(u32), 9) + 1, + @mod(random.int(u32), 9) + 1, + @mod(random.int(u32), 9) + 1, + }; + + try stdout.print("form 24 with using + - / * {d} {d} {d} {d}\n", .{ list[0], list[1], list[2], list[3] }); + + // Get user input + var buffer: [1024]u8 = undefined; + const input = try stdin.readUntilDelimiterOrEof(buffer[0..], '\n') orelse ""; + + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + const allocator = arena.allocator(); + + // Convert to RPN + const rpnInput = try toRpn(allocator, input); + if (rpnInput.len == 0) { + stdout.print("exit.\n", .{}) catch {}; + return; + } + + const result = calculate(rpnInput, &list); + + var allUsed = true; + for (list) |val| { + if (val != 10) { + allUsed = false; + break; + } + } + + if (allUsed) { + try stdout.print("and you used all numbers\n", .{}); + if (result == 24.0) { + try stdout.print("you won\n", .{}); + } else { + try stdout.print("but your formula doesn't result in 24\n", .{}); + } + } else { + try stdout.print("you didn't use all the numbers\n", .{}); + } +} diff --git a/Task/4-rings-or-4-squares-puzzle/EasyLang/4-rings-or-4-squares-puzzle.easy b/Task/4-rings-or-4-squares-puzzle/EasyLang/4-rings-or-4-squares-puzzle.easy index f2e05dc87f..22e54e305a 100644 --- a/Task/4-rings-or-4-squares-puzzle/EasyLang/4-rings-or-4-squares-puzzle.easy +++ b/Task/4-rings-or-4-squares-puzzle/EasyLang/4-rings-or-4-squares-puzzle.easy @@ -1,12 +1,10 @@ func ok v t[] . for h in t[] - if v = h - return 0 - . + if v = h : return 0 . return 1 . -proc four lo hi uni show . . +proc four lo hi uni show . # subr bf for f = lo to hi diff --git a/Task/99-bottles-of-beer/Elena/99-bottles-of-beer.elena b/Task/99-bottles-of-beer/Elena/99-bottles-of-beer.elena index e88bc758db..f80cd1b687 100644 --- a/Task/99-bottles-of-beer/Elena/99-bottles-of-beer.elena +++ b/Task/99-bottles-of-beer/Elena/99-bottles-of-beer.elena @@ -31,5 +31,5 @@ public program() { var bottles := 99; - bottles.bottleEnumerator().forEach(printingLn) + bottles.bottleEnumerator().forEach(PrintingLn) } diff --git a/Task/99-bottles-of-beer/Factor/99-bottles-of-beer-1.factor b/Task/99-bottles-of-beer/Factor/99-bottles-of-beer-1.factor new file mode 100644 index 0000000000..55688df8a7 --- /dev/null +++ b/Task/99-bottles-of-beer/Factor/99-bottles-of-beer-1.factor @@ -0,0 +1,6 @@ +USE: math.parser +100 +[ dup 1 - [ >dec " bottles of beer" append [ " on the wall" append ] keep ] bi@ + "Take one down, pass it around" -rot + first CHAR: - = [ 2drop "..." "why's all the rum gone??" ] when ! if leading character is "-" then replace with new string + 4array "\n" join print nl ] each diff --git a/Task/99-bottles-of-beer/Factor/99-bottles-of-beer.factor b/Task/99-bottles-of-beer/Factor/99-bottles-of-beer-2.factor similarity index 100% rename from Task/99-bottles-of-beer/Factor/99-bottles-of-beer.factor rename to Task/99-bottles-of-beer/Factor/99-bottles-of-beer-2.factor diff --git a/Task/99-bottles-of-beer/Uxntal/99-bottles-of-beer.uxnatl b/Task/99-bottles-of-beer/Uxntal/99-bottles-of-beer.uxnatl index 2d10b5487c..868c8dd512 100644 --- a/Task/99-bottles-of-beer/Uxntal/99-bottles-of-beer.uxnatl +++ b/Task/99-bottles-of-beer/Uxntal/99-bottles-of-beer.uxnatl @@ -1,63 +1,73 @@ -( uxncli 99bottles.rom ) +%\n { 0a } %\s { 20 } %\0 { 00 } +%newline { [ LIT2 \n -Console/write ] DEO } +%plural { [ LIT2 "s -Console/write ] DEO } -|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 +|18 @Console/write -|0100 ( -> ) - #63 &loop - DUP - [ LIT2 0a -Console/write ] DEO - #01 EQUk ?&done - POP #01 SUB - !&loop - &done BRK +|100 -@ ( num -- ) - DUP ;dict/wall - DUP [ LIT2 0a -Console/write ] DEO - ;dict/take - #01 SUB ;dict/wall ! +#63 +&loop + DUP print/verse + newline + #01 EQUk ?/done + POP #01 SUB + !/done -@ ( num -- ) - DUP #00 EQU ?&zero - DUP #01 EQU ?&one - ;dict/bottle - [ LIT2 "s -Console/write ] DEO - !&end + &done + POP2 - &one ( num -- ) - ;dict/bottle - !&end - &zero ( num -- ) - POP ;dict/no-more - ;dict/bottle - [ LIT2 "s -Console/write ] DEO - ( >> ) - &end - ;dict/of-beer +BRK + +@print/verse ( num -- ) + DUP /bottle ;msgs/wall /str + DUP /bottle newline + ;msgs/take /str + #01 SUB /bottle ;msgs/wall !/str + +@print/bottle ( num -- ) + DUP #00 EQU ?/bottle/zero + DUP #01 EQU ?/bottle/one + /dec ;msgs/bottle /str + plural + !/bottle/end + + &bottle/one ( num -- ) + /dec ;msgs/bottle /str + !/bottle/end + + &bottle/zero ( num -- ) + POP ;msgs/no-more /str + ;msgs/bottle /str + plural ( >> ) -@ ( str -- ) - &loop - LDAk .Console/write DEO - INC2 LDAk ?&loop + &bottle/end + ;msgs/of-beer + ( >> ) + +@print/str ( str -- ) + LDAk .Console/write DEO + INC2 LDAk ?/str POP2 JMP2r -@ ( byte -- ) - DUP #64 DIV /try - DUP #0a DIV /try +@print/dec ( byte -- ) + DUP #64 DIV /dec/try + DUP #0a DIV /dec/try ( >> ) -@ ( num -- ) - #0a DIVk MUL SUB - [ LIT "0 ] ADD .Console/write DEO - JMP2r + &dec/try/num ( num -- ) + #0a DIVk MUL SUB + [ LIT "0 ] ADD .Console/write DEO + JMP2r - &try ( num -- ) - DUP ? + &dec/try ( num -- ) + DUP ?/dec/try/num POP JMP2r -@dict &no-more "No 20 "more $1 - &bottle 20 "bottle $1 - &of-beer 20 "of 20 "beer 20 $1 - &wall "on 20 "the 20 "wall 0a $1 - &take "Take 20 "one 20 "down, 20 "pass 20 "it 20 "around 0a $1 +@msgs [ + &no-more "No \s "more \0 + &bottle \s "bottle \0 + &of-beer \s "of \s "beer \s \0 + &wall "on \s "the \s "wall \n \0 + &take "Take \s "one \s "down, \s "pass \s "it \s "around \n \0 ] diff --git a/Task/A+B/Ballerina/a+b.ballerina b/Task/A+B/Ballerina/a+b.ballerina new file mode 100644 index 0000000000..7c90b9d2f5 --- /dev/null +++ b/Task/A+B/Ballerina/a+b.ballerina @@ -0,0 +1,16 @@ +import ballerina/io; + +public function main() returns error? { + while true { + io:print("Enter two integers separated by a space : "); + string[] s = re ` `.split(io:readln()); + if s.length() < 2 { + io:println("Insufficient numbers, try again"); + } else { + int a = check int:fromString(s[0]); + int b = check int:fromString(s[1]); + io:println("Their sum is ", a + b, "."); + break; + } + } +} diff --git a/Task/A+B/Elena/a+b-1.elena b/Task/A+B/Elena/a+b-1.elena index a4c98a1213..afa03ef6c5 100644 --- a/Task/A+B/Elena/a+b-1.elena +++ b/Task/A+B/Elena/a+b-1.elena @@ -2,8 +2,8 @@ import extensions; public program() { - var A := Integer.new(); - var B := Integer.new(); + var A := Integer.new(); + var B := Integer.new(); - console.loadLine(A,B).printLine(A + B) + Console.loadLine(A,B).printLine(A + B) } diff --git a/Task/A+B/Elena/a+b-2.elena b/Task/A+B/Elena/a+b-2.elena index 8097b76574..b79d01d958 100644 --- a/Task/A+B/Elena/a+b-2.elena +++ b/Task/A+B/Elena/a+b-2.elena @@ -3,7 +3,7 @@ import extensions; public program() { - console.printLine(console.readLine() + Console.printLine(Console.readLine() .split() .selectBy(mssgconst toInt[1]) .summarize()) diff --git a/Task/A+B/REXX/a+b-1.rexx b/Task/A+B/REXX/a+b-1.rexx deleted file mode 100644 index 46a34f359e..0000000000 --- a/Task/A+B/REXX/a+b-1.rexx +++ /dev/null @@ -1,4 +0,0 @@ -/*REXX program obtains two numbers from the input stream (the console), shows their sum.*/ -parse pull a b /*obtain two numbers from input stream.*/ -say a+b /*display the sum to the terminal. */ - /*stick a fork in it, we're all done. */ diff --git a/Task/A+B/REXX/a+b-2.rexx b/Task/A+B/REXX/a+b-2.rexx deleted file mode 100644 index 064640ab38..0000000000 --- a/Task/A+B/REXX/a+b-2.rexx +++ /dev/null @@ -1,4 +0,0 @@ -/*REXX program obtains two numbers from the input stream (the console), shows their sum.*/ -parse pull a b /*obtain two numbers from input stream.*/ -say (a+b) / 1 /*display normalized sum to terminal. */ - /*stick a fork in it, we're all done. */ diff --git a/Task/A+B/REXX/a+b-3.rexx b/Task/A+B/REXX/a+b-3.rexx deleted file mode 100644 index 774178e64d..0000000000 --- a/Task/A+B/REXX/a+b-3.rexx +++ /dev/null @@ -1,6 +0,0 @@ -/*REXX program obtains two numbers from the input stream (the console), shows their sum.*/ -numeric digits 300 /*the default is nine decimal digits.*/ -parse pull a b /*obtain two numbers from input stream.*/ -z= (a+b) / 1 /*add and normalize sum, store it in Z.*/ -say z /*display normalized sum Z to terminal.*/ - /*stick a fork in it, we're all done. */ diff --git a/Task/A+B/REXX/a+b-4.rexx b/Task/A+B/REXX/a+b-4.rexx deleted file mode 100644 index 05e988dfb5..0000000000 --- a/Task/A+B/REXX/a+b-4.rexx +++ /dev/null @@ -1,11 +0,0 @@ -/*REXX program obtains some numbers from the input stream (the console), shows their sum*/ -numeric digits 1000 /*just in case the user gets ka-razy. */ -say 'enter some numbers to be summed:' /*display a prompt message to terminal.*/ -parse pull y /*obtain all numbers from input stream.*/ -many= words(y) /*obtain the number of numbers entered.*/ -$= 0 /*initialize the sum to zero. */ - do j=1 for many /*process each of the numbers. */ - $= $ + word(y, j) /*add one number to the sum. */ - end /*j*/ - /*stick a fork in it, we're all done. */ -say 'sum of ' many " numbers = " $/1 /*display normalized sum $ to terminal.*/ diff --git a/Task/A+B/REXX/a+b-5.rexx b/Task/A+B/REXX/a+b-5.rexx deleted file mode 100644 index 3aed91ea3f..0000000000 --- a/Task/A+B/REXX/a+b-5.rexx +++ /dev/null @@ -1,8 +0,0 @@ -/*REXX program obtains some numbers from the input stream (the console), shows their sum*/ -numeric digits 1000 /*just in case the user gets ka-razy. */ -say 'enter some numbers to be summed:' /*display a prompt message to terminal.*/ -parse pull y /*obtain all numbers from input stream.*/ -y=space(y) -y=translate(y,'+',' ') -Interpret 's='y -say 'sum of ' many " numbers = " s/1 /*display normalized sum s to terminal.*/ diff --git a/Task/A+B/REXX/a+b.rexx b/Task/A+B/REXX/a+b.rexx new file mode 100644 index 0000000000..928b14cfbb --- /dev/null +++ b/Task/A+B/REXX/a+b.rexx @@ -0,0 +1,27 @@ +-- 1 Jun 2025 +include Settings + +say 'A+B' +say version +say +do forever + call Charout, 'REXX ' + pull x + if x = '' then + leave + parse var x a b + say + say 'As given...' + say 'A =' a + say 'B =' b + say 'A+B =' a+b + say + say 'Normalized...' + say 'A =' a/1 + say 'B =' b/1 + say 'A+B =' (a+b)/1 + say +end +exit + +include Abend diff --git a/Task/ABC-problem/Ballerina/abc-problem.ballerina b/Task/ABC-problem/Ballerina/abc-problem.ballerina new file mode 100644 index 0000000000..0428dff997 --- /dev/null +++ b/Task/ABC-problem/Ballerina/abc-problem.ballerina @@ -0,0 +1,32 @@ +import ballerina/io; + +function r(string word, string[] bl) returns boolean { + if word == "" { return true; } + int c = word[0].toBytes()[0] | 32; + foreach int i in 0.. len w$[] cnt += 1 return diff --git a/Task/ABC-problem/Elena/abc-problem.elena b/Task/ABC-problem/Elena/abc-problem.elena index 99216ac706..2525c26eed 100644 --- a/Task/ABC-problem/Elena/abc-problem.elena +++ b/Task/ABC-problem/Elena/abc-problem.elena @@ -41,6 +41,6 @@ public program() words.forEach::(word) { - console.printLine("can make '",word,"' : ",word.canMakeWordFrom(blocks)); + Console.printLine("can make '",word,"' : ",word.canMakeWordFrom(blocks)); } } diff --git a/Task/ADFGVX-cipher/C-sharp/adfgvx-cipher.cs b/Task/ADFGVX-cipher/C-sharp/adfgvx-cipher.cs new file mode 100644 index 0000000000..3f4f47932f --- /dev/null +++ b/Task/ADFGVX-cipher/C-sharp/adfgvx-cipher.cs @@ -0,0 +1,117 @@ +using System.Diagnostics; + +const string cypher = "ADFGVX"; +var N = cypher.Length; +var size = N * N; +const string symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; +Debug.Assert(size == symbols.Length); +var square = new int[size]; + +for (var i = 0; i < size; i++) +{ + var j = Random.Shared.Next(i + 1); + square[i] = square[j]; + square[j] = i; +} + +Console.WriteLine($"{N} x {N} Polybius square:"); +Console.WriteLine(); +Console.WriteLine($" | {string.Join(' ', cypher.AsEnumerable())}"); +Console.WriteLine(new string('-', 2 * N + 3)); + +for (var row = 0; row < N; row++) +{ + Console.Write($"{cypher[row]} |"); + + for (var col = 0; col < N; col++) + { + Console.Write($" {symbols[square[col + row * N]]}"); + } + + Console.WriteLine(); +} + +static bool IsSuitableTranspositionKey(string s) => + s.Length >= 7 && s.Length <= 12 && s.Length == s.Distinct().Count() && s.All(symbols.ToLowerInvariant().Contains); + +var keys = File.ReadAllLines("unixdict.txt").Where(IsSuitableTranspositionKey).ToArray(); +var key = keys[Random.Shared.Next(keys.Length)].ToUpperInvariant(); +Console.WriteLine(); +Console.WriteLine($"The key is {key}"); +var plaintext = "ATTACKAT1200AM"; +Console.WriteLine($"Plaintext: {plaintext}"); + +string Encrypt(string plaintext, string key, int[] square) +{ + // Create a lookup table from symbol to fragment + var map = (from i in Enumerable.Range(0, size) + let k = square[i] + let code = cypher[i / N] + "" + cypher[i % N] + select (k, code)) + .ToDictionary(kc => symbols[kc.k], kc => kc.code); + + // Map the plaintext to fragments + var e = string.Join("", plaintext.Select(c => map[c])); + + // Determine number of rows + var K = key.Length; + var rows = (e.Length + K - 1) / K; + + // Pad with spaces + e += new string(' ', rows * K - e.Length); + + // Sort the key + var order = string.Join("", key.OrderBy(c => c)).Select(c => key.IndexOf(c)).ToArray(); + + // Reorder the fragments. + e = string.Join("", Enumerable.Range(0, K * rows).Select(i => e[(i / K) * K + order[i % K]])); + + // Transpose + e = new([.. from col in Enumerable.Range(0, K) + from row in Enumerable.Range(0, rows) + select e[row * K + col]]); + + // Read off each column. + return string.Join(" ", Enumerable.Range(0, K).Select(col => e.Substring(col * rows, rows).Trim())); +} + +var encrypted = Encrypt(plaintext, key, square); +Console.WriteLine($"Encrypted: {encrypted}"); + +string Decrypt(string encrypted, string key, int[] square) +{ + // Create a lookup table from fragment to symbol + var map = (from i in Enumerable.Range(0, size) + let k = square[i] + let code = cypher[i / N] + "" + cypher[i % N] + select (k, code)) + .ToDictionary(kc => kc.code, kc => symbols[kc.k]); + + // Split into columns + var cols = encrypted.Split(' '); + + // Determine number of rows + var K = key.Length; + var rows = cols.Max(c => c.Length); + + // Pad each column + cols = [.. cols.Select(c => c.PadRight(rows))]; + + // Transpose + string e = new([.. from row in Enumerable.Range(0, rows) + from col in Enumerable.Range(0, K) + select cols[col][row]]); + + // Sort the key + var sorted = string.Join("", key.OrderBy(c => c)); + var order = key.Select(c => sorted.IndexOf(c)).ToArray(); + + // Reorder the fragments + e = string.Join("", Enumerable.Range(0, K * rows).Select(i => e[(i / K) * K + order[i % K]])).Trim(); + + // Map the fragments to plaintext + return string.Join("", Enumerable.Range(0, e.Length / 2).Select(i => map[e.Substring(2 * i, 2)])); +} + +var decrypted = Decrypt(encrypted, key, square); +Console.WriteLine($"Decrypted: {decrypted}"); diff --git a/Task/ADFGVX-cipher/JavaScript/adfgvx-cipher.js b/Task/ADFGVX-cipher/JavaScript/adfgvx-cipher.js new file mode 100644 index 0000000000..0bdfe6eb1a --- /dev/null +++ b/Task/ADFGVX-cipher/JavaScript/adfgvx-cipher.js @@ -0,0 +1,134 @@ +class ADFGVX { + /** The WWI German ADFGVX cipher. */ + constructor(spoly, k, alph = 'ADFGVX') { + this.polybius = spoly.toUpperCase().split(''); + this.pdim = Math.floor(Math.sqrt(this.polybius.length)); + this.key = k.toUpperCase().split(''); + this.keylen = this.key.length; + this.alphabet = alph.split(''); + const pairs = []; + for (let i = 0; i < this.alphabet.length; i++) { + for (let j = 0; j < this.alphabet.length; j++) { + pairs.push(this.alphabet[i] + this.alphabet[j]); + } + } + this.encode = {}; + for (let i = 0; i < this.polybius.length; i++) { + this.encode[this.polybius[i]] = pairs[i]; + } + this.decode = {}; + for (const k in this.encode) { + this.decode[this.encode[k]] = k; + } + } + + encrypt(msg) { + /** Encrypt with the ADFGVX cipher. */ + const chars = []; + for (const c of msg.toUpperCase()) { + if (this.polybius.includes(c)) { + chars.push(this.encode[c]); + } + } + const flatChars = chars.join('').split(''); + const colvecs = []; + for (let i = 0; i < this.keylen; i++) { + const currentCol = []; + for (let j = i; j < flatChars.length; j += this.keylen) { + currentCol.push(flatChars[j]); + } + colvecs.push([this.key[i], currentCol]); + } + + colvecs.sort((a, b) => a[0].localeCompare(b[0])); + + let result = ''; + for (const a of colvecs) { + result += a[1].join(''); + } + return result; + } + + decrypt(cod) { + /** Decrypt with the ADFGVX cipher. Does not depend on spacing of encoded text */ + const chars = []; + for (const c of cod) { + if (this.alphabet.includes(c)) { + chars.push(c); + } + } + + const sortedkey = [...this.key].sort(); + const order = []; + for (const ch of sortedkey) { + order.push(this.key.indexOf(ch)); + } + const originalorder = []; + for (const ch of this.key) { + originalorder.push(sortedkey.indexOf(ch)); + } + + const base = Math.floor(chars.length / this.keylen); + const extra = chars.length % this.keylen; + const strides = order.map((_, i) => base + (extra > i ? 1 : 0)); + const starts = [0]; + let sum = 0; + for (let i = 0; i < strides.length - 1; i++) { + sum += strides[i]; + starts.push(sum); + } + const ends = starts.map((start, i) => start + strides[i]); + const cols = originalorder.map(i => chars.slice(starts[i], ends[i])); + + const pairs = []; + for (let i = 0; i < Math.floor((chars.length - 1) / this.keylen) + 1; i++) { + for (let j = 0; j < this.keylen; j++) { + if (i * this.keylen + j < chars.length) { + pairs.push(cols[j][i]); + } + } + } + + let decoded = ''; + for (let i = 0; i < pairs.length; i += 2) { + decoded += this.decode[pairs[i] + pairs[i + 1]]; + } + return decoded; + } +} + +// Helper function to shuffle an array (Fisher-Yates shuffle) +function shuffle(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +} + + +async function main() { + const PCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.split(''); + shuffle(PCHARS); + const POLYBIUS = PCHARS.join(''); + + // Simulate reading from unixdict.txt (replace with your actual file reading method if needed) + // For demonstration purposes, using a hardcoded word list: + const WORDS = ['ABDEFGHIK', 'JLMNOPQRS', 'TUVWXYZ01', '23456789']; + const KEY = WORDS[Math.floor(Math.random() * WORDS.length)]; + + + const SECRET = new ADFGVX(POLYBIUS, KEY); + const MESSAGE = 'ATTACKAT1200AM'; + + console.log(`Polybius: ${POLYBIUS}, key: ${KEY}`); + console.log('Message: ', MESSAGE); + + const ENCODED = SECRET.encrypt(MESSAGE); + const DECODED = SECRET.decrypt(ENCODED); + + console.log('Encoded: ', ENCODED); + console.log('Decoded: ', DECODED); +} + +main(); diff --git a/Task/ADFGVX-cipher/M2000-Interpreter/adfgvx-cipher.m2000 b/Task/ADFGVX-cipher/M2000-Interpreter/adfgvx-cipher.m2000 new file mode 100644 index 0000000000..1cc6519280 --- /dev/null +++ b/Task/ADFGVX-cipher/M2000-Interpreter/adfgvx-cipher.m2000 @@ -0,0 +1,116 @@ +Module CheckADFGVX_Cipher { + Class cipher { + Private: + buffer a as byte*36 + b="ADFGVX" + key="ABCDEFGHIJK" + orderkey="ABCDEFGHIJK" + map=list + map2=list + module preparemaps { + for i=0 to 5 + jj=0 + for j=i*6 to j+5 + .map(chr$(.a[j]))=mid$(.b, i+1,1)+mid$(.b,jj+1, 1) + .map2(mid$(.b, i+1,1)+mid$(.b,jj+1, 1))=chr$(.a[j]) + jj++ + next + next + } + Public: + Module SetRandom (&returnvalue) { + return .a, 0:=str$("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + for i=1 to 100 + c=random(0, 35):d=c + while c=d {d=random(0, 35)} + byte o=.a[c] + .a[c]<=.a[d] + .a[d]<=o + next + returnvalue=chr$(eval$(.a)) ' convert to UTF16LE + .preparemaps + } + Module SetSpecific (that$){ + return .a, 0:=str$(Ucase$(that$)) + .preparemaps + } + Module SetKey (.key as string) { + .key<=ucase$(.key) + if len(.key)<7 or len(.key)>12 then Error "Key has not proper length" + if filter$(.key, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")<>"" then + Error "Key has bad letters" + end if + dim aa(1 to len(.key)) + for i=1 to len(.key):aa(i)=mid$(.key,i,1):next + .orderkey<=aa()#sort()#str$("") + } + Module Display { + Print "The 6 x 6 Polybius square:" + Print " | A D F G V X" + Print "---------------" + for i=0 to 5 + Print mid$(.b,i+1,1)+" | "; + jj=0 + for j=i*6 to j+5 + print chr$(.a[j]);" "; + jj++ + next + print + next + Print "Key:";.key + } + Function Encrypt(p as string) { + crypted="" + for i=1 to len(p) + crypted+=.map$(mid$(p,i,1)) + next + m=1 + encrypted="" + For i = 1 To Len(.key) + ch = Mid$(.orderkey, i, 1) + For j = Instr(.key, ch) - 1 To Len(crypted) - 1 Step Len(.key) + encrypted += Mid$(crypted, j + 1, 1) + if m mod 5=0 then encrypted += " " + m++ + Next + Next + =encrypted + } + Function Decrypt(p as string) { + p=filter$(p, " ") + decrypted="" + m=1 + dim b$(len(p)) + For i = 1 To Len(.key) + ch = Mid$(.orderkey, i, 1) + For j = Instr(.key, ch) - 1 To Len(p) - 1 Step Len(.key) + b$(j)=mid$(p, m, 1) + m++ + Next + Next + for i=0 to len(b$())-1 step 2 + decrypted+=.map2(b$(i)+b$(i+1)) + next + =decrypted + } + } + ADFGVX=cipher() + for ADFGVX { + .SetSpecific "A9GKMF1DQRSBVX8Z0WTEJLOPY5U4CN2H76I3" + .SetKey "volcanism" + .Display + encode=.Encrypt("ATTACKAT1200AM") + Print "Encoded: ";encode + Print "Decoded: ";.Decrypt(encode) + Rem { ' using randomblock + thisblock="" + .SetRandom &thisblock + Print "Random Block:";thisblock + .Display + encode=.Encrypt("ATTACKAT1200AM") + Print "Encoded: ";encode + Print "Decoded: ";.Decrypt(encode) + } + } +} +CheckADFGVX_Cipher diff --git a/Task/AKS-test-for-primes/Ballerina/aks-test-for-primes.ballerina b/Task/AKS-test-for-primes/Ballerina/aks-test-for-primes.ballerina new file mode 100644 index 0000000000..575c645a5f --- /dev/null +++ b/Task/AKS-test-for-primes/Ballerina/aks-test-for-primes.ballerina @@ -0,0 +1,58 @@ +import ballerina/io; + +int[] e = "²³⁴⁵⁶⁷".toCodePointInts(); + +function bc(int p) returns int[] { + int[] c = []; + c.setLength(p + 1); + int r = 1; + int half = p / 2; + foreach int i in 0...half { + c[i] = r; + c[p - i] = r; + r = r * (p - i) / (i + 1); + } + foreach int i in int:range(p - 1, -1, -2) { + c[i] = -c[i]; + } + return c; +} + +function pp(int[] c) returns string|error { + if c.length() == 1 { return c[0].toString(); } + int p = c.length() - 1; + string s = ""; + if c[p] != 1 { s = c[p].toString(); } + foreach int i in int:range(p, 0, -1) { + s += "x"; + if i != 1 { s += check string:fromCodePointInt(e[i - 2]); } + int d = c[i - 1]; + if d < 0 { + s += " - " + (-d).toString(); + } else { + s += " + " + d.toString(); + } + } + return s; +} + +function aks(int p) returns boolean { + int[] c = bc(p); + c[p] -= 1; + c[0] += 1; + foreach int d in c { + if d % p != 0 { return false; } + } + return true; +} + +public function main() { + foreach int p in 0...7 { + io:println(p, ": ", pp(bc(p))); + } + io:println("\nAll primes under 50:"); + foreach int p in 2...49 { + if aks(p) { io:print(p, " "); } + } + io:println(); +} diff --git a/Task/AKS-test-for-primes/Elena/aks-test-for-primes.elena b/Task/AKS-test-for-primes/Elena/aks-test-for-primes.elena index d1ab382bf3..714dc0f0ae 100644 --- a/Task/AKS-test-for-primes/Elena/aks-test-for-primes.elena +++ b/Task/AKS-test-for-primes/Elena/aks-test-for-primes.elena @@ -45,7 +45,7 @@ singleton AksTest while(i != 0) { i -= 1; - console.print("+",c[i],"x^",i) + Console.print("+",c[i],"x^",i) } } } @@ -55,18 +55,18 @@ public program() for (int n := 0; n < 10; n += 1) { AksTest.coef(n); - console.print("(x-1)^",n," = "); + Console.print("(x-1)^",n," = "); AksTest.show(n); - console.printLine() + Console.printLine() }; - console.print("Primes:"); + Console.print("Primes:"); for (int n := 1; n <= 63; n += 1) { if (AksTest.is_prime(n)) { - console.print(n," ") + Console.print(n," ") } }; - console.printLine().readChar() + Console.printLine().readChar() } diff --git a/Task/AKS-test-for-primes/REXX/aks-test-for-primes-2.rexx b/Task/AKS-test-for-primes/REXX/aks-test-for-primes-2.rexx index f2aa00be60..1942f69672 100644 --- a/Task/AKS-test-for-primes/REXX/aks-test-for-primes-2.rexx +++ b/Task/AKS-test-for-primes/REXX/aks-test-for-primes-2.rexx @@ -1,43 +1,91 @@ -/*REXX program calculates primes via the Agrawal─Kayal─Saxena (AKS) primality test.*/ -parse arg Z . /*obtain optional argument from the CL.*/ -if Z=='' | Z=="," then Z= 200 /*Not specified? Then use the default.*/ -OZ=Z; tell= Z<0; Z= abs(Z) /*Is Z negative? Then show expression.*/ -numeric digits max(9, Z % 3) /*define a dynamic # of decimal digits.*/ -call AKS /*invoke the AKS funtion for coef. bld.*/ -if left(OZ,1)=='+' then do; say Z isAksp(); exit /*display if Z is or isn't a prime.*/ - end /* [↑] call isAKSp if Z has leading +.*/ -say; say "primes found:" # /*display the prime number list. */ -say; if \datatype(#, 'W') then exit /* [↓] the digit length of a big coef.*/ -say 'Found ' words(#) " primes and the largest coefficient has " length(@.pm.h) @dd -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -AKS: $.0= '-'; $.1= "+"; @. = 1 /*$.x: sign char; default coefficients.*/ - q.= 1; q.1= 0; q.4= 0 /*sparse array for faster comparisons. */ - #=; L= length(Z) /*define list of prime numbers (so far)*/ - do p=3 for Z; pm=p - 1; pp=p + 1 /*PM & PP: used as a coding convenience*/ - do m=2 for pp % 2 - 1; mm=m - 1 /*calculate coefficients for a power. */ - @.p.m= @.pm.mm + @.pm.m; h=pp - m /*calculate left side of coefficients*/ - @.p.h= @.p.m /* " right " " " */ - end /*m*/ /* [↑] The M DO loop creates both */ - end /*p*/ /* sides in the same loop. */ - if tell then say '(x-1)^'right(0, L)": 1" /*possibly display the first expression*/ - @dd= 'decimal digits.' /* [↓] test for primality by division.*/ - do n=2 for Z; nh=n % 2; d= n - 1 /*create expressions; find the primes.*/ - do k=3 to nh while @.n.k//d == 0 /*are coefficients divisible by N-1 ? */ - end /*k*/ /* [↑] skip the 1st & 2nd coefficients*/ - if k>nh then if q.d then #= # d /*add a number to the prime list. */ - if \tell then iterate /*Don't tell? Don't show expressions.*/ - y= '(x-1)^'right(d, L)":" /*define the 1st part of the expression*/ - s=1 /*S: is the sign indicator (-1│+1).*/ - do j=n for n-1 by -1 /*create the higher powers first. */ - if j==2 then xp= 'x' /*if power=1, then don't show the power*/ - else xp= 'x^' || j-1 /* ··· else show power with ^ */ - if j==n then y=y xp /*no sign (+│-) for the 1st expression.*/ - else y=y $.s || @.n.j'∙'xp /*build the expression with sign (+|-).*/ - s= \s /*flip the sign for the next expression*/ - end /*j*/ /* [↑] the sign (now) is either 0 │ 1,*/ - say y $.s'1' /*just show the first N expressions, */ - end /*n*/ /* [↑] ··· but only for negative Z. */ - if #=='' then #= "none"; return # /*if null, return "none"; else return #*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isAKSp: if z==word(#,words(#)) then return ' is a prime.'; else return " isn't a prime." +-- 22 Mar 2025 +include Settings + +say 'AKS TEST FOR PRIMES' +say version +say +arg p +if p = '' then + p = 10 +numeric digits Max(10,Abs(p)%3) +call Combis p +call Polynomials p +call Showprimes p +exit + +Combis: +procedure expose comb. +arg p +call Time('r') +if p > 0 then + say 'Combinations up to' p'...' +else + say 'Combinations for' Abs(p)'...' +say Combinations(p) 'combinations generated' +say Format(Time('e'),,3) 'seconds' +say +return + +Polynomials: +procedure expose poly. comb. work. prim. +arg p +call Time('r') +say 'Polynomials...' +if p < 0 then + b = Abs(p) +else + b = 0 +p = Abs(p); prim. = 0; n = 0 +do i = b to p + a = Ppow('1 -1',i) + if i < 11 then + say '(x-1)^'i '=' Plst2form(Parr2lst()) + s = 1 + do j = 2 to poly.0-1 + a = poly.coef.j + if a//i > 0 then do + s = 0 + leave j + end + end + if s = 1 then do + if i > 1 then do + n = n+1 + prim.n = i + end + end +end +prim.0 = n +say Format(Time('e'),,3) 'seconds' +say +return + +Showprimes: +procedure expose prim. +arg p +call Time('r') +say 'Primes...' +if p < 0 then do + p = Abs(p) + if prim.0 > 0 then + say p 'is prime' + else + say p 'is not prime' +end +else do + do i = 1 to prim.0 + call Charout ,Right(prim.i,5) + if i//20 = 0 then + say + end + say +end +say Format(Time('e'),,3) 'seconds' +say +return + +include Functions +include Numbers +include Polynomial +include Sequences +include Abend diff --git a/Task/AKS-test-for-primes/REXX/aks-test-for-primes-3.rexx b/Task/AKS-test-for-primes/REXX/aks-test-for-primes-3.rexx deleted file mode 100644 index 77862e7896..0000000000 --- a/Task/AKS-test-for-primes/REXX/aks-test-for-primes-3.rexx +++ /dev/null @@ -1,89 +0,0 @@ -include Settings - -say version -say 'AKS-test for primes'; say -arg p -if p = '' then - p = 10 -numeric digits Max(10,Abs(p)%3) -call Combis p -call Polynomials p -call Showprimes p -exit - -Combis: -procedure expose comb. -arg p -call Time('r') -if p > 0 then - say 'Combinations up to' p'...' -else - say 'Combinations for' Abs(p)'...' -say Combinations(p) 'combinations generated' -say Format(Time('e'),,3) 'seconds' -say -return - -Polynomials: -procedure expose poly. comb. work. prim. -arg p -call Time('r') -say 'Polynomials...' -if p < 0 then - b = Abs(p) -else - b = 0 -p = Abs(p); prim. = 0; n = 0 -do i = b to p - a = Ppow('1 -1',i) - if i < 11 then - say '(x-1)^'i '=' Plst2form(Parr2lst()) - s = 1 - do j = 2 to poly.0-1 - a = poly.coef.j - if a//i > 0 then do - s = 0 - leave j - end - end - if s = 1 then do - if i > 1 then do - n = n+1 - prim.n = i - end - end -end -prim.0 = n -say Format(Time('e'),,3) 'seconds' -say -return - -Showprimes: -procedure expose prim. -arg p -call Time('r') -say 'Primes...' -if p < 0 then do - p = Abs(p) - if prim.0 > 0 then - say p 'is prime' - else - say p 'is not prime' -end -else do - do i = 1 to prim.0 - call Charout ,Right(prim.i,5) - if i//20 = 0 then - say - end - say -end -say Format(Time('e'),,3) 'seconds' -say -return - -include Functions -include Numbers -include Polynomial -include Sequences -include Abend diff --git a/Task/ASCII-art-diagram-converter/C-sharp/ascii-art-diagram-converter-1.cs b/Task/ASCII-art-diagram-converter/C-sharp/ascii-art-diagram-converter-1.cs new file mode 100644 index 0000000000..003dbde2f0 --- /dev/null +++ b/Task/ASCII-art-diagram-converter/C-sharp/ascii-art-diagram-converter-1.cs @@ -0,0 +1,190 @@ +using System.CodeDom.Compiler; +using System.Diagnostics; + +var format = @"+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| ID | ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +|QR| Opcode |AA|TC|RD|RA| Z | RCODE | ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| QDCOUNT | ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| ANCOUNT | ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| NSCOUNT | ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| ARCOUNT | ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"; + +var lines = format.Split('\n') + .Select(line => line.Trim()) + .Where(s => s.Length > 0) + .ToArray(); + +var first = lines[0]; +var ll = first.Length; + +if (lines.Any(line => line.Length != ll)) + throw new Exception("Lines are not the same length."); + +if (first[0] != '+' || first[^1] != '+') + throw new Exception("First line does not start and end with '+'."); + +var bits = first.Split('+')[1..^1]; + +if (bits.Any(bit => bit != "--")) + throw new Exception("Not all bits on first line match '+--+'."); + +if (lines.Length % 2 == 0) + throw new Exception("Expected an odd number of definition lines."); + +var rows = lines.Length / 2; + +if (Enumerable.Range(0, rows).Any(row => lines[2 * row + 2] != first)) + throw new Exception("Not all line separators match first line."); + +var width = bits.Length; + +if (width != 8 && width != 16 && width != 32 && width != 64) + throw new Exception("Bit width is not 8, 16, 32, or 64."); + +var ftype = width switch +{ + 8 => "byte", + 16 => "ushort", + 32 => "uint", + _ => "ulong" +}; + +const string filename = "Header.cs"; +const string structName = "Header"; +List<(string Name, int Width)> fieldList = []; +List backing = []; + +using (var file = File.CreateText(filename)) +using (var code = new IndentedTextWriter(file)) +{ + code.WriteLine("using System.Buffers.Binary;"); + code.WriteLine("using System.Runtime.InteropServices;"); + code.WriteLine(); + code.WriteLine("[StructLayout(LayoutKind.Sequential, Pack = 0)]"); + code.WriteLine($"public struct {structName}"); + code.WriteLine("{"); + code.Indent++; + code.WriteLine($"public static readonly int MarshalledSize = Marshal.SizeOf<{structName}>();"); + + for (var row = 0; row < rows; row++) + { + var def = lines[row * 2 + 1]; + + if (def[0] != '|' || def[^1] != '|') + throw new Exception($"Row {row} doesn't start and end with '|'."); + + var fields = def.Split('|')[1..^1]; + + if (fields.Length > 1) + { + code.WriteLine(); + code.WriteLine($"{ftype} data{row};"); + backing.Add($"data{row}"); + } + + var offset = width; + + foreach (var field in fields) + { + if (field.Length % 3 != 2) + throw new Exception($"Field '{field.Trim()}' delimiters misaligned."); + + var fname = field.Trim(); + + if (fname.Length == 0) + throw new Exception($"Field name is missing."); + + var fwidth = (field.Length + 1) / 3; + offset -= fwidth; + fieldList.Add((fname, fwidth)); + var mask = "0b" + new string('1', fwidth); + var nmask = "0b" + new string('1', width - fwidth - offset) + new string('0', fwidth) + new string('1', offset); + code.WriteLine(); + code.WriteLine($"public {ftype} {fname}"); + code.WriteLine("{"); + code.Indent++; + + if (fields.Length == 1) + { + code.WriteLine("readonly get;"); + code.WriteLine("set;"); + backing.Add(fname); + } + else + { + code.WriteLine($"readonly get {{ return ({ftype})((data{row} >> {offset}) & {mask});}}"); + code.WriteLine($"set {{ data{row} = ({ftype})((data{row} & {nmask}) | ((value & {mask}) << {offset})); }}"); + } + + code.Indent--; + code.WriteLine("}"); + } + } + + code.WriteLine(); + code.WriteLine($"public static {structName} FromArray(byte[] bytes)"); + code.WriteLine("{"); + code.Indent++; + code.WriteLine("var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);"); + code.WriteLine($"var result = Marshal.PtrToStructure<{structName}>(handle.AddrOfPinnedObject());"); + code.WriteLine("handle.Free();"); + + if (width > 8) + { + code.WriteLine(); + code.WriteLine("if (BitConverter.IsLittleEndian)"); + code.WriteLine("{"); + code.Indent++; + + foreach (var f in backing) + { + code.WriteLine($"result.{f} = BinaryPrimitives.ReverseEndianness(result.{f});"); + } + + code.Indent--; + code.WriteLine("}"); + code.WriteLine(); + } + + code.WriteLine("return result;"); + code.Indent--; + code.WriteLine("}"); + code.WriteLine(); + code.WriteLine("public readonly byte[] ToArray()"); + code.WriteLine("{"); + code.Indent++; + code.WriteLine($"var bytes = new byte[Marshal.SizeOf<{structName}>()];"); + code.WriteLine("var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);"); + code.WriteLine("Marshal.StructureToPtr(this, handle.AddrOfPinnedObject(), false);"); + code.WriteLine("handle.Free();"); + + if (width > 8) + { + code.WriteLine(); + code.WriteLine("if (BitConverter.IsLittleEndian)"); + code.WriteLine("{"); + code.Indent++; + code.WriteLine($"for (var i = 0; i < MarshalledSize; i += sizeof({ftype}))"); + code.WriteLine("{"); + code.Indent++; + code.WriteLine($"Array.Reverse(bytes, i, sizeof({ftype}));"); + code.Indent--; + code.WriteLine("}"); + code.Indent--; + code.WriteLine("}"); + code.WriteLine(); + } + + code.WriteLine("return bytes;"); + code.Indent--; + code.WriteLine("}"); + + code.Indent--; + code.WriteLine("}"); +} diff --git a/Task/ASCII-art-diagram-converter/C-sharp/ascii-art-diagram-converter-2.cs b/Task/ASCII-art-diagram-converter/C-sharp/ascii-art-diagram-converter-2.cs new file mode 100644 index 0000000000..9fb3e832ae --- /dev/null +++ b/Task/ASCII-art-diagram-converter/C-sharp/ascii-art-diagram-converter-2.cs @@ -0,0 +1,15 @@ +var bytes = new byte[Header.MarshalledSize]; +Random.Shared.NextBytes(bytes); +var header = Header.FromArray(bytes); +var bytes2 = header.ToArray(); +Debug.Assert(Enumerable.SequenceEqual(bytes, bytes2)); +Console.WriteLine($"Struct size: {Header.MarshalledSize} bytes"); +Console.WriteLine($"Binary data: {string.Join(" ", bytes.Select(b => b.ToString("B8")))}"); +Console.WriteLine($"Fields"); + +foreach (var (fname, fwidth) in fieldList) +{ + var value = typeof(Header).GetProperty(fname)!.GetValue(header); + var vstr = $"{value!:B}".PadLeft(fwidth, '0'); + Console.WriteLine($" {fname} = {vstr}"); +} diff --git a/Task/Abbreviations-automatic/EasyLang/abbreviations-automatic.easy b/Task/Abbreviations-automatic/EasyLang/abbreviations-automatic.easy new file mode 100644 index 0000000000..4953f45b97 --- /dev/null +++ b/Task/Abbreviations-automatic/EasyLang/abbreviations-automatic.easy @@ -0,0 +1,30 @@ +proc abbrev s$ . + d$[] = strtok s$ " " + repeat + lng += 1 + for i to len d$[] - 1 + a$ = substr d$[i] 1 lng + for j = i + 1 to len d$[] + if substr d$[j] 1 lng = a$ : break 2 + . + . + until i = len d$[] + . + print lng & ": " & s$ +. +repeat + s$ = input + if s$ = "" + print s$ + s$ = input + . + until s$ = "" + abbrev s$ +. +# +input_data +Sunday Monday Tuesday Wednesday Thursday Friday Saturday +Sondag Maandag Dinsdag Woensdag Donderdag Vrydag Saterdag +E_djelë E_hënë E_martë E_mërkurë E_enjte E_premte E_shtunë +Ehud Segno Maksegno Erob Hamus Arbe Kedame +Al_Ahad Al_Ithinin Al_Tholatha'a Al_Arbia'a Al_Kamis Al_Gomia'a Al_Sabit diff --git a/Task/Abbreviations-easy/Crystal/abbreviations-easy.cr b/Task/Abbreviations-easy/Crystal/abbreviations-easy.cr new file mode 100644 index 0000000000..ddf3b6a402 --- /dev/null +++ b/Task/Abbreviations-easy/Crystal/abbreviations-easy.cr @@ -0,0 +1,17 @@ +abbrevs = Hash(String, String).new + +" Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy + COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find + NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput + Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO + MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT + READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT + RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up +".scan(/([A-Z]+)([a-z]*)/) do |m| + command, minimal_abbrev, extra_letters = m[0].upcase, m[1], m[2].upcase + extra_letters.chars.accumulate(minimal_abbrev).each do |k| abbrevs[k] = command end +end + +puts "riG rePEAT copies put mo rest types fup. 6 poweRin".split.map {|w| + abbrevs[w.upcase]? || "*error*" +}.join(" ") diff --git a/Task/Abbreviations-easy/EasyLang/abbreviations-easy.easy b/Task/Abbreviations-easy/EasyLang/abbreviations-easy.easy new file mode 100644 index 0000000000..17497ce6cb --- /dev/null +++ b/Task/Abbreviations-easy/EasyLang/abbreviations-easy.easy @@ -0,0 +1,42 @@ +a$ = "Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy" +a$ &= " COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find" +a$ &= " NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput" +a$ &= " Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO" +a$ &= " MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT" +a$ &= " READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT" +a$ &= " RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up" +cmd$[] = strtok a$ " " +# +func$ toupper s$ . + for c$ in strchars s$ + c = strcode c$ + if c >= 97 : c -= 32 + r$ &= strchar c + . + return r$ +. +for i to len cmd$[] + h$ = "" + for c$ in strchars cmd$[i] + if strcode c$ > strcode "Z" : break 1 + h$ &= c$ + . + abbr$[] &= h$ + cmd$[i] = toupper cmd$[i] +. +func$ getabbr in$ . + in$ = toupper in$ + for i to len cmd$[] + if strpos cmd$[i] in$ = 1 and strpos in$ abbr$[i] = 1 + return cmd$[i] + . + . + return "*error*" +. +in$[] = strtok input " " +for s$ in in$[] + write getabbr s$ & " " +. +# +input_data +riG rePEAT copies put mo rest types fup. 6 poweRin diff --git a/Task/Abbreviations-simple/EasyLang/abbreviations-simple.easy b/Task/Abbreviations-simple/EasyLang/abbreviations-simple.easy new file mode 100644 index 0000000000..ffbc7cc06f --- /dev/null +++ b/Task/Abbreviations-simple/EasyLang/abbreviations-simple.easy @@ -0,0 +1,42 @@ +a$ = "add 1 alter 3 backup 2 bottom 1 Cappend 2 change 1 Schange Cinsert 2 Clast 3" +a$ &= " compress 4 copy 2 count 3 Coverlay 3 cursor 3 delete 3 Cdelete 2 down 1 duplicate" +a$ &= " 3 xEdit 1 expand 3 extract 3 find 1 Nfind 2 Nfindup 6 NfUP 3 Cfind 2 findUP 3 fUP 2" +a$ &= " forward 2 get help 1 hexType 4 input 1 powerInput 3 join 1 split 2 spltJOIN load" +a$ &= " locate 1 Clocate 2 lowerCase 3 upperCase 3 Lprefix 2 macro merge 2 modify 3 move 2" +a$ &= " msg next 1 overlay 1 parse preserve 4 purge 3 put putD query 1 quit read recover 3" +a$ &= " refresh renum 3 repeat 3 replace 1 Creplace 2 reset 3 restore 4 rgtLEFT right 2 left" +a$ &= " 2 save set shift 2 si sort sos stack 3 status 4 top transfer 3 type 1 up 1" +toks$[] = strtok a$ " " +# +func$ toupper s$ . + for c$ in strchars s$ + c = strcode c$ + if c >= 97 : c -= 32 + r$ &= strchar c + . + return r$ +. +for tok$ in toks$[] + if number tok$ <> 0 + cnt[$] = number tok$ + else + cmd$[] &= toupper tok$ + cnt[] &= 999 + . +. +func$ getabbr in$ . + in$ = toupper in$ + for i to len cmd$[] + if cmd$[i] = in$ or len in$ >= cnt[i] and strpos cmd$[i] in$ = 1 + return cmd$[i] + . + . + return "*error*" +. +in$[] = strtok input " " +for s$ in in$[] + write getabbr s$ & " " +. +# +input_data +riG rePEAT copies put mo rest types fup. 6 poweRin diff --git a/Task/Abelian-sandpile-model-Identity/EasyLang/abelian-sandpile-model-identity.easy b/Task/Abelian-sandpile-model-Identity/EasyLang/abelian-sandpile-model-identity.easy index 3e0c4d008f..df68c01fac 100644 --- a/Task/Abelian-sandpile-model-Identity/EasyLang/abelian-sandpile-model-identity.easy +++ b/Task/Abelian-sandpile-model-Identity/EasyLang/abelian-sandpile-model-identity.easy @@ -1,13 +1,11 @@ -proc out s[] . . +proc out s[] . for r = 0 to 2 - for c to 3 - write s[c + 3 * r] & " " - . + for c to 3 : write s[c + 3 * r] & " " print "" . print "" . -proc stab . m[] . +proc stab &m[] . n = sqrt len m[] repeat stable = 1 @@ -15,27 +13,17 @@ proc stab . m[] . if m[p] >= 4 stable = 0 m[p] -= 4 - if p > n - m[p - n] += 1 - . - if p mod n <> 0 - m[p + 1] += 1 - . - if p <= len m[] - n - m[p + n] += 1 - . - if p mod n <> 1 - m[p - 1] += 1 - . + if p > n : m[p - n] += 1 + if p mod n <> 0 : m[p + 1] += 1 + if p <= len m[] - n : m[p + n] += 1 + if p mod n <> 1 : m[p - 1] += 1 . . until stable = 1 . . func[] add s1[] s2[] . - for i to len s1[] - r[] &= s1[i] + s2[i] - . + for i to len s1[] : r[] &= s1[i] + s2[i] stab r[] return r[] . diff --git a/Task/Abelian-sandpile-model/EasyLang/abelian-sandpile-model.easy b/Task/Abelian-sandpile-model/EasyLang/abelian-sandpile-model.easy index c77b7a2530..12ff7d05c0 100644 --- a/Task/Abelian-sandpile-model/EasyLang/abelian-sandpile-model.easy +++ b/Task/Abelian-sandpile-model/EasyLang/abelian-sandpile-model.easy @@ -2,19 +2,18 @@ n = 77 len m[] n * n m[n * n div 2 + 1] = 10000 # -proc show . . +proc show . sc = 100 / n for r range0 n for c range0 n - move c * sc r * sc p = r * n + c + 1 - color 222 * m[p] - rect sc sc + gcolor 222 * m[p] + grect c * sc r * sc sc sc . . sleep 0 . -proc run . . +proc run . repeat mp[] = m[] stable = 1 diff --git a/Task/Abundant-deficient-and-perfect-number-classifications/Ballerina/abundant-deficient-and-perfect-number-classifications-1.ballerina b/Task/Abundant-deficient-and-perfect-number-classifications/Ballerina/abundant-deficient-and-perfect-number-classifications-1.ballerina new file mode 100644 index 0000000000..4b63fb03d5 --- /dev/null +++ b/Task/Abundant-deficient-and-perfect-number-classifications/Ballerina/abundant-deficient-and-perfect-number-classifications-1.ballerina @@ -0,0 +1,46 @@ +import ballerina/io; + +function divisors(int n) returns int[] { + if n < 1 { return []; } + int[] divisors = []; + int[] divisors2 = []; + int i = 1; + int k = n % 2 == 0 ? 1 : 2; + while i * i <= n { + if n % i == 0 { + divisors.push(i); + int j = n / i; + if j != i { divisors2.push(j); } + } + i += k; + } + if divisors2.length() > 0 { + divisors.push(...divisors2.reverse()); + } + return divisors; +} + +function properDivisors(int n) returns int[] { + int[] d = divisors(n); + int c = d.length(); + return c <= 1 ? [] : d.slice(0, c - 1); +} + +public function main() { + int d = 0; + int a = 0; + int p = 0; + foreach int i in 1...20000 { + int j = int:sum(...properDivisors(i)); + if j < i { + d += 1; + } else if j == i { + p += 1; + } else { + a += 1; + } + } + io:println("There are ", d, " deficient numbers between 1 and 20000"); + io:println("There are ", a, " abundant numbers between 1 and 20000"); + io:println("There are ", p, " perfect numbers between 1 and 20000"); +} diff --git a/Task/Abundant-deficient-and-perfect-number-classifications/Ballerina/abundant-deficient-and-perfect-number-classifications-2.ballerina b/Task/Abundant-deficient-and-perfect-number-classifications/Ballerina/abundant-deficient-and-perfect-number-classifications-2.ballerina new file mode 100644 index 0000000000..a96bb0a4a1 --- /dev/null +++ b/Task/Abundant-deficient-and-perfect-number-classifications/Ballerina/abundant-deficient-and-perfect-number-classifications-2.ballerina @@ -0,0 +1,36 @@ +import ballerina/io; + +public function main() { + final int maxNumber = 20000; + int abundantCount = 0; + int deficientCount = 0; + int perfectCount = 0; + + int[] pds = []; + pds.push(0); // element 0 + pds.push(0); // element 1 + foreach int i in 2...maxNumber { + pds.push(1); + } + foreach int i in 2...maxNumber { + int j = i + i; + while j <= maxNumber { + pds[j] += i; + j += i; + } + } + foreach int n in 1...maxNumber { + int pdSum = pds[n]; + if pdSum < n { + deficientCount += 1; + } else if pdSum == n { + perfectCount += 1; + } else { // pdSum > n + abundantCount += 1; + } + } + + io:println("Abundant : ", abundantCount); + io:println("Deficient: ", deficientCount); + io:println("Perfect : ", perfectCount); +} diff --git a/Task/Abundant-deficient-and-perfect-number-classifications/Elena/abundant-deficient-and-perfect-number-classifications.elena b/Task/Abundant-deficient-and-perfect-number-classifications/Elena/abundant-deficient-and-perfect-number-classifications.elena index 90f65ae3e7..7523b4abd7 100644 --- a/Task/Abundant-deficient-and-perfect-number-classifications/Elena/abundant-deficient-and-perfect-number-classifications.elena +++ b/Task/Abundant-deficient-and-perfect-number-classifications/Elena/abundant-deficient-and-perfect-number-classifications.elena @@ -47,5 +47,5 @@ public program() int deficient := 0; int perfect := 0; classifyNumbers(20000, ref abundant, ref deficient, ref perfect); - console.printLine("Abundant: ",abundant,", Deficient: ",deficient,", Perfect: ",perfect) + Console.printLine("Abundant: ",abundant,", Deficient: ",deficient,", Perfect: ",perfect) } diff --git a/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-1.rexx b/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-1.rexx index 076015bcfb..e2df0a6f1f 100644 --- a/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-1.rexx +++ b/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-1.rexx @@ -1,23 +1,51 @@ -/*REXX program counts the number of abundant/deficient/perfect numbers within a range.*/ -parse arg low high . /*obtain optional arguments from the CL*/ -high=word(high low 20000,1); low= word(low 1,1) /*obtain the LOW and HIGH values.*/ -say center('integers from ' low " to " high, 45, "═") /*display a header.*/ -!.= 0 /*define all types of sums to zero. */ - do j=low to high; $= sigma(j) /*get sigma for an integer in a range. */ - if $j then !.a= !.a + 1 /*Greater? " " abundant " */ - else !.p= !.p + 1 /*Equal? " " perfect " */ - end /*j*/ /* [↑] IFs are coded as per likelihood*/ +/* REXX */ +Call time 'R' +cnt.=0 +Do x=1 To 20000 + pd=proper_divisors(x) + sumpd=sum(pd) + Select + When xhi Then Do + list.npd=x + hi=npd + End + When npd=hi Then + list.hi=list.hi x + Otherwise + Nop + End + End -say ' the number of perfect numbers: ' right(!.p, length(high) ) -say ' the number of abundant numbers: ' right(!.a, length(high) ) -say ' the number of deficient numbers: ' right(!.d, length(high) ) -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sigma: procedure; parse arg x; if x<2 then return 0; odd=x // 2 /* // ◄──remainder.*/ - s= 1 /* [↓] only use EVEN or ODD integers.*/ - do k=2+odd by 1+odd while k*kj then !.a= !.a + 1 /*Greater? " " abundant " */ - else !.p= !.p + 1 /*Equal? " " perfect " */ - end /*j*/ /* [↑] IFs are coded as per likelihood*/ +-- 8 May 2025 +include Settings -say ' the number of perfect numbers: ' right(!.p, length(high) ) -say ' the number of abundant numbers: ' right(!.a, length(high) ) -say ' the number of deficient numbers: ' right(!.d, length(high) ) -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sigma: procedure; parse arg x 1 z; if x<5 then return max(0, x-1) /*sets X&Z to arg1.*/ - q=1; do while q<=z; q= q * 4; end /* ◄──↓ compute integer sqrt of Z (=R)*/ - r=0; do while q>1; q=q%4; _=z-r-q; r=r%2; if _>=0 then do; z=_; r=r+q; end; end - odd= x//2 /* [↓] only use EVEN | ODD ints. ___*/ - s= 1; do k=2+odd by 1+odd to r /*divide by all integers up to √ x */ - if x//k==0 then s=s + k + x%k /*add the two divisors to (sigma) sum. */ - end /*k*/ /* [↑] % is the REXX integer division*/ - if r*r==x then return s - k /*Was X a square? If so, subtract √ x */ - return s /*return (sigma) sum of the divisors. */ +say 'ABUNDANT, DEFICIENT AND PERFECT NUMBER CLASSIFICATIONS' +say version +say +parse value 0 0 0 with a p d +do x = 1 to 20000 + sum = Aliquot(x) + select + when x < sum then + a = a+1 + when x = sum then + p = p+1 + otherwise + d = d+1 + end +end + +say 'In the range 1 - 20000' +say Format(a,5) 'numbers are abundant ' +say Format(p,5) 'numbers are perfect ' +say Format(d,5) 'numbers are deficient ' +say Time('e') 'seconds' +exit + +include Numbers +include Functions +include Special +include Abend diff --git a/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-3.rexx b/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-3.rexx deleted file mode 100644 index e2df0a6f1f..0000000000 --- a/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-3.rexx +++ /dev/null @@ -1,51 +0,0 @@ -/* REXX */ -Call time 'R' -cnt.=0 -Do x=1 To 20000 - pd=proper_divisors(x) - sumpd=sum(pd) - Select - When xhi Then Do - list.npd=x - hi=npd - End - When npd=hi Then - list.hi=list.hi x - Otherwise - Nop - End - End - -Say 'In the range 1 - 20000' -Say format(cnt.abundant ,5) 'numbers are abundant ' -Say format(cnt.perfect ,5) 'numbers are perfect ' -Say format(cnt.deficient,5) 'numbers are deficient ' -Say time('E') 'seconds elapsed' -Exit - -proper_divisors: Procedure -Parse Arg n -Pd='' -If n=1 Then Return '' -If n//2=1 Then /* odd number */ - delta=2 -Else /* even number */ - delta=1 -Do d=1 To n%2 By delta - If n//d=0 Then - pd=pd d - End -Return space(pd) - -sum: Procedure -Parse Arg list -sum=0 -Do i=1 To words(list) - sum=sum+word(list,i) - End -Return sum diff --git a/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-4.rexx b/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-4.rexx deleted file mode 100644 index 488aede163..0000000000 --- a/Task/Abundant-deficient-and-perfect-number-classifications/REXX/abundant-deficient-and-perfect-number-classifications-4.rexx +++ /dev/null @@ -1,27 +0,0 @@ -/* REXX */ -Call time 'R' -cnt.=0 -Do x=1 to 20000 - sumpd=Sigma(x)-x - Select - When x 2n''', -
or,   equivalently,   the   ''sum of proper divisors''   (or aliquot sum)       '''s(n) > n'''. +An [[wp:Abundant_number|Abundant number]] is a number '''n''' for which the   ''sum of divisors''   '''\sigma(n) > 2n''', +
or,   equivalently,   the   ''sum of proper divisors''   (or aliquot sum)       '''s(n) > n'''. ;E.G.: -'''12'''   is abundant, it has the proper divisors     '''1,2,3,4 & 6'''     which sum to   '''16'''   ( > '''12''' or '''n'''); -
       or alternately,   has the sigma sum of   '''1,2,3,4,6 & 12'''   which sum to   '''28'''   ( > '''24''' or '''2n'''). +'''12'''   is abundant, it has the proper divisors     '''1, 2, 3, 4 & 6'''     which sum to   '''16'''   ( > '''12''' or '''n'''); +
       or alternately,   has the sigma sum of   '''1, 2, 3, 4, 6 & 12'''   which sum to   '''28'''   ( > '''24''' or '''2n'''). Abundant numbers are common, though '''even''' abundant numbers seem to be much more common than '''odd''' abundant numbers. @@ -15,7 +15,7 @@ To make things more interesting, this task is specifically about finding   ;Task *Find and display here: at least the first 25 abundant odd numbers and either their proper divisor sum or sigma sum. *Find and display here: the one thousandth abundant odd number and either its proper divisor sum or sigma sum. -*Find and display here: the first abundant odd number greater than one billion (109) and either its proper divisor sum or sigma sum. +*Find and display here: the first abundant odd number greater than one billion (10^9) and either its proper divisor sum or sigma sum. ;References: diff --git a/Task/Abundant-odd-numbers/Ballerina/abundant-odd-numbers.ballerina b/Task/Abundant-odd-numbers/Ballerina/abundant-odd-numbers.ballerina new file mode 100644 index 0000000000..42e8483b29 --- /dev/null +++ b/Task/Abundant-odd-numbers/Ballerina/abundant-odd-numbers.ballerina @@ -0,0 +1,73 @@ +import ballerina/io; + +function divisors(int n) returns int[] { + if n < 1 { return []; } + int[] divisors = []; + int[] divisors2 = []; + int i = 1; + int k = n % 2 == 0 ? 1 : 2; + while i * i <= n { + if n % i == 0 { + divisors.push(i); + int j = n / i; + if j != i { divisors2.push(j); } + } + i += k; + } + if divisors2.length() > 0 { + divisors.push(...divisors2.reverse()); + } + return divisors; +} + +function properDivisors(int n) returns int[] { + int[] d = divisors(n); + int c = d.length(); + return c <= 1 ? [] : d.slice(0, c - 1); +} + +function sumStr(int[] divs) returns string { + var f = function(string acc, int div) returns string { + return acc + div.toString() + " + "; + }; + string sum = divs.reduce(f, ""); + int len = sum.length(); + return sum.substring(0, len - 3); +} + +function abundantOdd(int searchFrom, int countFrom, int countTo, boolean printOne) + returns int { + int count = countFrom; + int n = searchFrom; + while count < countTo { + int[] divs = properDivisors(n); + int tot = int:sum(...divs); + if tot > n { + count += 1; + if !printOne || count >= countTo { + string s = sumStr(divs); + if !printOne { + string s1 = count.toString().padStart(2); + string s2 = n.toString().padStart(5); + io:println(`${s1}. ${s2} < ${s} = ${tot}`); + } else { + io:println(`${n} < ${s} = ${tot}`); + } + } + } + n += 2; + } + return n; +} + +public function main() { + final int max = 25; + io:println("The first ", max, " abundant odd numbers are:"); + int n = abundantOdd(1, 0, 25, false); + + io:println("\nThe one thousandth abundant odd number is:"); + _ = abundantOdd(n, 25, 1000, true); + + io:println("\nThe first abundant odd number above one billion is:"); + _ = abundantOdd(1e9+1, 0, 1, true); +} diff --git a/Task/Abundant-odd-numbers/EasyLang/abundant-odd-numbers.easy b/Task/Abundant-odd-numbers/EasyLang/abundant-odd-numbers.easy index 5cfb14b7e7..8092c07c7d 100644 --- a/Task/Abundant-odd-numbers/EasyLang/abundant-odd-numbers.easy +++ b/Task/Abundant-odd-numbers/EasyLang/abundant-odd-numbers.easy @@ -14,7 +14,7 @@ fastfunc sumdivs n . return sum . n = 1 -numfmt 0 6 +numfmt 6 0 while cnt < 1000 sum = sumdivs n if sum > n diff --git a/Task/Accumulator-factory/Ballerina/accumulator-factory.ballerina b/Task/Accumulator-factory/Ballerina/accumulator-factory.ballerina new file mode 100644 index 0000000000..a8f8252dea --- /dev/null +++ b/Task/Accumulator-factory/Ballerina/accumulator-factory.ballerina @@ -0,0 +1,38 @@ +import ballerina/io; + +type numeric int|float|decimal; + +function accumulator(numeric acc) returns (function(numeric) returns numeric) { + numeric sum = acc; + return function(numeric n) returns numeric { + numeric sum2 = sum; + if sum2 is int && n is int { + sum2 += n; + } else if sum2 is float && n is float { + sum2 += n; + } else if sum2 is decimal && n is decimal { + sum2 += n; + } else if sum2 is int && n is float { + sum2 = sum2 + n; + } else if sum2 is int && n is decimal { + sum2 = sum2 + n; + } else if sum2 is float && n is int { + sum2 += n; + } else if sum2 is float && n is decimal { + sum2 = sum2 + n; + } else if sum2 is decimal && n is int { + sum2 += n; + } else if sum2 is decimal && n is float { + sum2 += n; + } + sum = sum2; + return sum; + }; +} + +public function main() { + var x = accumulator(1); + _ = x(5); + _ = accumulator(2); + io:println(x(2.3)); +} diff --git a/Task/Accumulator-factory/Elena/accumulator-factory.elena b/Task/Accumulator-factory/Elena/accumulator-factory.elena index be112e0585..ca3b64dd19 100644 --- a/Task/Accumulator-factory/Elena/accumulator-factory.elena +++ b/Task/Accumulator-factory/Elena/accumulator-factory.elena @@ -12,5 +12,5 @@ public program() var y := accumulator(3); - console.write(x(2.3r)) + Console.write(x(2.3r)) } diff --git a/Task/Achilles-numbers/Ballerina/achilles-numbers.ballerina b/Task/Achilles-numbers/Ballerina/achilles-numbers.ballerina new file mode 100644 index 0000000000..ff31e0dfeb --- /dev/null +++ b/Task/Achilles-numbers/Ballerina/achilles-numbers.ballerina @@ -0,0 +1,92 @@ +import ballerina/io; + +map pps = {}; + +function getPerfectPowers(int maxExp) { + int upper = 10.0.pow(maxExp); + int upper2 = 10.0.pow(maxExp).sqrt().floor(); + foreach int i in 2...upper2 { + int p = i; + while true { + if p > int:MAX_VALUE / i { break; } + p *= i; + if p >= upper { break; } + pps[p.toString()] = 1; + } + } +} + +function getAchilles(int minExp, int maxExp) returns map { + int lower = 10.0.pow(minExp); + int upper = 10.0.pow(maxExp); + int upper2 = 10.0.pow(maxExp).cbrt().floor(); + int upper3 = 10.0.pow(maxExp).sqrt().floor(); + map achilles = {}; + foreach int b in 1...upper2 { + int b3 = b * b * b; + foreach int a in 1...upper3 { + int p = b3 * a * a; + if p >= upper { break; } + if p >= lower { + string ps = p.toString(); + if !pps.hasKey(ps) { + achilles[ps] = 1; + } + } + } + } + return achilles; +} + +function totient(int m) returns int { + if m < 1 { return 0; } + int tot = m; + int n = m; + int i = 2; + while i * i <= n { + if (n % i) == 0 { + while (n % i) == 0 { n /= i; } + tot -= tot / i; + } + if i == 2 { i = 1; } + i += 2; + } + if n > 1 { tot -= tot / n; } + return tot; +} + +public function main() returns error? { + final int maxDigits = 14; + getPerfectPowers(maxDigits); + map achillesSet = getAchilles(1, 5); // enough for first 2 parts + int[] achilles = achillesSet.keys().map(s => check int:fromString(s)).sort(); + io:println("First 50 Achilles numbers:"); + foreach int i in 0..<50 { + string s = achilles[i].toString().padStart(4); + io:print(s, " "); + if (i + 1) % 10 == 0 { io:println(); } + } + io:println("\nFirst 30 strong Achilles numbers:"); + int[] strongAchilles = []; + int count = 0; + int n = 0; + while count < 30 { + int tot = totient(achilles[n]); + if achillesSet.hasKey(tot.toString()) { + strongAchilles.push(achilles[n]); + count += 1; + } + n += 1; + } + foreach int j in 0..<30 { + string t = strongAchilles[j].toString().padStart(5); + io:print(t, " "); + if (j + 1) % 10 == 0 { io:println(); } + } + + io:println("\nNumber of Achilles numbers with:"); + foreach int d in 2...maxDigits { + int ac = getAchilles(d - 1, d).length(); + io:println(d.toString().padStart(2), " digits: ", ac); + } +} diff --git a/Task/Achilles-numbers/EasyLang/achilles-numbers.easy b/Task/Achilles-numbers/EasyLang/achilles-numbers.easy index ec0935dde9..fda73a8936 100644 --- a/Task/Achilles-numbers/EasyLang/achilles-numbers.easy +++ b/Task/Achilles-numbers/EasyLang/achilles-numbers.easy @@ -1,14 +1,10 @@ func gcd n d . - if d = 0 - return n - . + if d = 0 : return n return gcd d (n mod d) . func totient n . for m = 1 to n - if gcd m n = 1 - tot += 1 - . + if gcd m n = 1 : tot += 1 . return tot . @@ -16,41 +12,29 @@ func isPowerful m . n = m f = 2 l = sqrt m - if m <= 1 - return 0 - . + if m <= 1 : return 0 while 1 = 1 q = n div f if n mod f = 0 - if m mod (f * f) <> 0 - return 0 - . + if m mod (f * f) <> 0 : return 0 n = q - if f > n - return 1 - . + if f > n : return 1 else f += 1 if f > l - if m mod (n * n) <> 0 - return 0 - . + if m mod (n * n) <> 0 : return 0 return 1 . . . . func isAchilles n . - if isPowerful n = 0 - return 0 - . + if isPowerful n = 0 : return 0 m = 2 a = m * m repeat repeat - if a = n - return 0 - . + if a = n : return 0 a *= m until a > n . @@ -91,9 +75,7 @@ b = 100 for i = 2 to 5 num = 0 for n = a to b - 1 - if isAchilles n = 1 - num += 1 - . + num += isAchilles n . write num & " " a = b diff --git a/Task/Ackermann-function/Ballerina/ackermann-function.ballerina b/Task/Ackermann-function/Ballerina/ackermann-function.ballerina new file mode 100644 index 0000000000..95e0bc7de0 --- /dev/null +++ b/Task/Ackermann-function/Ballerina/ackermann-function.ballerina @@ -0,0 +1,14 @@ +import ballerina/io; + +function ackermann(int m, int n) returns int { + if m == 0 { return n + 1; } + if n == 0 { return ackermann(m - 1, 1); } + return ackermann(m - 1, ackermann(m, n - 1)); +} + +public function main() { + int[][] pairs = [ [1, 3], [2, 3], [3, 3], [1, 5], [2, 5], [3, 5] ]; + foreach var p in pairs { + io:println(`A[${p[0]}, ${p[1]}] = ${ackermann(p[0], p[1])}`); + } +} diff --git a/Task/Ackermann-function/Elena/ackermann-function.elena b/Task/Ackermann-function/Elena/ackermann-function.elena index fc46c62750..c8a0ec4580 100644 --- a/Task/Ackermann-function/Elena/ackermann-function.elena +++ b/Task/Ackermann-function/Elena/ackermann-function.elena @@ -1,5 +1,7 @@ import extensions; +// --- Ackermann function --- + ackermann(m,n) { if(n < 0 || m < 0) @@ -8,11 +10,11 @@ ackermann(m,n) }; m => - 0 { ^n + 1 } - ! { + 0 : { ^n + 1 } + ! : { n => - 0 { ^ackermann(m - 1,1) } - ! { ^ackermann(m - 1,ackermann(m,n-1)) } + 0 : { ^ackermann(m - 1,1) } + ! : { ^ackermann(m - 1,ackermann(m,n-1)) } } } @@ -22,9 +24,9 @@ public program() { for(int j := 0; j <= 5; j += 1) { - console.printLine("A(",i,",",j,")=",ackermann(i,j)) + Console.printLine("A(",i,",",j,")=",ackermann(i,j)) } }; - console.readChar() + Console.readChar() } diff --git a/Task/Add-a-variable-to-a-class-instance-at-runtime/Ballerina/add-a-variable-to-a-class-instance-at-runtime.ballerina b/Task/Add-a-variable-to-a-class-instance-at-runtime/Ballerina/add-a-variable-to-a-class-instance-at-runtime.ballerina new file mode 100644 index 0000000000..a4d319d761 --- /dev/null +++ b/Task/Add-a-variable-to-a-class-instance-at-runtime/Ballerina/add-a-variable-to-a-class-instance-at-runtime.ballerina @@ -0,0 +1,23 @@ +import ballerina/io; + +// Person is an 'open' record type which allows fields of 'anydata' type +// to be added at runtime. +type Person record { + string name; + int age; +}; + +public function main() { + // Create an instance of Person with an additional 'town' field. + Person p = { + name: "Fred", + age: 40, + "town": "Boston" // extra field name needs to be in quotes + }; + + // Print name and age fields - using standard '.' syntax. + io:print(p.name, " is ", p.age); + + // Print the additional field - using a map-like syntax. + io:println(" and lives in ", p["town"], "."); +} diff --git a/Task/Add-a-variable-to-a-class-instance-at-runtime/Elena/add-a-variable-to-a-class-instance-at-runtime.elena b/Task/Add-a-variable-to-a-class-instance-at-runtime/Elena/add-a-variable-to-a-class-instance-at-runtime.elena index 9634046d11..229abebea3 100644 --- a/Task/Add-a-variable-to-a-class-instance-at-runtime/Elena/add-a-variable-to-a-class-instance-at-runtime.elena +++ b/Task/Add-a-variable-to-a-class-instance-at-runtime/Elena/add-a-variable-to-a-class-instance-at-runtime.elena @@ -19,7 +19,7 @@ public program() object.foo := "bar"; - console.printLine(object,".foo=",object.foo); + Console.printLine(object,".foo=",object.foo); - console.readChar() + Console.readChar() } diff --git a/Task/Additive-primes/ALGOL-60/additive-primes.alg b/Task/Additive-primes/ALGOL-60/additive-primes.alg new file mode 100644 index 0000000000..177adf1e20 --- /dev/null +++ b/Task/Additive-primes/ALGOL-60/additive-primes.alg @@ -0,0 +1,60 @@ +begin + +integer procedure sumdigits(n); + value n; integer n; +begin + integer q, sum; + sum := 0; + for sum := sum while n > 0 do + begin + q := entier(n / 10); + sum := sum + (n - q * 10); + n := q; + end; + sumdigits := sum; +end; + +boolean procedure isprime(n); +value n; integer n; +begin + if n < 2 then + isprime := false + else if n = entier(n / 2) * 2 then + isprime := (n = 2) + else + begin + comment - check odd divisors up to sqrt(n); + integer i, limit; + boolean divisible; + i := 3; + limit := entier(sqrt(n)); + divisible := false; + for i := i while i <= limit and not divisible do + begin + if entier(n / i) * i = n then + divisible := true; + i := i + 2 + end; + isprime := not divisible; + end; +end; + +integer i, count; +outstring(1,"Looking up to 500 for additive primes\n"); +count := 0; +for i := 2 step 1 until 500 do + if isprime(i) then + begin + if isprime(sumdigits(i)) then + begin + outinteger(1,i); + count := count + 1; + if count = entier(count / 10) * 10 then + outstring(1,"\n"); + end; + end; +outstring(1,"\n"); +outinteger(1,count); +outstring(1,"were found\n"); + +end diff --git a/Task/Additive-primes/ALGOL-M/additive-primes.alg b/Task/Additive-primes/ALGOL-M/additive-primes.alg new file mode 100644 index 0000000000..54334dd123 --- /dev/null +++ b/Task/Additive-primes/ALGOL-M/additive-primes.alg @@ -0,0 +1,64 @@ +BEGIN + +% RETURN N MOD M % +INTEGER FUNCTION MOD(N, M); +INTEGER N, M; +BEGIN + MOD := N - (N / M) * M; +END; + +% RETURN 1 IF N IS PRIME, OTHERWISE 0 % +INTEGER FUNCTION ISPRIME(N); +INTEGER N; +BEGIN + IF N = 2 THEN + ISPRIME := 1 + ELSE IF (N < 2) OR (MOD(N,2) = 0) THEN + ISPRIME := 0 + ELSE % TEST ODD DIVISORS UP TO SQRT OF N % + BEGIN + INTEGER I, DIVISIBLE; + I := 3; + DIVISIBLE := 0; + WHILE (I * I <= N) AND (DIVISIBLE = 0) DO + BEGIN + IF MOD(N,I) = 0 THEN DIVISIBLE := 1; + I := I + 2; + END; + ISPRIME := 1 - DIVISIBLE; + END; +END; + +% RETURN THE SUM OF THE DIGITS OF N % +INTEGER FUNCTION SUMDIGITS(N); +INTEGER N; +BEGIN + INTEGER SUM; + SUM := 0; + WHILE N > 0 DO + BEGIN + SUM := SUM + MOD(N, 10); + N := N / 10; + END; + SUMDIGITS := SUM; +END; + +% LOOK FOR ADDITIVE PRIMES IN RANGE 1 TO 500 % +INTEGER I, S, COUNT; +COUNT := 0; +FOR I := 1 STEP 1 UNTIL 500 DO + BEGIN + IF ISPRIME(I)=1 THEN + BEGIN + S := SUMDIGITS(I); + IF ISPRIME(S)=1 THEN + BEGIN + WRITEON(I); + COUNT := COUNT + 1; + IF MOD(COUNT,8) = 0 THEN WRITE(""); + END; + END; + END; +WRITE(COUNT," ADDITIVE PRIMES WERE FOUND"); + +END diff --git a/Task/Additive-primes/Ballerina/additive-primes.ballerina b/Task/Additive-primes/Ballerina/additive-primes.ballerina new file mode 100644 index 0000000000..f4d3373ce4 --- /dev/null +++ b/Task/Additive-primes/Ballerina/additive-primes.ballerina @@ -0,0 +1,67 @@ +import ballerina/io; + +function sumDigits(int m) returns int { + int n = m; // make mutable + int sum = 0; + while n > 0 { + sum += n % 10; + n /= 10; + } + return sum; +} + +function isPrime(int n) returns boolean { + if n < 2 { return false; } + if n % 2 == 0 { return n == 2; } + if n % 3 == 0 { return n == 3; } + int d = 5; + while d * d <= n { + if n % d == 0 { return false; } + d += 2; + if n % d == 0 { return false; } + d += 4; + } + return true; +} + +function getPrimes(int n) returns int[] { + if n < 2 { return []; } + if n == 2 { return [2]; } + int k = (n - 3) / 2 + 1; + boolean[] marked = []; + marked.setLength(k); + foreach int i in 0..n).sqrt().floor(); + int lim = (f - 3) / 2 + 1; + foreach int i in 0.. 2 - return 0 - . + if n mod 2 = 0 and n > 2 : return 0 i = 3 sq = sqrt n while i <= sq - if n mod i = 0 - return 0 - . + if n mod i = 0 : return 0 i += 2 . return 1 @@ -22,9 +18,6 @@ func digsum n . for i = 2 to 500 if prime i = 1 s = digsum i - if prime s = 1 - write i & " " - . + if prime s = 1 : write i & " " . . -print "" diff --git a/Task/Additive-primes/PL-I-80/additive-primes.pli b/Task/Additive-primes/PL-I-80/additive-primes.pli new file mode 100644 index 0000000000..cbb1259113 --- /dev/null +++ b/Task/Additive-primes/PL-I-80/additive-primes.pli @@ -0,0 +1,52 @@ +additive_primes: procedure options (main); + %replace + search_limit by 500, + true by '1'b, + false by '0'b; + dcl (i, count) fixed bin; + put skip edit('Searching up to ', search_limit, + ' for additive primes') (a,f(3),a); + put skip; + count = 0; + do i = 2 to search_limit; + if isprime(i) then + do; + if isprime(sumdigits(i)) then + do; + put edit(i) (f(5)); + count = count + 1; + if mod(count,8) = 0 then put skip; + end; + end; + end; + put skip edit(count, ' were found') (f(3), a); + +/* return true if n is prime */ +isprime: proc(n) returns (bit(1)); + dcl + (n, i, limit) fixed bin; + if n < 2 then return (false); + if mod(n, 2) = 0 then return (n = 2); + limit = floor(sqrt(n)); + i = 3; + do while ((i <= limit) & (mod(n, i) ^= 0)); + i = i + 2; + end; + return (i > limit); +end isprime; + +/* return the sum of the digits of n */ +sumdigits: proc(n) returns (fixed bin); + dcl + (n, nn, sum) fixed bin; + /* use copy, since n is passed by reference */ + nn = n; + sum = 0; + do while (nn > 0); + sum = sum + mod(nn, 10); + nn = nn / 10; + end; + return (sum); +end sumdigits; + +end additive_primes; diff --git a/Task/Additive-primes/PascalABC.NET/additive-primes.pas b/Task/Additive-primes/PascalABC.NET/additive-primes.pas new file mode 100644 index 0000000000..c8f11a6506 --- /dev/null +++ b/Task/Additive-primes/PascalABC.NET/additive-primes.pas @@ -0,0 +1,4 @@ +## uses School;//поиск аддитивных простых чисел +var AdditivePrimes := Primes(500).Where(n -> n.Digits.Sum.IsPrime).ToArray; +Print('Additive Primes:'); AdditivePrimes.Println; +Println('Additive Primes Count:', AdditivePrimes.Count); diff --git a/Task/Additive-primes/REXX/additive-primes-2.rexx b/Task/Additive-primes/REXX/additive-primes-2.rexx index d7524b90f3..398faf76e3 100644 --- a/Task/Additive-primes/REXX/additive-primes-2.rexx +++ b/Task/Additive-primes/REXX/additive-primes-2.rexx @@ -1,61 +1,28 @@ +-- 22 Mar 2025 include Settings -say version; say 'Additive primes'; say +say 'ADDITIVE PRIMES' +say version +say arg n numeric digits 16 if n = '' then - n = -500 + n = 500 show = (n > 0); n = Abs(n) -a = Additiveprimes(n) +a = Additives(n) if show then do do i = 1 to a - call Charout ,Right(addi.additiveprime.i,8)' ' + call Charout ,Right(addi.i,8)' ' if i//10 = 0 then say end say end -say a 'additive Primes found below' n -say Time('e') 'seconds' +say a 'additive primes found below' n +say Time('e')/1 'seconds' exit -Additiveprimes: -/* Additive prime numbers */ -procedure expose addi. prim. -arg x -/* Init */ -addi. = 0 -/* Fast values */ -if x < 2 then - return 0 -if x < 101 then do - a = '2 3 5 7 11 23 29 41 43 47 61 67 83 89 999' - do n = 1 to Words(a) - w = Word(a,n) - if w > x then - leave - addi.additiveprime.n = w - end - n = n-1; addi.0 = n - return n -end -/* Get primes */ -p = Primes(x) -/* Collect additive primes */ -n = 0 -do i = 1 to p - q = prim.Prime.i; s = 0 - do j = 1 to Length(q) - s = s+Substr(q,j,1) - end - if Prime(s) then do - n = n+1; addi.additiveprime.n = q - end -end -/* Return number of additive primes */ -return n - -include Functions -include Numbers include Sequences +include Numbers +include Functions include Abend diff --git a/Task/Additive-primes/Raku/additive-primes.raku b/Task/Additive-primes/Raku/additive-primes.raku index 7497ffbb89..24abe19684 100644 --- a/Task/Additive-primes/Raku/additive-primes.raku +++ b/Task/Additive-primes/Raku/additive-primes.raku @@ -1,3 +1,3 @@ unit sub MAIN ($limit = 500); say "{+$_} additive primes < $limit:\n{$_».fmt("%" ~ $limit.chars ~ "d").batch(10).join("\n")}", - with ^$limit .grep: { .is-prime and .comb.sum.is-prime } + with ^$limit .grep: { .is-prime && .comb.sum.is-prime } diff --git a/Task/Additive-primes/S-BASIC/additive-primes.basic b/Task/Additive-primes/S-BASIC/additive-primes.basic new file mode 100644 index 0000000000..1ca0da2c9a --- /dev/null +++ b/Task/Additive-primes/S-BASIC/additive-primes.basic @@ -0,0 +1,55 @@ +$constant true = 0FFFFH +$constant false = 0 +$constant limit = 500 + +function sum.of.digits(n = integer) = integer + var i, sum = integer + var s = string + var ch = char + s = str$(n) + sum = 0 + for i = 2 to len(s) + ch = mid(s,i,1) + sum = sum + (ch - '0') + next i +end = sum + +function mod(n, m = integer) = integer +end = n - (n / m) * m + +comment + build a table of prime numbers using + the classic sieve of Erathosthenes +end +dim integer prime(limit) +var i, j, count = integer +prime(1) = false +for i = 2 to limit + prime(i) = true +next i +rem - strike out multiples of each prime found +for i = 2 to sqr(limit) + if prime(i) then + begin + for j = i + i to limit step i + prime(j) = false + next j + end +next i + +rem - use the table for the search +print "Searching up to"; limit; " for additive primes" +count = 0 +for i = 2 to limit + if prime(i) then + if prime(sum.of.digits(i)) then + begin + print using "### "; i; + count = count + 1 + if mod(count, 10) = 0 then print + end +next i +print +print count;" were found" + +end diff --git a/Task/Additive-primes/TypeScript/additive-primes.ts b/Task/Additive-primes/TypeScript/additive-primes.ts new file mode 100644 index 0000000000..d3008744d2 --- /dev/null +++ b/Task/Additive-primes/TypeScript/additive-primes.ts @@ -0,0 +1,29 @@ +function isPrime(n: number): boolean { + if (n < 2) return false; + if (n < 4) return true; + if (n % 2 == 0 || n % 3 == 0) return false; + for (let i = 5; i <= n ** 0.5; i += 6) { + if (n % i == 0 || n % (i+2) == 0) return false; + } + return true; +} + +function sumDigits(x: number): number { + let sum = 0; + while (x > 0) { + sum = sum + (x % 10); + x = Math.floor(x / 10); + } + return sum; +} + +const additivePrimes: number[] = []; + +for (let i = 2; i < 10**7; i++) { + if (isPrime(i) && isPrime(sumDigits(i))) { + additivePrimes.push(i); + } +} + +console.log(additivePrimes); +console.log(`Found ${additivePrimes.length} values`); diff --git a/Task/Address-of-a-variable/Ballerina/address-of-a-variable.ballerina b/Task/Address-of-a-variable/Ballerina/address-of-a-variable.ballerina new file mode 100644 index 0000000000..9e682fb12b --- /dev/null +++ b/Task/Address-of-a-variable/Ballerina/address-of-a-variable.ballerina @@ -0,0 +1,8 @@ +import ballerina/io; + +public function main() { + int[] a = [1, 2, 3, 4]; + int[] b = [1, 2, 3, 4]; + io:println(a == b); // 'true' as values are the same + io:println(a === b); // 'false' as stored at different addresses +} diff --git a/Task/Align-columns/EasyLang/align-columns.easy b/Task/Align-columns/EasyLang/align-columns.easy index 8bac81bda5..3058394bc3 100644 --- a/Task/Align-columns/EasyLang/align-columns.easy +++ b/Task/Align-columns/EasyLang/align-columns.easy @@ -1,5 +1,5 @@ global width inp$[] . -proc read . . +proc read . repeat inp$ = input until inp$ = "" @@ -12,7 +12,7 @@ proc read . . . read # -proc out mode . . +proc out mode . for inp$ in inp$[] ar$[] = strsplit inp$ "$" for s$ in ar$[] diff --git a/Task/Align-columns/Emacs-Lisp/align-columns.l b/Task/Align-columns/Emacs-Lisp/align-columns.l index a073ab13c1..3588e6e422 100644 --- a/Task/Align-columns/Emacs-Lisp/align-columns.l +++ b/Task/Align-columns/Emacs-Lisp/align-columns.l @@ -1,246 +1,129 @@ -(defun rob-even-p (integer) - "Test if INTEGER is even." - (= (% integer 2) 0)) +(defun prepare-data () + "Process data into list of lists." + (let ((all-lines) + (processed-line)) + (dolist (one-line (split-string "Given$a$text$file$of$many$lines,$where$fields$within$a$line$ +are$delineated$by$a$single$'dollar'$character,$write$a$program +that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$ +column$are$separated$by$at$least$one$space. +Further,$allow$for$each$word$in$a$column$to$be$either$left$ +justified,$right$justified,$or$center$justified$within$its$column." "[\n\r]" :OMIT-NULLS)) + (dolist (one-word (split-string one-line "\\$")) + (push one-word processed-line)) + (push (nreverse processed-line) all-lines) + (setq processed-line nil)) + (nreverse all-lines))) -(defun rob-odd-p (integer) - "Test if INTEGER is odd." - (not (rob-even-p integer))) +(defun get-column (column-number data) + "Get words from COLUMN-NUMBER column in DATA." + (let ((column-result)) + (setq column-number (- column-number 1)) + (dolist (line data) + (if (nth column-number line) + (push (nth column-number line) column-result) + (push "" column-result))) + column-result)) -(defun both-odd-or-both-even-p (x y) - "Test if X and Y are both even or both odd." - (or (and (rob-even-p x) (rob-even-p y)) - (and (rob-odd-p x) (rob-odd-p y)))) +(defun calc-column-width (column-number data) + "Calculate padded width for COLUMN-NUMBER in DATA." + (let ((column-words (get-column column-number data))) + (+ 2 (apply #'max (mapcar #'length column-words))))) -(defun word-lengths (words) - "Convert WORDS into list of lengths of each word." - (mapcar 'length words)) +(defun get-last-column (data) + "Find the last column in DATA." + (apply #'max (mapcar #'length data))) -(defun get-one-row (row-number rows-columns-words) - "Get ROW-NUMBER row from ROWS-COLUMNS-WORDS. -ROWS-COLUMNS-WORDS is list of lists in form of row, column, word." - (seq-filter - (lambda (element) - (= row-number (car element))) - rows-columns-words)) +(defun get-column-widths (data) + "Get a list of column widths from DATA." + (let ((current-column 1) + (last-column (get-last-column data)) + (column-widths)) + (while (<= current-column last-column) + (push (calc-column-width current-column data) column-widths) + (setq current-column (1+ current-column))) + (nreverse column-widths))) -(defun get-one-word (row-number column-number rows-columns-words) - "Get one word from ROWS-COLUMNS-WORDS at ROW-NUMBER and COLUMN-NUMBER. -ROWS-COLUMNS-WORDS is list of lists in form of row, column, word." - (delq nil - (mapcar - (lambda (element) - (when (= column-number (nth 1 element)) - (nth 2 element))) - (get-one-row row-number rows-columns-words)))) +(defun get-one-column-width (column-number data) + "Get column width of COLUMN-NUMBER from DATA." + (let ((column-widths (get-column-widths data))) + (nth (- column-number 1) column-widths))) -(defun get-last-row (rows-columns-words) - "Get the number of the last row of ROWS-COLUMNS-WORDS. -ROWS-COLUMNS-WORDS is a list of lists, each list in the form of -row, column, word." - (apply 'max (mapcar 'car rows-columns-words))) +(defun center-align-one-word (word column-width) + "Center align WORD in space of COLUMN-WIDTH." + (let* ((word-width (length word)) + (total-padding (- column-width word-width)) + (pre-padding-length (/ total-padding 2)) + (post-padding-length (- column-width (+ pre-padding-length word-width))) + (pre-padding (make-string pre-padding-length ? )) + (post-padding (make-string post-padding-length ? ))) + (insert (format "%s%s%s" pre-padding word post-padding)))) -(defun list-nth-column (column rows-columns-words) - "List the words in column COLUMN of ROWS-COLUMNS-WORDS. -ROWS-COLUMNS-WORDS is a list of lists, each list in the form of row, column, -word." - (let ((row 1) - (column-word) - (last-row (get-last-row rows-columns-words )) - (matches nil)) - (while (and (<= row last-row) - (<= column (get-last-column rows-columns-words))) - (setq column-word (get-one-word row column rows-columns-words)) - (when (null column-word) - (setq column-word "")) - (push column-word matches) - (setq row (1+ row))) - (flatten-tree (nreverse matches)))) +(defun center-align-one-line (one-line column-widths) + "Center align ONE-LINE using COLUMN-WIDTHS." + (let ((word-position 0)) + (dolist (word one-line) + (center-align-one-word word (nth word-position column-widths)) + (setq word-position (1+ word-position))))) -(defun get-widest-in-column (column) - "Get the widest word in COLUMN, which is a list of words." - (apply #'max (word-lengths column))) +(defun center-align-lines (data) + "Center align columns of words in DATA." + (let ((column-widths (get-column-widths data))) + (dolist (one-line data) + (center-align-one-line one-line column-widths) + (insert (format "%s" "\n"))))) -(defun get-column-width (column) - "Calculate the width of COLUMN, which is a list of words." - (+ (get-widest-in-column column) 2)) +(defun left-align-one-word (word column-width) + "Left align WORD in space of COLUMN-WIDTH." + (let* ((word-width (length word)) + (total-padding (- column-width word-width)) + (pre-padding-length 1) + (post-padding-length (- column-width (+ pre-padding-length word-width))) + (pre-padding (make-string pre-padding-length ? )) + (post-padding (make-string post-padding-length ? ))) + (insert (format "%s%s%s" pre-padding word post-padding)))) -(defun get-column-widths (rows-columns-words) - "Make a list of the column widths in ROWS-COLUMNS-WORDS. -ROWS-COLUMNS-WORDS is list of lists, with each list in the form of row, column, -word." - (let ((last-column (get-last-column rows-columns-words)) - (column 1) - (columns)) - (while (<= column last-column) - (push (get-column-width (list-nth-column column rows-columns-words)) columns) - (setq column (1+ column))) - (reverse columns))) +(defun left-align-one-line (one-line column-widths) + "Left align ONE-LINE using COLUMN-WIDTHS." + (let ((word-position 0)) + (dolist (word one-line) + (left-align-one-word word (nth word-position column-widths)) + (setq word-position (1+ word-position))))) -(defun add-column-widths (widths rows-columns-words) - "Add WIDTHS to ROWS-COLUMNS-WORDS. -ROWS-COLUMNS-WORDS is a list of lists, with each list in the form of row, -column, word. WIDTHS are the widths of each column. Output is a -list of lists, with each list in the form of column-width, row, -column, word." - (let ((new-data) - (new-database) - (column) - (width)) - (dolist (data rows-columns-words) - (setq column (cadr data)) - (setq width (nth (- column 1) widths)) - (setq new-data (push width data)) - (push new-data new-database)) - (nreverse new-database))) +(defun left-align-lines (data) + "Left align columns of words in DATA." + (let ((column-widths (get-column-widths data))) + (dolist (one-line data) + (left-align-one-line one-line column-widths) + (insert (format "%s" "\n"))))) -(defun get-last-column (rows-columns-words) - "Get the number of the last column in ROWS-COLUMNS-WORDS." - (apply 'max (mapcar 'cadr rows-columns-words))) +(defun right-align-one-word (word column-width) + "Right align WORD in space of COLUMN-WIDTH." + (let* ((word-width (length word)) + (total-padding (- column-width word-width)) + (post-padding-length 1) + (pre-padding-length (- column-width (+ post-padding-length word-width))) + (pre-padding (make-string pre-padding-length ? )) + (post-padding (make-string post-padding-length ? ))) + (insert (format "%s%s%s" pre-padding word post-padding)))) -(defun create-rows-columns-words () - "Put text from column-data.txt file in lists. -Each list consists of a row number, a column number, and a word." - (let ((lines) - (line-number 0) - (word-number) - (words)) - (with-temp-buffer - (insert-file-contents "~/Documents/Elisp/column_data.txt") - (beginning-of-buffer) - (dolist (line (split-string (buffer-string) "[\r\n]" :no-nulls)) - (push line lines)) - (setq lines (nreverse lines))) - (dolist (line lines) - (setq line-number (1+ line-number)) - (setq word-number 0) - (dolist (word (split-string line "\\$" :no-nulls)) - (setq word-number (1+ word-number)) - (push (list line-number word-number word) words))) - (setq words (nreverse words)))) +(defun right-align-one-line (one-line column-widths) + "Right align ONE-LINE using COLUMN-WIDTHS." + (let ((word-position 0)) + (dolist (word one-line) + (right-align-one-word word (nth word-position column-widths)) + (setq word-position (1+ word-position))))) -(defun pad-for-center-align (column-width text) - "Pad TEXT to center in space of COLUMN-WIDTH." - (let* ((text-width (length text)) - (total-padding-length (- column-width text-width)) - (pre-padding-length) - (post-padding-length) - (pre-padding) - (post-padding)) - (if (both-odd-or-both-even-p text-width column-width) - (progn - (setq pre-padding-length (/ total-padding-length 2)) - (setq post-padding-length pre-padding-length)) - (setq pre-padding-length (+ (/ total-padding-length 2) 1)) - (setq post-padding-length (- pre-padding-length 1))) - (setq pre-padding (make-string pre-padding-length ? )) - (setq post-padding (make-string post-padding-length ? )) - (format "%s%s%s" pre-padding text post-padding))) +(defun right-align-lines (data) + "Right align columns of words in DATA." + (let ((column-widths (get-column-widths data))) + (dolist (one-line data) + (right-align-one-line one-line column-widths) + (insert (format "%s" "\n"))))) -(defun create-a-center-aligned-line (widths-1row-columns-words) - "Create a centered line based on WIDTHS-1ROW-COLUMNS-WORDS. -WIDTHS-1ROW-COLUMNS-WORDS is a list of lists. Each list consists -of the column-width, the row number, the column number, and the -word. The row number is the same in all lists." - (let ((full-line "") - (next-section)) - (insert "\n") - (dolist (word-data widths-1row-columns-words) - ;; below, nth 0 is the column width, nth 3 is the word - (setq next-section (pad-for-center-align (nth 0 word-data) (nth 3 word-data))) - (setq full-line (concat full-line next-section))) - (insert full-line))) - -(defun pad-for-left-align (column-width text) - "Pad TEXT to left-align in space of COLUMN-WIDTH." - (let* ((text-width (length text)) - (post-padding-length (- column-width text-width))) - (setq post-padding (make-string post-padding-length ? )) - (format "%s%s" text post-padding))) - -(defun create-a-left-aligned-line (widths-1row-columns-words) - "Create a left-aligned line based on WIDTHS-1ROW-COLUMNS-WORDS. -Each element of WIDTHS-1ROW-COLUMNS-WORDS consists of the column -width, the row number, the column number, and the word. The row -number is the same in every case." - (let ((full-line "") - (next-section)) - (insert "\n") - (dolist (one-item widths-1row-columns-words) - (setq next-section (pad-for-left-align (nth 0 one-item) (nth 3 one-item))) - (setq full-line (concat full-line next-section))) - (insert full-line))) - -(defun pad-for-right-align (column-width text) - "Pad TEXT to right-align in space of COLUMN-WIDTH." - (let* ((text-width (length text)) - (pre-padding-length (- column-width text-width))) - (setq pre-padding (make-string pre-padding-length ? )) - (format "%s%s" pre-padding text))) - -(defun create-a-right-aligned-line (widths-1row-columns-words) - "Create a right-aligned line based on WIDTHS-1ROW-COLUMNS-WORDS. -Each element of WIDTHS-1ROW-COLUMNS-WORDS consists of the column -width, the row number, the column number, and the word. The row -number is the same in every case." - (let ((full-line "") - (next-section)) - (insert "\n") - (dolist (one-item widths-1row-columns-words) - (setq next-section (pad-for-right-align (nth 0 one-item) (nth 3 one-item))) - (setq full-line (concat full-line next-section))) - (insert full-line))) - -(defun left-align-lines (rows-columns-words) - "Write ROWS-COLUMNS-WORDS in left-aligned columns. -ROWS-COLUMNS-WORDS is a list of lists. Each list consists of the -row number, the column number, and the word." - (let* ((row-number 1) - (column-widths (get-column-widths rows-columns-words)) - (last-row (get-last-row rows-columns-words)) - (one-row) - (width-place 0)) - (while (<= row-number last-row) - (setq one-row (get-one-row row-number rows-columns-words)) - (setq one-row (add-column-widths column-widths one-row)) - (create-a-left-aligned-line one-row) - (setq row-number (1+ row-number)) - (setq width-place (1+ width-place))))) - -(defun right-align-lines (rows-columns-words) - "Write ROWS-COLUMNS-WORDS in right-aligned columns. -ROWS-COLUMNS-WORDS is a list of lists. Each list consists of the -row number, the column number, and the word." - (let* ((row-number 1) - (column-widths (get-column-widths rows-columns-words)) - (last-row (get-last-row rows-columns-words)) - (one-row) - (width-place 0)) - (while (<= row-number last-row) - (setq one-row (get-one-row row-number rows-columns-words)) - (setq one-row (add-column-widths column-widths one-row)) - (create-a-right-aligned-line one-row) - (setq row-number (1+ row-number)) - (setq width-place (1+ width-place))))) - -(defun center-align-lines (rows-columns-words) - "Write ROWS-COLUMNS-WORDS in center-aligned columns. -ROWS-COLUMNS-WORDS is a list of lists. Each list consists of the -row number, the column number, and the word." - (let* ((row-number 1) - (column-widths (get-column-widths rows-columns-words)) - (last-row (get-last-row rows-columns-words)) - (one-row) - (width-place 0)) - (while (<= row-number last-row) - (setq one-row (get-one-row row-number rows-columns-words)) - (setq one-row (add-column-widths column-widths one-row)) - (create-a-center-aligned-line one-row) - (setq row-number (1+ row-number)) - (setq width-place (1+ width-place))))) - -(defun align-lines (alignment rows-columns-words) - "Write ROWS-COLUMNS-WIDTHS with given ALIGNMENT. -ROWS-COLUMNS-WIDTHS consists of a list of lists. Each internal list contains width of column, row number, column number, and a word." +(defun align-lines (alignment data) + "Write DATA with given ALIGNMENT. +DATA consists of a list of lists. Each internal list conists of a list +of words." (let ((align-function (pcase alignment ('left 'left-align-lines) ("left" 'left-align-lines) @@ -248,4 +131,4 @@ ROWS-COLUMNS-WIDTHS consists of a list of lists. Each internal list contains wid ("center" 'center-align-lines) ('right 'right-align-lines) ("right" 'right-align-lines)))) - (funcall align-function rows-columns-words))) + (funcall align-function data))) diff --git a/Task/Aliquot-sequence-classifications/EasyLang/aliquot-sequence-classifications.easy b/Task/Aliquot-sequence-classifications/EasyLang/aliquot-sequence-classifications.easy index e25f92c48c..40a22a8833 100644 --- a/Task/Aliquot-sequence-classifications/EasyLang/aliquot-sequence-classifications.easy +++ b/Task/Aliquot-sequence-classifications/EasyLang/aliquot-sequence-classifications.easy @@ -1,7 +1,5 @@ fastfunc sumprop num . - if num = 1 - return 0 - . + if num = 1 : return 0 sum = 1 root = sqrt num i = 2 @@ -16,60 +14,36 @@ fastfunc sumprop num . . return sum . -func$ tostr ar[] . - for v in ar[] - s$ &= " " & v - . - return s$ -. func$ class k . oldk = k newk = sumprop oldk oldk = newk seq[] &= newk - if newk = 0 - return "terminating " & tostr seq[] - . - if newk = k - return "perfect " & tostr seq[] - . + if newk = 0 : return "terminating " & seq[] + if newk = k : return "perfect " & seq[] newk = sumprop oldk oldk = newk seq[] &= newk - if newk = 0 - return "terminating " & tostr seq[] - . - if newk = k - return "amicable " & tostr seq[] - . + if newk = 0 : return "terminating " & seq[] + if newk = k : return "amicable " & seq[] for t = 4 to 16 newk = sumprop oldk seq[] &= newk - if newk = 0 - return "terminating " & tostr seq[] - . - if newk = k - return "sociable (period " & t - 1 & ") " & tostr seq[] - . - if newk = oldk - return "aspiring " & tostr seq[] - . + if newk = 0 : return "terminating " & seq[] + if newk = k : return "sociable (period " & t - 1 & ") " & seq[] + if newk = oldk : return "aspiring " & seq[] for i to len seq[] - 1 - if newk = seq[i] - return "cyclic (at " & newk & ") " & tostr seq[] - . - . - if newk > 140737488355328 - return "non-terminating (term > 140737488355328) " & tostr seq[] + if newk = seq[i] : return "cyclic (at " & newk & ") " & seq[] . + if newk > 140737488355328 : return "non-terminating (term > 140737488355328) " & seq[] oldk = newk . - return "non-terminating (after 16 terms) " & tostr seq[] + return "non-terminating (after 16 terms) " & seq[] . print "Number classification sequence" for j = 1 to 12 - print j & " " & class j + print j & ": " & class j . for j in [ 28 496 220 1184 12496 1264460 790 909 562 1064 1488 15355717786080 ] - print j & " " & class j + print j & ": " & class j . diff --git a/Task/Almkvist-Giullera-formula-for-pi/00-TASK.txt b/Task/Almkvist-Giullera-formula-for-pi/00-TASK.txt index b3424c960c..9dd91723eb 100644 --- a/Task/Almkvist-Giullera-formula-for-pi/00-TASK.txt +++ b/Task/Almkvist-Giullera-formula-for-pi/00-TASK.txt @@ -1,27 +1,27 @@ -The Almkvist-Giullera formula for calculating   1/π2   is based on the Calabi-Yau +The Almkvist-Giullera formula for calculating \frac{1}{\pi^2} is based on the Calabi-Yau differential equations of order 4 and 5,   which were originally used to describe certain manifolds in string theory. The formula is: -::::: 1/π2 = (25/3) ∑0 ((6n)! / (n!6))(532n2 + 126n + 9) / 10002n+1 +:\frac{1}{\pi^{2}}=32 \sum_{n=0}^{\infty}\frac{(6n)!}{3 \cdot n!^{6}}(532n^{2}+126n+9)\frac{1}{10^{6n+3}} -This formula can be used to calculate the constant   π-2,   and thus to calculate   π. +This formula can be used to calculate the constant \frac{1}{\pi^2},   and thus to calculate \pi. Note that, because the product of all terms but the power of 1000 can be calculated as an integer, the terms in the series can be separated into a large integer term: -::::: (25) (6n)! (532n2 + 126n + 9) / (3(n!)6)     (***) +:\frac{32(6n)!}{3 \cdot n!^{6}}(532n^{2}+126n+9) multiplied by a negative integer power of 10: -::::: 10-(6n + 3) +:10^{-(6n + 3)} ;Task: :* Print the integer portions (the starred formula, which is without the power of 1000 divisor) of the first 10 terms of the series. -:* Use the complete formula to calculate and print π to 70 decimal digits of precision. +:* Use the complete formula to calculate and print \pi to 70 decimal digits of precision. ;Reference: diff --git a/Task/Almost-prime/00-TASK.txt b/Task/Almost-prime/00-TASK.txt index c607041068..adb7f91ccd 100644 --- a/Task/Almost-prime/00-TASK.txt +++ b/Task/Almost-prime/00-TASK.txt @@ -7,7 +7,7 @@ A   [[wp:Almost prime|k-Almost-prime]]   is a natural number   1 <= K <= 5. +Write a function/method/subroutine/... that generates k-almost primes and use it to create a table here of the first ten members of k-Almost primes for   1 \le K \le 5. ;Related tasks: diff --git a/Task/Almost-prime/Ballerina/almost-prime.ballerina b/Task/Almost-prime/Ballerina/almost-prime.ballerina new file mode 100644 index 0000000000..4591f6997f --- /dev/null +++ b/Task/Almost-prime/Ballerina/almost-prime.ballerina @@ -0,0 +1,32 @@ +import ballerina/io; + +function kPrime(int m, int k) returns boolean { + int n = m; // make mutable + int nf = 0; + foreach int i in 2...n { + while (n % i) == 0 { + if nf == k { return false; } + nf += 1; + n /= i; + } + } + return nf == k; +} + +function gen(int k, int m) returns int[] { + int[] r = []; + r.setLength(m); + int n = 2; + foreach int i in 0 ..< r.length() { + while !kPrime(n, k) { n += 1; } + r[i] = n; + n += 1; + } + return r; +} + +public function main() { + foreach int k in 1...5 { + io:println(k, " ", gen(k, 10)); + } +} diff --git a/Task/Almost-prime/Clojure/almost-prime.clj b/Task/Almost-prime/Clojure/almost-prime.clj index c35a61bd6b..3adf67d1cc 100644 --- a/Task/Almost-prime/Clojure/almost-prime.clj +++ b/Task/Almost-prime/Clojure/almost-prime.clj @@ -19,5 +19,3 @@ (println (for [k (range 1 6)] (println "k:" k (divisors-k k 10)))) - -} diff --git a/Task/Almost-prime/EasyLang/almost-prime.easy b/Task/Almost-prime/EasyLang/almost-prime.easy index 67e268e1f0..72cd4d8d65 100644 --- a/Task/Almost-prime/EasyLang/almost-prime.easy +++ b/Task/Almost-prime/EasyLang/almost-prime.easy @@ -2,27 +2,23 @@ func kprime n k . i = 2 while i <= n while n mod i = 0 - if f = k - return 0 - . + if f = k : return 0 f += 1 n /= i . i += 1 . - if f = k - return 1 - . + if f = k : return 1 return 0 . for k = 1 to 5 write "k=" & k & " : " i = 2 - c = 0 - while c < 10 + cnt = 0 + while cnt < 10 if kprime i k = 1 write i & " " - c += 1 + cnt += 1 . i += 1 . diff --git a/Task/Almost-prime/Forth/almost-prime.fth b/Task/Almost-prime/Forth/almost-prime.fth new file mode 100644 index 0000000000..77210f5046 --- /dev/null +++ b/Task/Almost-prime/Forth/almost-prime.fth @@ -0,0 +1,38 @@ +: multiplicity ( n1 n2 -- n1 n2 n3 ) + 0 >r + begin + 2dup mod 0= + while + r> 1+ >r + tuck / swap + repeat + r> ; + +: k-prime? ( n k -- ? ) + >r 0 >r 2 + begin + 2dup dup * >= if 2r@ > else false then + while + multiplicity r> + >r 1+ + repeat + drop + 1 > if 1 else 0 then r> + r> = ; + +: next-k-prime ( n k -- n ) + begin + swap 1+ swap + 2dup k-prime? + until drop ; + +: main + 6 1 do + ." k = " i 1 .r ." :" + 1 10 0 do + j next-k-prime + dup 3 .r space + loop + drop cr + loop ; + +main +bye diff --git a/Task/Almost-prime/REXX/almost-prime-1.rexx b/Task/Almost-prime/REXX/almost-prime-1.rexx deleted file mode 100644 index e5652afb7c..0000000000 --- a/Task/Almost-prime/REXX/almost-prime-1.rexx +++ /dev/null @@ -1,35 +0,0 @@ -/*REXX program computes and displays the first N K─almost primes from 1 ──► K. */ -parse arg N K . /*get optional arguments from the C.L. */ -if N=='' | N=="," then N=10 /*N not specified? Then use default.*/ -if K=='' | K=="," then K= 5 /*K " " " " " */ - /*W: is the width of K, used for output*/ - do m=1 for K; $=2**m; fir=$ /*generate & assign 1st K─almost prime.*/ - #=1; if #==N then leave /*#: K─almost primes; Enough are found?*/ - #=2; $=$ 3*(2**(m-1)) /*generate & append 2nd K─almost prime.*/ - if #==N then leave /*#: K─almost primes; Enough are found?*/ - if m==1 then _=fir + fir /* [↓] gen & append 3rd K─almost prime*/ - else do; _=9 * (2**(m-2)); #=3; $=$ _; end - do j=_ + m - 1 until #==N /*process an K─almost prime N times.*/ - if factr()\==m then iterate /*not the correct K─almost prime? */ - #=# + 1; $=$ j /*bump K─almost counter; append it to $*/ - end /*j*/ /* [↑] generate N K─almost primes.*/ - say right(m, length(K))"─almost ("N') primes:' $ - end /*m*/ /* [↑] display a line for each K─prime*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -factr: z=j; do f=0 while z// 2==0; z=z% 2; end /*divisible by 2.*/ - do f=f while z// 3==0; z=z% 3; end /*divisible " 3.*/ - do f=f while z// 5==0; z=z% 5; end /*divisible " 5.*/ - do f=f while z// 7==0; z=z% 7; end /*divisible " 7.*/ - do f=f while z//11==0; z=z%11; end /*divisible " 11.*/ - do f=f while z//13==0; z=z%13; end /*divisible " 13.*/ - do p=17 by 6 while p<=z /*insure P isn't divisible by three. */ - parse var p '' -1 _ /*obtain the right─most decimal digit. */ - /* [↓] fast check for divisible by 5. */ - if _\==5 then do; do f=f+1 while z//p==0; z=z%p; end; f=f-1; end /*÷ by P? */ - if _ ==3 then iterate /*fast check for X divisible by five.*/ - x=p+2; do f=f+1 while z//x==0; z=z%x; end; f=f-1 /*÷ by X? */ - end /*i*/ /* [↑] find all the factors in Z. */ - - if f==0 then return 1 /*if prime (f==0), then return unity.*/ - return f /*return to invoker the number of divs.*/ diff --git a/Task/Almost-prime/REXX/almost-prime-2.rexx b/Task/Almost-prime/REXX/almost-prime-2.rexx deleted file mode 100644 index d0dbbe54d6..0000000000 --- a/Task/Almost-prime/REXX/almost-prime-2.rexx +++ /dev/null @@ -1,66 +0,0 @@ -/*REXX program computes and displays the first N K─almost primes from 1 ──► K. */ -parse arg N K . /*obtain optional arguments from the CL*/ -if N=='' | N==',' then N=10 /*N not specified? Then use default.*/ -if K=='' | K==',' then K= 5 /*K " " " " " */ -nn=N; N=abs(N); w=length(K) /*N positive? Then show K─almost primes*/ -limit= (2**K) * N / 2 /*this is the limit for most K-primes. */ -if N==1 then limit=limit * 2 /* " " " " " a N of 1.*/ -if K==1 then limit=limit * 4 /* " " " " " a K─prime " 2.*/ -if K==2 then limit=limit * 2 /* " " " " " " " " 4.*/ -if K==3 then limit=limit * 3 % 2 /* " " " " " " " " 8.*/ -call genPrimes limit + 1 /*generate primes up to the LIMIT + 1.*/ -say 'The highest prime computed: ' @.# " (under the limit of " limit').' -say /* [↓] define where 1st K─prime is odd*/ -d.=0; d.2= 2; d.3 = 4; d.4 = 7; d.5 = 13; d.6 = 22; d.7 = 38; d.8=63 - d.9=102; d.10=168; d.11=268; d.12=426; d.13=673; d.14=1064 -d!=0 - do m=1 for K; d!=max(d!,d.m) /*generate & assign 1st K─almost prime.*/ - mr=right(m,w); mm=m-1 - - $=; do #=1 to min(N, d!) /*assign some doubled K─almost primes. */ - $=$ d.mm.# * 2 - end /*#*/ - #=#-1 - if m==1 then from=2 - else from=1 + word($, words($) ) - - do j=from until #==N /*process an K─almost prime N times.*/ - if factr()\==m then iterate /*not the correct K─almost prime? */ - #=#+1; $=$ j /*bump K─almost counter; append it to $*/ - end /*j*/ /* [↑] generate N K─almost primes.*/ - - if nn>0 then say mr"─almost ("N') primes:' $ - else say ' the last' mr "K─almost prime: " word($, words($)) - /* [↓] assign K─almost primes.*/ - do q=1 for #; d.m.q=word($,q) ; end /*q*/ - do q=1 for #; if d.m.q\==d.mm.q*2 then leave; end /*q*/ - /* [↑] count doubly-duplicates*/ -/*──── say copies('─',40) 'for ' m", " q-1 'numbers were doubly─duplicated.' ────*/ -/*──── say ────*/ - end /*m*/ /* [↑] display a line for each K─prime*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -factr: if #.j\==. then return #.j - z=j; do f=0 while z// 2==0; z=z% 2; end /*÷ by 2*/ - do f=f while z// 3==0; z=z% 3; end /*÷ " 3*/ - do f=f while z// 5==0; z=z% 5; end /*÷ " 5*/ - do f=f while z// 7==0; z=z% 7; end /*÷ " 7*/ - do f=f while z//11==0; z=z%11; end /*÷ " 11*/ - do f=f while z//13==0; z=z%13; end /*÷ " 13*/ - do f=f while z//17==0; z=z%17; end /*÷ " 17*/ - do f=f while z//19==0; z=z%19; end /*÷ " 19*/ - - do i=9 while @.i<=z; d=@.i /*divide by some higher primes. */ - do f=f while z//d==0; z=z%d; end /*is Z divisible by the prime D ? */ - end /*i*/ /* [↑] find all factors in Z. */ - - if f==0 then f=1; #.j=f; return f /*Is prime (f≡0)? Then return unity. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genPrimes: arg x; @.=; @.1=2; @.2=3; #.=.; #=2; s.#=@.#**2 - do j=@.# +2 by 2 to x /*only find odd primes from here on. */ - do p=2 while s.p<=j /*divide by some known low odd primes. */ - if j//@.p==0 then iterate j /*Is J divisible by X? Then ¬ prime.*/ - end /*p*/ /* [↓] a prime (J) has been found. */ - #=#+1; @.#=j; #.j=1; s.#=j*j /*bump prime count, and also assign ···*/ - end /*j*/ /* ··· the # of factors, prime, prime².*/ - return /* [↑] not an optimal prime generator.*/ diff --git a/Task/Almost-prime/REXX/almost-prime-3.rexx b/Task/Almost-prime/REXX/almost-prime.rexx similarity index 92% rename from Task/Almost-prime/REXX/almost-prime-3.rexx rename to Task/Almost-prime/REXX/almost-prime.rexx index 2c8d9e5b73..69046a42f9 100644 --- a/Task/Almost-prime/REXX/almost-prime-3.rexx +++ b/Task/Almost-prime/REXX/almost-prime.rexx @@ -1,6 +1,8 @@ include Settings -say version; say 'k-Almost primes'; say +say 'ALMOST PRIME - 3 Mar 2025' +say version +say arg n k m say 'Direct approach using Factors' numeric digits 16 diff --git a/Task/Amb/Ballerina/amb.ballerina b/Task/Amb/Ballerina/amb.ballerina new file mode 100644 index 0000000000..3f0fdce8b4 --- /dev/null +++ b/Task/Amb/Ballerina/amb.ballerina @@ -0,0 +1,35 @@ +import ballerina/io; + +string[] finalRes = []; + +function amb(string[][] wordsets, string[] res) returns boolean { + if wordsets.length() == 0 { + finalRes.push(...res); + return true; + } + string s = ""; + int l = res.length(); + if l > 0 { s = res[l - 1]; } + res.push(""); + foreach string word in wordsets[0] { + res[l] = word; + if l > 0 && s[s.length() - 1] != res[l][0] { continue; } + if amb(wordsets.slice(1), [...res]) { return true; } + } + return false; +} + +public function main() { + var wordsets = [ + [ "the", "that", "a" ], + [ "frog", "elephant", "thing" ], + [ "walked", "treaded", "grows" ], + [ "slowly", "quickly" ] + ]; + + if amb(wordsets, []) { + io:println(string:'join(" ", ...finalRes)); + } else { + io:println("No amb found"); + } +} diff --git a/Task/Amb/EasyLang/amb.easy b/Task/Amb/EasyLang/amb.easy new file mode 100644 index 0000000000..4c3e80dd21 --- /dev/null +++ b/Task/Amb/EasyLang/amb.easy @@ -0,0 +1,31 @@ +func ambtest a$ b$ . + if substr a$ len a$ 1 = substr b$ 1 1 : return 1 + return 0 +. +proc amb &opts$[][] pos prev$ &res$[] &found . + if pos = 0 + found = 1 + res$[] = [ ] + return + . + for curr$ in opts$[pos][] + if prev$ = "" or ambtest curr$ prev$ = 1 + amb opts$[][] (pos - 1) curr$ res$[] found + if found = 1 + res$[] &= curr$ + return + . + . + . + found = 0 + return +. +proc main . + sets$[][] = [ [ "the" "that" "a" ] [ "frog" "elephant" "thing" ] [ "walked" "treaded" "grows" ] [ "slowly" "quickly" ] ] + h = len sets$[][] + amb sets$[][] h "" res$[] found + if found = 1 + print res$[] + . +. +main diff --git a/Task/Amb/Elena/amb.elena b/Task/Amb/Elena/amb.elena index 158379a738..2627185b46 100644 --- a/Task/Amb/Elena/amb.elena +++ b/Task/Amb/Elena/amb.elena @@ -82,12 +82,12 @@ public program() new object[]{"walked", "treaded", "grows"}, new object[]{"slowly", "quickly"}) .seek::(a,b,c,d => joinable(a,b) && joinable(b,c) && joinable(c,d) ) - .do::(a,b,c,d) { console.printLine(a," ",b," ",c," ",d) } + .do::(a,b,c,d) { Console.printLine(a," ",b," ",c," ",d) } } catch(Exception e) { - console.printLine("AMB is angry") + Console.printLine("AMB is angry") }; - console.readChar() + Console.readChar() } diff --git a/Task/Amb/Langur/amb.langur b/Task/Amb/Langur/amb.langur index 7f047193bb..a2a6dca16f 100644 --- a/Task/Amb/Langur/amb.langur +++ b/Task/Amb/Langur/amb.langur @@ -6,7 +6,7 @@ val wordsets = [ ] val alljoin = fn words: for[=true] i of len(words)-1 { - if words[i][-1] != words[i+1][1]: break = false + if words[i][-1] != words[i+1][1]: break val=false } # amb expects 2 or more arguments diff --git a/Task/Amicable-pairs/EasyLang/amicable-pairs.easy b/Task/Amicable-pairs/EasyLang/amicable-pairs.easy index 648a0ba8ce..dc3d7e0186 100644 --- a/Task/Amicable-pairs/EasyLang/amicable-pairs.easy +++ b/Task/Amicable-pairs/EasyLang/amicable-pairs.easy @@ -1,17 +1,13 @@ func sumdivs n . sum = 1 for d = 2 to sqrt n - if n mod d = 0 - sum += d + n div d - . + if n mod d = 0 : sum += d + n div d . return sum . for n = 1 to 20000 m = sumdivs n - if m > n - if sumdivs m = n - print n & " " & m - . + if m > n and sumdivs m = n + print n & " " & m . . diff --git a/Task/Amicable-pairs/Elena/amicable-pairs-1.elena b/Task/Amicable-pairs/Elena/amicable-pairs-1.elena index 62814d6243..06a9bfd320 100644 --- a/Task/Amicable-pairs/Elena/amicable-pairs-1.elena +++ b/Task/Amicable-pairs/Elena/amicable-pairs-1.elena @@ -31,6 +31,6 @@ public program() { N.AmicablePairs.forEach::(pair) { - console.printLine(pair.Item1, " ", pair.Item2) + Console.printLine(pair.Item1, " ", pair.Item2) } } diff --git a/Task/Amicable-pairs/Elena/amicable-pairs-2.elena b/Task/Amicable-pairs/Elena/amicable-pairs-2.elena index 8ac6072f0d..a7d4a255ca 100644 --- a/Task/Amicable-pairs/Elena/amicable-pairs-2.elena +++ b/Task/Amicable-pairs/Elena/amicable-pairs-2.elena @@ -27,7 +27,7 @@ extension op : IntNumber public program() { - N.AmicablePairs.forEach::(var Tuple pair) + (N.AmicablePairs)::forEach>::(pair) { console.printLine(pair.Item1, " ", pair.Item2) } diff --git a/Task/Amicable-pairs/Elena/amicable-pairs-3.elena b/Task/Amicable-pairs/Elena/amicable-pairs-3.elena index ede0ca6ccd..90b88b9964 100644 --- a/Task/Amicable-pairs/Elena/amicable-pairs-3.elena +++ b/Task/Amicable-pairs/Elena/amicable-pairs-3.elena @@ -19,7 +19,7 @@ public sealed AmicablePairs this max := max } - yieldable Tuple next() + yield Enumerator> enumerator() { List divsums := Range.new(0, max + 1).selectBy::(int i => ProperDivisors(i).summarize(0)); @@ -27,19 +27,17 @@ public sealed AmicablePairs { int sum := divsums[i]; if(i < sum && sum <= divsums.Length && divsums[sum] == i) { - $yield new Tuple(i, sum); + :yield new Tuple(i, sum); } }; - - ^ nil } } public program() { - auto e := new AmicablePairs(Limit); - for(auto pair := e.next(); pair != nil) - { - console.printLine(pair.Item1, " ", pair.Item2) + auto e := new AmicablePairs(Limit).enumerator(); + while (e.next()) { + auto pair := *e; + console.printLine(pair.Item1, " ", pair.Item2) } } diff --git a/Task/Amicable-pairs/PascalABC.NET/amicable-pairs.pas b/Task/Amicable-pairs/PascalABC.NET/amicable-pairs.pas new file mode 100644 index 0000000000..e6b4e2cd91 --- /dev/null +++ b/Task/Amicable-pairs/PascalABC.NET/amicable-pairs.pas @@ -0,0 +1,9 @@ +function k(n : Integer) := 1.to(n div 2).where(d->n mod d=0).sum; +begin +1.to(20000).Where(n->n=k(k(n))) +.Select(n-> + begin var m:=k(n); +Result:=(min(n,m),max(n,m)); + end).where(v->v[0]$'{v[0]}-{v[1]}').Printlines; +end. diff --git a/Task/Amicable-pairs/REXX/amicable-pairs-2.rexx b/Task/Amicable-pairs/REXX/amicable-pairs-2.rexx index 6c7c579692..0df72c5809 100644 --- a/Task/Amicable-pairs/REXX/amicable-pairs-2.rexx +++ b/Task/Amicable-pairs/REXX/amicable-pairs-2.rexx @@ -1,28 +1,26 @@ -/*REXX program calculates and displays all amicable pairs up to a given number. */ -parse arg H .; if H=='' | H=="," then H= 20000 /*get optional arguments (high limit).*/ -w= length(H) ; low= 220 /*W: used for columnar output alignment*/ -@.=. /* [↑] LOW is lowest amicable number. */ - do k=low for H-low; _= sigma(k) /*generate sigma sums for a range of #s*/ - if _>=low then @.k= _ /*only keep the pertinent sigma sums. */ - end /*k*/ /* [↑] process a range of integers. */ -#= 0 /*number of amicable pairs found so far*/ - do m=low to H; n= @.m /*start the search at the lowest number*/ - if m==@.n then do /*If equal, might be an amicable number*/ - if m==n then iterate /*Is this a perfect number? Then skip.*/ - #= # + 1 /*bump the amicable pair counter. */ - say right(m,w) ' and ' right(n,w) " are an amicable pair." - m= n /*start M (DO index) from N. */ - end - end /*m*/ +-- 8 May 2025 +include Settings + +say 'AMICABLE PAIRS' +say version say -say # ' amicable pairs found up to ' H /*display count of the amicable pairs. */ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sigma: procedure; parse arg x; od= x // 2 /*use either EVEN or ODD integers. */ - s= 1 /*set initial sigma sum to unity. ___*/ - do j=2+od by 1+od while j*j 0); n = Abs(n) +a = Amicables(n) +say time('e') a 'amicable pairs collected' +if show then do + do i = 1 to a + say time('e') amic.1.i 'and' amic.2.i 'are an amicable pair' + end +end +say time('e') 'seconds' +exit + +include Sequences +include Numbers +include Functions +include Special +include Abend diff --git a/Task/Amicable-pairs/REXX/amicable-pairs-3.rexx b/Task/Amicable-pairs/REXX/amicable-pairs-3.rexx deleted file mode 100644 index 5ceabf3e71..0000000000 --- a/Task/Amicable-pairs/REXX/amicable-pairs-3.rexx +++ /dev/null @@ -1,30 +0,0 @@ -/*REXX program calculates and displays all amicable pairs up to a given number. */ -parse arg H .; if H=='' | H=="," then H=20000 /*get optional arguments (high limit).*/ -w=length(H) ; low=220 /*W: used for columnar output alignment*/ -x= 220 34765731 6232 87633 284 12285 10856 36939357 6368 5684679 /*S minimums.*/ - do i=0 for 10; $.i= word(x, i + 1); end /*minimum amicable #s for last dec dig.*/ -@.= /* [↑] LOW is lowest amicable number. */ -#= 0 /*number of amicable pairs found so far*/ - do k=low for H-low /*generate sigma sums for a range of #s*/ - parse var k '' -1 D /*obtain last decimal digit of K. */ - if k<$.D then iterate /*if no need to compute, then skip it. */ - _= sigma(k) /*generate sigma sum for the number K.*/ - @.k= _ /*only keep the pertinent sigma sums. */ - if k==@._ then do /*is it a possible amicable number ? */ - if _==k then iterate /*Is it a perfect number? Then skip it*/ - #= # + 1 /*bump the amicable pair counter. */ - say right(_, w) ' and ' right(k, w) " are an amicable pair." - end - end /*k*/ /* [↑] process a range of integers. */ -say -say # 'amicable pairs found up to' H /*display the count of amicable pairs. */ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sigma: procedure; parse arg x; od= x // 2 /*use either EVEN or ODD integers. */ - s= 1 /*set initial sigma sum to unity. ___*/ - do j=2+od by 1+od while j*j1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end - return r -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sigma: procedure; parse arg x; od= x // 2 /*use either EVEN or ODD integers. */ - s= 1 /*set initial sigma sum to unity. ___*/ - do j=2+od by 1+od to iSqrt(x) /*divide by all integers up to the √ x */ - if x//j==0 then s= s + j + x%j /*add the two divisors to the sum. */ - end /*j*/ /* [↑] % is the REXX integer division.*/ - /* ___ */ - if j*j==x then return s + j /*Was X a square? If so, add √ X */ - return s /*return (sigma) sum of the divisors. */ diff --git a/Task/Amicable-pairs/REXX/amicable-pairs-5.rexx b/Task/Amicable-pairs/REXX/amicable-pairs-5.rexx deleted file mode 100644 index 5ee02d6498..0000000000 --- a/Task/Amicable-pairs/REXX/amicable-pairs-5.rexx +++ /dev/null @@ -1,34 +0,0 @@ -/*REXX program calculates and displays all amicable pairs up to a given number. */ -parse arg H .; if H=='' | H=="," then H=20000 /*get optional arguments (high limit).*/ -w= length(H) ; low= 220 /*W: used for columnar output alignment*/ -x= 220 34765731 6232 87633 284 12285 10856 36939357 6368 5684679 /*S minimums.*/ - do i=0 for 10; $.i= word(x, i + 1); end /*minimum amicable #s for last dec dig.*/ -@.= /* [↑] LOW is lowest amicable number. */ -#= 0 /*number of amicable pairs found so far*/ - do k=low for H-low /*generate sigma sums for a range of #s*/ - parse var k '' -1 D /*obtain last decimal digit of K. */ - if k<$.D then iterate /*if no need to compute, then skip it. */ - _= sigma(k) /*generate sigma sum for the number K.*/ - @.k= _ /*only keep the pertinent sigma sums. */ - if k==@._ then do /*is it a possible amicable number ? */ - if _==k then iterate /*Is it a perfect number? Then skip it*/ - #= # + 1 /*bump the amicable pair counter. */ - say right(_, w) ' and ' right(k, w) " are an amicable pair." - end - end /*k*/ /* [↑] process a range of integers. */ -say -say # 'amicable pairs found up to' H /*display the count of amicable pairs. */ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -iSqrt: procedure; parse arg x; r= 0; q= 1; do while q<=x; q= q * 4; end - do while q>1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end - return r -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sigma: procedure; parse arg x; od= x // 2 /*use either EVEN or ODD integers. */ - s= 1 /*set initial sigma sum to unity. ___*/ - do j=2+od by 1+od to iSqrt(x) /*divide by all integers up to the √ x */ - if x//j==0 then s= s + j + x%j /*add the two divisors to the sum. */ - end /*j*/ /* [↑] % is the REXX integer division.*/ - /* ___ */ - if j*j==x then return s + j /*Was X a square? If so, add √ X */ - return s /*return (sigma) sum of the divisors. */ diff --git a/Task/Amicable-pairs/REXX/amicable-pairs-6.rexx b/Task/Amicable-pairs/REXX/amicable-pairs-6.rexx deleted file mode 100644 index cec5b774eb..0000000000 --- a/Task/Amicable-pairs/REXX/amicable-pairs-6.rexx +++ /dev/null @@ -1,43 +0,0 @@ -include Settings - -say version; say 'Amicable pairs'; say -arg n -numeric digits 16 -if n = '' then - n = 20000 -show = (n > 0); n = Abs(n) -/* Get amicable pairs */ -a = Amicables(n) -say time('e') a 'amicable pairs collected' -/* Show amical pairs */ -if show then do - do i = 1 to a - say time('e') amic.amicable.1.i 'and' amic.amicable.2.i 'are an amicable pair' - end -end -say time('e') 'seconds' -exit - -Amicables: -/* Amicable number pairs */ -procedure expose glob. amic. -arg x -/* Init */ -amic. = 0 -/* Scan for amicable pairs */ -n = 0 -do i = 1 to x - s = Sigma(i)-i; glob.sigma.i = s - if i = glob.sigma.s then do - if s = i then - iterate - n = n+1 - amic.amicable.1.n = s; amic.amicable.2.n = i - end -end -amic.0 = n -return n - -include Numbers -include Functions -include Abend diff --git a/Task/Anagrams-Deranged-anagrams/Crystal/anagrams-deranged-anagrams.cr b/Task/Anagrams-Deranged-anagrams/Crystal/anagrams-deranged-anagrams.cr new file mode 100644 index 0000000000..0e8a15fdbb --- /dev/null +++ b/Task/Anagrams-Deranged-anagrams/Crystal/anagrams-deranged-anagrams.cr @@ -0,0 +1,19 @@ +def deranged? (a, b) + a.chars.zip(b.chars).all? {|char_a, char_b| char_a != char_b} +end + +def find_derangements (list) + list.each_combination(2) {|(a, b)| return a, b if deranged?(a, b)} + nil +end + +anagram = File.read_lines("unixdict.txt").group_by {|s| s.chars.sort} + +anagram = anagram.select {|k,list| list.size>1}.to_a.sort_by! {|k, list| -k.size} + +anagram.each do |k, list| + if derangements = find_derangements(list) + puts "Longest derangement anagram: #{derangements}" + break + end +end diff --git a/Task/Anagrams-Deranged-anagrams/EasyLang/anagrams-deranged-anagrams.easy b/Task/Anagrams-Deranged-anagrams/EasyLang/anagrams-deranged-anagrams.easy new file mode 100644 index 0000000000..f9b6445b1f --- /dev/null +++ b/Task/Anagrams-Deranged-anagrams/EasyLang/anagrams-deranged-anagrams.easy @@ -0,0 +1,74 @@ +proc norm s$ &name$[] &cnt[] &id . + d$[] = strchars s$ + for i = 1 to len d$[] - 1 + for j = i + 1 to len d$[] + if strcode d$[j] < strcode d$[i] : swap d$[j] d$[i] + . + . + n$ = strjoin d$[] "" + for id to len name$[] : if name$[id] = n$ : break 1 + if id > len name$[] + name$[] &= n$ + cnt[] &= 0 + . + cnt[id] += 1 +. +func deranged a$ b$ . + for i to len a$ + if substr a$ i 1 = substr b$ i 1 : return 0 + . + return 1 +. +global maxlng w$[] . +proc read . + repeat + s$ = input + until s$ = "" + w$[] &= s$ + maxlng = higher maxlng len s$ + . +. +read +# +len wid[] len w$[] +done = 0 +proc search a b . + for i = a to b + norm w$[i] name$[] cnt[] id + wid[i] = id + . + for id to len name$[] : if cnt[id] > 1 + h[] = [ ] + for i = a to b : if wid[i] = id : h[] &= i + for i to len h[] - 1 : for j = i + 1 to len h[] + if deranged w$[h[i]] w$[h[j]] = 1 + print w$[h[i]] & " " & w$[h[j]] + done = 1 + . + . + . +. +b = len w$[] +while done = 0 and maxlng >= 2 + a = b + for i = b downto 1 : if len w$[i] = maxlng + swap w$[i] w$[a] + a -= 1 + . + search a + 1 b + maxlng -= 1 +. +# +# a few lines of unixdict.txt, also works with all +input_data +ancestor +ancestral +ancestry +anchor +lana +lancashire +lancaster +lance +zucchini +zurich +zygote diff --git a/Task/Anagrams/EasyLang/anagrams.easy b/Task/Anagrams/EasyLang/anagrams.easy new file mode 100644 index 0000000000..2e5fcff599 --- /dev/null +++ b/Task/Anagrams/EasyLang/anagrams.easy @@ -0,0 +1,46 @@ +global name$[] cnt[] . +func n2id n$ . + for id to len name$[] : if name$[id] = n$ : return id + name$[] &= n$ + cnt[] &= 0 + return id +. +func norm s$ . + d$[] = strchars s$ + for i = 1 to len d$[] - 1 + for j = i + 1 to len d$[] + if strcode d$[j] < strcode d$[i] : swap d$[j] d$[i] + . + . + n$ = strjoin d$[] "" + return n2id n$ +. +repeat + s$ = input + until s$ = "" + id = norm s$ + cnt[id] += 1 + max = higher max cnt[id] + w$[] &= s$ + wid[] &= id +. +for id to len name$[] + if cnt[id] = max + for i to len w$[] + if wid[i] = id : write w$[i] & " " + . + print "" + . +. +# +# a few lines of unixdict.txt, also works with all +input_data +abe +abed +abel +ablaze +able +ablution +angel +angle +angles diff --git a/Task/Anagrams/Elena/anagrams.elena b/Task/Anagrams/Elena/anagrams.elena index 65bb59e28f..a98ee663ba 100644 --- a/Task/Anagrams/Elena/anagrams.elena +++ b/Task/Anagrams/Elena/anagrams.elena @@ -15,7 +15,7 @@ extension op public program() { - var start := now; + var start := Now; auto dictionary := new Map(); @@ -35,13 +35,13 @@ public program() dictionary.Values .quickSort::(former,later => former.Item2.Length > later.Item2.Length ) .top(20) - .forEach::(pair){ console.printLine(pair.Item2) }; + .forEach::(pair){ Console.printLine(pair.Item2) }; - var end := now; + var end := Now; var diff := end - start; - console.printLine("Time elapsed in msec:",diff.Milliseconds); + Console.printLine("Time elapsed in msec:",diff.Milliseconds); - console.readChar() + Console.readChar() } diff --git a/Task/Angle-difference-between-two-bearings/Ballerina/angle-difference-between-two-bearings.ballerina b/Task/Angle-difference-between-two-bearings/Ballerina/angle-difference-between-two-bearings.ballerina new file mode 100644 index 0000000000..213bb46d14 --- /dev/null +++ b/Task/Angle-difference-between-two-bearings/Ballerina/angle-difference-between-two-bearings.ballerina @@ -0,0 +1,34 @@ +import ballerina/io; + +function subtract(float b1, float b2) returns float { + float d = (b2 - b1) % 360.0; + if d < -180.0 { d += 360.0; } + if d >= 180.0 { d -= 360.0; } + return d.round(4); +} + +public function main() { + float[][] pairs = [ + [ 20, 45], + [-45, 45], + [-85, 90], + [-95, 90], + [-45, 125], + [-45, 145], + [ 29.4803, -88.6381], + [-78.3251, -159.036], + [-70099.74233810938, 29840.67437876723], + [-165313.6666297357, 33693.9894517456], + [1174.8380510598456, -154146.66490124757], + [60175.77306795546, 42213.07192354373] + ]; + + io:println("Differences (to 4dp) between these bearings:"); + foreach var pair in pairs { + float p0 = pair[0]; + float p1 = pair[1]; + float diff = subtract(p0, p1); + string offset = p0 < 0.0 ? " " : " "; + io:println(`${offset}${p0} and ${p1} -> ${diff}`); + } +} diff --git a/Task/Angle-difference-between-two-bearings/EasyLang/angle-difference-between-two-bearings.easy b/Task/Angle-difference-between-two-bearings/EasyLang/angle-difference-between-two-bearings.easy index fbe96a9106..052ea0af48 100644 --- a/Task/Angle-difference-between-two-bearings/EasyLang/angle-difference-between-two-bearings.easy +++ b/Task/Angle-difference-between-two-bearings/EasyLang/angle-difference-between-two-bearings.easy @@ -7,7 +7,7 @@ func angdiff a b . . return r . -proc pd a b . . +proc pd a b . print b & " " & a & " -> " & angdiff a b . pd 20 45 diff --git a/Task/Angles-geometric-normalization-and-conversion/EasyLang/angles-geometric-normalization-and-conversion.easy b/Task/Angles-geometric-normalization-and-conversion/EasyLang/angles-geometric-normalization-and-conversion.easy index 546d276c89..2a63ef3ad8 100644 --- a/Task/Angles-geometric-normalization-and-conversion/EasyLang/angles-geometric-normalization-and-conversion.easy +++ b/Task/Angles-geometric-normalization-and-conversion/EasyLang/angles-geometric-normalization-and-conversion.easy @@ -27,7 +27,7 @@ func$ fmt s$ . # scales$[] = [ "degree" "gradian" "mil" "radian" ] values[] = [ -2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000 ] -numfmt 3 10 +numfmt 10 3 for f$ in scales$[] write fmt f$ for t$ in scales$[] diff --git a/Task/Animate-a-pendulum/EasyLang/animate-a-pendulum.easy b/Task/Animate-a-pendulum/EasyLang/animate-a-pendulum.easy index f295faf12e..1f2b4d30c3 100644 --- a/Task/Animate-a-pendulum/EasyLang/animate-a-pendulum.easy +++ b/Task/Animate-a-pendulum/EasyLang/animate-a-pendulum.easy @@ -1,12 +1,11 @@ ang = 45 on animate - clear - move 50 50 - circle 1 - x = 50 + 40 * sin ang - y = 50 + 40 * cos ang - line x y - circle 6 - vel += sin ang / 5 - ang += vel + gclear + gcircle 50 50 1 + x = 50 + 40 * sin ang + y = 50 + 40 * cos ang + gline 50 50 x y + gcircle x y 6 + vel += sin ang / 5 + ang += vel . diff --git a/Task/Animation/EasyLang/animation.easy b/Task/Animation/EasyLang/animation.easy index 82c5470808..575b1619dc 100644 --- a/Task/Animation/EasyLang/animation.easy +++ b/Task/Animation/EasyLang/animation.easy @@ -1,13 +1,11 @@ s$ = "Hello world! " -textsize 14 +gtextsize 14 lg = len s$ on timer - color 333 - move 10 20 - rect 80 20 - color 999 - move 12 24 - text substr s$ 1 9 + gcolor 333 + grect 10 20 80 20 + gcolor 999 + gtext 12 24 substr s$ 1 9 if forw = 1 s$ = substr s$ lg 1 & substr s$ 1 (lg - 1) else diff --git a/Task/Anonymous-recursion/Elena/anonymous-recursion.elena b/Task/Anonymous-recursion/Elena/anonymous-recursion.elena index f8f6bcd578..2845fb591f 100644 --- a/Task/Anonymous-recursion/Elena/anonymous-recursion.elena +++ b/Task/Anonymous-recursion/Elena/anonymous-recursion.elena @@ -21,16 +21,16 @@ public program() { for (int i := -1; i <= 10; i += 1) { - console.print("fib(",i,")="); + Console.print("fib(",i,")="); try { - console.printLine(fib(i)) + Console.printLine(fib(i)) } catch(Exception e) { - console.printLine("invalid") + Console.printLine("invalid") } }; - console.readChar() + Console.readChar() } diff --git a/Task/Anti-primes/Ballerina/anti-primes.ballerina b/Task/Anti-primes/Ballerina/anti-primes.ballerina new file mode 100644 index 0000000000..c8e5cf3088 --- /dev/null +++ b/Task/Anti-primes/Ballerina/anti-primes.ballerina @@ -0,0 +1,42 @@ +import ballerina/io; + +function divisorCount(int x) returns int { + int n = x; + if n < 1 { return 0; } + int count = 0; + int prod = 1; + while n % 2 == 0 { + count += 1; + n /= 2; + } + prod *= 1 + count; + int i = 3; + while i * i <= n { + count = 0; + while n % i == 0 { + count += 1; + n /= i; + } + prod *= 1 + count; + i += 2; + } + if n > 2 { prod *= 2; } + return prod; +} + +public function main() { + io:println("The first 20 anti-primes are:"); + int maxDiv = 0; + int count = 0; + int n = 1; + while count < 20 { + int d = divisorCount(n); + if d > maxDiv { + io:print(n, " "); + maxDiv = d; + count += 1; + } + n += 1; + } + io:println(); +} diff --git a/Task/Anti-primes/EasyLang/anti-primes.easy b/Task/Anti-primes/EasyLang/anti-primes.easy index d5099ac863..fba9fdd79b 100644 --- a/Task/Anti-primes/EasyLang/anti-primes.easy +++ b/Task/Anti-primes/EasyLang/anti-primes.easy @@ -11,16 +11,14 @@ func divcnt v . p += 1 tot *= cnt . - if n > 1 - tot *= 2 - . + if n > 1 : tot *= 2 return tot . while count < 20 n += 1 divs = divcnt n if divs > max - print n + write n & " " max = divs count += 1 . diff --git a/Task/Anti-primes/OCaml/anti-primes.ml b/Task/Anti-primes/OCaml/anti-primes.ml new file mode 100644 index 0000000000..aeb3bab8ae --- /dev/null +++ b/Task/Anti-primes/OCaml/anti-primes.ml @@ -0,0 +1,18 @@ +let num_divisors (n : int) : int = + if n = 0 || n = 1 then 1 else if n = 2 then 2 else + List.init (n / 2) ((+) 1) (* O(n) *) + |> List.filter (fun i -> n mod i = 0) + |> List.length + +let first_n_antiprimes (n : int) : int list = + let rec loop = function + | i, record, antis when List.length antis = n -> antis + | i, record, antis -> let nd = num_divisors i in + if nd > record then loop (i + 1, nd, i :: antis) else + loop (i + 1, record, antis) + in loop (2, 1, [1]) |> List.rev + +let () = first_n_antiprimes 19 + |> List.map string_of_int + |> String.concat ", " + |> Printf.printf "[%s]\n" diff --git a/Task/Anti-primes/REXX/anti-primes-1.rexx b/Task/Anti-primes/REXX/anti-primes-1.rexx index 1e20a7931e..814dcd4d22 100644 --- a/Task/Anti-primes/REXX/anti-primes-1.rexx +++ b/Task/Anti-primes/REXX/anti-primes-1.rexx @@ -1,40 +1,32 @@ -/*REXX program finds and displays N number of anti-primes (highly-composite) numbers.*/ -Parse Arg N . /* obtain optional argument from the CL. */ -If N=='' | N=="," Then N=20 /* Not specified? Then use the default. */ -maxD=0 /* the maximum number of divisors so far */ -Say '-index- --anti-prime--' /* display a title For the numbers shown */ -nn=0 /* the count of anti-primes found " " */ -Do i=1 For 59 While nnmaxD Then Do /* found an anti-prime nn set new maxD */ - maxD=d - nn=nn+1 - Say center(nn,7) right(i,10) /* display the index and the anti-prime. */ - End - End /*i*/ +-- 8 May 2025 +include Settings +arg xx +if xx = '' then + xx = 1500000 -Do i=60 by 20 While nnmaxD Then Do /* found an anti-prime nn set new maxD */ - maxD=d - nn=nn+1 - Say center(nn,7) right(i,10) /* display the index and the anti-prime. */ - End - End /*i*/ -Exit /* stick a fork in it, we're all done. */ -/*-----------------------------------------------------------------------------------*/ -nndivs: Procedure /* compute the number of proper divisors */ - Parse Arg x - If x<2 Then - Return 1 - odd=x//2 - n=1 /* 1 is a proper divisor */ - Do j=2+odd by 1+odd While j*j h then do + n = n+1 + call Charout ,Left(i' ['c'] ',16) + if n//5 = 0 then + say + h = c + end +end +say n 'found' +say +call Timer +exit + +include Numbers +include Functions +include Special +include Helper +include Abend diff --git a/Task/Anti-primes/REXX/anti-primes-2.rexx b/Task/Anti-primes/REXX/anti-primes-2.rexx index 25e3818e7a..33c855c408 100644 --- a/Task/Anti-primes/REXX/anti-primes-2.rexx +++ b/Task/Anti-primes/REXX/anti-primes-2.rexx @@ -1,38 +1,33 @@ -/*REXX program finds and displays N number of anti─primes or highly─composite numbers.*/ -parse arg N . /*obtain optional argument from the CL.*/ -if N=='' | N=="," then N= 20 /*Not specified? Then use the default.*/ - @.= .; @.1= 1; @.2= 2; @.4= 3; @.5= 2; @.6= 4 -say '─index─ ──anti─prime──' /*display a title for the numbers shown*/ -#= 1 /*the count of anti─primes found " " */ -maxD= 1 /*the maximum number of divisors so far*/ -say center(#, 7) right(1, 10) /*display the index and the anti─prime.*/ - do once=1 for 1 - do i=2 by 2 to 59 /*step through possible numbers by twos*/ - d= #divs(i); if d<=maxD then iterate /*get # divisors; Is too small? Skip.*/ - #= # + 1; maxD= d /*found an anti─prime #; set new minD.*/ - say center(#, 7) right(i, 10) /*display the index and the anti─prime.*/ - if #>=N then leave once /*if we have enough anti─primes, done. */ - end /*i*/ +-- 8 May 2025 +include Settings +arg xx +if xx = '' then + xx = 1500000 - do j=60 by 20 /*step through possible numbers by 20. */ - d= #divs(j); if d<=maxD then iterate /*get # divisors; Is too small? Skip.*/ - #= # + 1; maxD= d /*found an anti─prime #; set new minD.*/ - say center(#, 7) right(j, 10) /*display the index and the anti─prime.*/ - if #>=N then leave once /*if we have enough anti─primes, done. */ - L= length(j) /*obtain the length of the index (J). */ - if L>3 then j= j + left(4, L-2, 0) - 20 /*Length>3? Then calculate a long jump*/ - end /*j*/ - end /*once*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -#divs: parse arg x; if @.x\==. then return @.x /*if pre─computed, then return shortcut*/ - $= 3; y= x % 2 - /* [↑] start with known num of Pdivs.*/ - do k=3 for x%2-3 while k=y then do; $= $ - 1; leave; end /*limit?*/ - end /* ___ */ - else if k*k>x then leave /*only divide up to √ x */ - end /*k*/ /* [↑] this form of DO loop is faster.*/ - return $+1 /*bump "proper divisors" to "divisors".*/ +say 'ANTI-PRIMES' +say version +say 'Cheating' +say +say 'Anti-primes below' xx'...' +numeric digits 16 +s = (xx > 0); xx = Abs(xx) +h = Highcomposites(xx) +if s then do + do i = 1 to high.0 + c = Divisor(high.i) + call Charout ,Left(high.i' ['c'] ',20) + if i//5 = 0 then + say + end +end +say h 'found' +say +call Timer +exit + +include Numbers +include Functions +include Special +include Sequences +include Helper +include Abend diff --git a/Task/Anti-primes/REXX/anti-primes-3.rexx b/Task/Anti-primes/REXX/anti-primes-3.rexx deleted file mode 100644 index 1fd8eab5dc..0000000000 --- a/Task/Anti-primes/REXX/anti-primes-3.rexx +++ /dev/null @@ -1,44 +0,0 @@ -include Settings - -say version; say 'Anti-prims'; say -arg n -numeric digits 16 -if n = '' then - n = 10000 -show = (n > 0); n = Abs(n) -h = Highcomposites(n) -say h 'anti-primes found below' n -if show then do - do i = 1 to high.0 - say i high.highcomposite.i - end -end -say time('e') 'seconds' -exit - -Highcomposites: -/* Highly composite sequence */ -procedure expose high. -arg x -/* Thresholds and increments */ -a = '1 2 6 60 840 55440 720720 61261200 2327925600 321253732800 9999999999999' -b = '1 2 6 60 420 27720 360360 12252240 232792560 80313433200 9999999999999' -c = Words(a)-1; m = 0; n = 0 -/* Colllect cf definition */ -do i = 1 to c - do j = Word(a,i) by Word(b,i) to Min(x,Word(a,i+1)-1) - d = Divisors(j) - if d > m then do - n = n+1; high.highcomposite.n = j - m = d - end - end -end -high.0 = n -/* Return count */ -return n - -include Numbers -include Functions -include Sequences -include Abend diff --git a/Task/Anti-primes/Zig/anti-primes.zig b/Task/Anti-primes/Zig/anti-primes.zig new file mode 100644 index 0000000000..055b8a243e --- /dev/null +++ b/Task/Anti-primes/Zig/anti-primes.zig @@ -0,0 +1,160 @@ +const std = @import("std"); + +fn sieve(allocator: std.mem.Allocator, n: usize) ![]i32 { + var is_prime = try allocator.alloc(i32, n); + var primes = std.ArrayList(i32).init(allocator); + defer allocator.free(is_prime); + for (is_prime) |*p| { + p.* = 1; + } + is_prime[0] = 0; + is_prime[1] = 0; + for (2..n) |i| { + if (is_prime[i] == 1) { + var j = i * i; + while (j < n) : (j += i) { + is_prime[j] = 0; + } + } + } + for (2..n) |i| { + if (is_prime[i] == 1) { + try primes.append(@intCast(i)); + } + } + return primes.toOwnedSlice(); +} + +const AntiPrime = struct { + value: i32, + divisors_count: i32, + factorization: std.ArrayList(i32), + + pub fn init(allocator: std.mem.Allocator, value: i32, divisors_count: i32, factors: []i32) !AntiPrime { + var factorization = try std.ArrayList(i32).initCapacity(allocator, factors.len); + errdefer factorization.deinit(); + try factorization.appendSlice(factors); + return AntiPrime{ + .value = value, + .divisors_count = divisors_count, + .factorization = factorization, + }; + } + + pub fn deinit(self: *AntiPrime) void { + self.factorization.deinit(); + } + + pub fn asc(context: void, a: AntiPrime, b: AntiPrime) bool { + _ = context; + if (a.value < b.value) return true; + if (a.value > b.value) return false; + if (a.divisors_count < b.divisors_count) return true; + if (a.divisors_count > b.divisors_count) return false; + if (a.factorization.items.len < b.factorization.items.len) return true; + if (a.factorization.items.len > b.factorization.items.len) return false; + for (a.factorization.items, b.factorization.items) |a_factor, b_factor| { + if (a_factor < b_factor) return true; + if (a_factor > b_factor) return false; + } + return false; + } + + pub fn clone(self: *AntiPrime) !AntiPrime { + var new_factorization = try std.ArrayList(i32).initCapacity(self.factorization.allocator, self.factorization.items.len); + errdefer new_factorization.deinit(); + try new_factorization.appendSlice(self.factorization.items); + return AntiPrime{ + .value = self.value, + .divisors_count = self.divisors_count, + .factorization = new_factorization, + }; + } +}; +const MAXN = 100000000; +fn generate_anti_primes(allocator: std.mem.Allocator) ![]AntiPrime { + var anti_primes = std.ArrayList(AntiPrime).init(allocator); + try anti_primes.append(try AntiPrime.init(allocator, 1, 1, &[_]i32{})); + const primes = try (sieve(allocator, 1000)); + defer allocator.free(primes); + + for (primes, 0..) |prime, i| { + var new_anti_primes = std.ArrayList(AntiPrime).init(allocator); + defer { + for (new_anti_primes.items) |*new_anti_prime| { + new_anti_prime.*.deinit(); + } + new_anti_primes.deinit(); + } + for (anti_primes.items) |*el| { + try new_anti_primes.append(try el.*.clone()); + if (el.*.factorization.items.len < i) continue; + const e_max = if (i >= 1) el.*.factorization.items[i - 1] else @as(i32, @intCast(std.math.log2(MAXN))); + var n1 = el.*.value; + var e: i32 = 1; + while (e <= e_max) : (e += 1) { + n1 *= prime; + if (n1 > MAXN) break; + const div = el.*.divisors_count * (e + 1); + var exponents = std.ArrayList(i32).init(allocator); + defer exponents.deinit(); + try exponents.appendSlice(el.*.factorization.items); + try exponents.append(e); + try new_anti_primes.append(try AntiPrime.init( + allocator, + @as(i32, n1), + div, + exponents.items, + )); + } + } + std.mem.sort(AntiPrime, new_anti_primes.items, {}, AntiPrime.asc); + for (anti_primes.items) |*anti_prime| { + anti_prime.*.deinit(); + } + try anti_primes.resize(0); + try anti_primes.append(try AntiPrime.init( + allocator, + 1, + 1, + &[_]i32{}, + )); + + for (new_anti_primes.items) |*el| { + if (el.divisors_count > anti_primes.getLast().divisors_count) { + try anti_primes.append(try el.*.clone()); + } + } + } + + return anti_primes.toOwnedSlice(); +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer { + const result = gpa.deinit(); + if (result == .leak) { + std.debug.panic("Memory leak detected in GeneralPurposeAllocator deinit", .{}); + } + } + const stdout = std.io.getStdOut().writer(); + const n = 20; + + const anti_primes = try generate_anti_primes(allocator); + defer { + for (anti_primes) |*anti_prime| { + anti_prime.*.deinit(); + } + allocator.free(anti_primes); + } + + try stdout.print("The first 20 anti-primes:\n", .{}); + for (anti_primes[0..n], 0..) |anti_prime, index| { + try stdout.print("{} ", .{anti_prime.value}); + if (index % 10 == 9) { + try stdout.print("\n", .{}); + } + } +} diff --git a/Task/Apply-a-callback-to-an-array/Ballerina/apply-a-callback-to-an-array.ballerina b/Task/Apply-a-callback-to-an-array/Ballerina/apply-a-callback-to-an-array.ballerina new file mode 100644 index 0000000000..a2d7fd5818 --- /dev/null +++ b/Task/Apply-a-callback-to-an-array/Ballerina/apply-a-callback-to-an-array.ballerina @@ -0,0 +1,9 @@ +import ballerina/io; + +public function main() { + int[] a = from int i in 1...10 select i; + var square = function(int i) returns int { + return i * i; + }; + io:println(a.map(i => square(i))); +} diff --git a/Task/Apply-a-digital-filter-direct-form-II-transposed-/Fortran/apply-a-digital-filter-direct-form-ii-transposed-.f b/Task/Apply-a-digital-filter-direct-form-II-transposed-/Fortran/apply-a-digital-filter-direct-form-ii-transposed-.f new file mode 100644 index 0000000000..82aef332a6 --- /dev/null +++ b/Task/Apply-a-digital-filter-direct-form-II-transposed-/Fortran/apply-a-digital-filter-direct-form-ii-transposed-.f @@ -0,0 +1,42 @@ +module df2_filter + implicit none + real, parameter :: a(4) = [1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17] + real, parameter :: b(4) = [0.16666667, 0.5, 0.5, 0.16666667] + real :: w(4) = 0.0 ! State vector + +contains + function filter(x) result(y) + real, intent(in) :: x + real :: y + integer :: i + + y = x * b(1) + w(1) + + do i = 2, 4 + w(i-1) = x * b(i) - y * a(i) + w(i) + end do + end function filter +end module df2_filter + +program apply_filter + use df2_filter + implicit none + real, dimension(20) :: input = [ & + -0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, & + -0.662370894973, -1.00700480494, -0.404707073677, 0.800482325044, & + 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195, & + 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293, & + 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589 ] + real, dimension(20) :: output + integer :: i + + do i = 1, 20 + output(i) = filter(input(i)) + end do + + print *, "Filtered signal:" + do i = 1,20 + write(*, '(f12.9,2x)',advance='no') output(i) + if(mod(i,5)==0)write(*,*) + end do +end program apply_filter diff --git a/Task/Apply-a-digital-filter-direct-form-II-transposed-/M2000-Interpreter/apply-a-digital-filter-direct-form-ii-transposed-.m2000 b/Task/Apply-a-digital-filter-direct-form-II-transposed-/M2000-Interpreter/apply-a-digital-filter-direct-form-ii-transposed-.m2000 new file mode 100644 index 0000000000..7cc823c84a --- /dev/null +++ b/Task/Apply-a-digital-filter-direct-form-II-transposed-/M2000-Interpreter/apply-a-digital-filter-direct-form-ii-transposed-.m2000 @@ -0,0 +1,49 @@ +module Checkit { + locale 1033 ' use of dot for decimals + window 12, window ' set 12pt for current display monitor + form 60 ' 60 chars width, any for heigh + Print $("0.00000000",12) ' 12 chars per tab + ' all data push to end of stack, so we use the stack of values as FIFO + Flush + ' a() + Data 1, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17 + ' b() + Data 0.16666667, 0.5, 0.5, 0.16666667 + ' signal() + Data -0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412 + Data -0.662370894973, -1.00700480494, -0.404707073677, 0.800482325044 + Data 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195 + Data 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293 + Data 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589 + Dim Base 0, a(4) as Double , b(4) as Double , signal(20) as Double + Integer i + For i = 0 To 3 : Read a(i) : Next i + For i = 0 To 3 : Read b(i) : Next i + For i = 0 To 19 : Read signal(i) : Next i + dim resp() + resp()=@Filter_a_b(&signal()) + k=each(resp()) + while k + Print array(k), + if pos>0 then if (k^+1) mod 5=0 then Print + end while + Function Filter_a_b(&c()) + Local Integer j, k + Local Double tmp + Local result(0 to len(c())-1) as Double + For j = 0 To Len(c())-1 + tmp = 0 + For k = 0 To Len(b())-1 + If (j-k < 0) Then Continue For + tmp += b(k) * c(j-k) + Next k + For k = 0 To Len(a())-1 + If (j-k < 0) Then Continue For + tmp -= a(k) * result(j-k) + Next k + result(j) = tmp/a(0) + Next j + =result() + End Function +} +Checkit diff --git a/Task/Approximate-equality/Ballerina/approximate-equality.ballerina b/Task/Approximate-equality/Ballerina/approximate-equality.ballerina new file mode 100644 index 0000000000..83ba4b25e0 --- /dev/null +++ b/Task/Approximate-equality/Ballerina/approximate-equality.ballerina @@ -0,0 +1,22 @@ +import ballerina/io; + +public function main() { + float[][] pairs = [ + [100000000000000.01, 100000000000000.011], + [100.01, 100.011], + [10000000000000.001 / 10000.0, 1000000000.0000001000], + [0.001, 0.0010000001], + [0.000000000000000000000101, 0.0], + [2.0.sqrt() * 2.0.sqrt(), 2.0], + [-2.0.sqrt() * 2.0.sqrt(), -2.0], + [3.14159265358979323846, 3.14159265358979324] + ]; + io:println("Approximate equality of test cases with a tolerance of 1 bit:"); + int i = 0; + foreach float[] pair in pairs { + i += 1; + int bi0 = pair[0].toBitsInt(); + int bi1 = pair[1].toBitsInt(); + io:println(` ${i} -> ${(bi0 - bi1).abs() <= 1}`); + } +} diff --git a/Task/Approximate-equality/EasyLang/approximate-equality.easy b/Task/Approximate-equality/EasyLang/approximate-equality.easy index 910f89b4d4..5384fbce38 100644 --- a/Task/Approximate-equality/EasyLang/approximate-equality.easy +++ b/Task/Approximate-equality/EasyLang/approximate-equality.easy @@ -1,7 +1,7 @@ func aeq a b . return if abs (a - b) <= abs a * 1e-14 . -proc test a b . . +proc test a b . write a & " " & b & " -> " if aeq a b = 1 print "true" @@ -9,7 +9,7 @@ proc test a b . . print "false" . . -numfmt 10 0 +numfmt 0 10 test 100000000000000.01 100000000000000.011 test 100.01 100.011 test 10000000000000.001 / 10000 1000000000.0000001 diff --git a/Task/Archimedean-spiral/EasyLang/archimedean-spiral.easy b/Task/Archimedean-spiral/EasyLang/archimedean-spiral.easy index 6f648c90fb..4fc2177a04 100644 --- a/Task/Archimedean-spiral/EasyLang/archimedean-spiral.easy +++ b/Task/Archimedean-spiral/EasyLang/archimedean-spiral.easy @@ -1,8 +1,12 @@ -linewidth 0.4 -x = 50 -y = 50 +glinewidth 0.4 +x0 = 50 +y0 = 50 while r < 50 - line r * cos t + x r * sin t + y + xp = x + yp = y + x = r * cos t + x0 + y = r * sin t + y0 + if r > 0 : gline xp yp x y r += 0.05 t += 3 . diff --git a/Task/Arithmetic-Complex/ALGOL-68/arithmetic-complex.alg b/Task/Arithmetic-Complex/ALGOL-68/arithmetic-complex.alg index 0e4466402d..d1c920b389 100644 --- a/Task/Arithmetic-Complex/ALGOL-68/arithmetic-complex.alg +++ b/Task/Arithmetic-Complex/ALGOL-68/arithmetic-complex.alg @@ -1,27 +1,29 @@ -main:( - FORMAT compl fmt = $g(-7,5)"⊥"g(-7,5)$; +BEGIN PROC compl operations = VOID: ( - LONG COMPL a = 1.0 ⊥ 1.0; - LONG COMPL b = 3.14159 ⊥ 1.2; + COMPL a = 1.0 I 1.0; + COMPL b = 3.14159 I 1.2; - LONG COMPL c; + COMPL c; - printf(($x"a="f(compl fmt)l$,a)); - printf(($x"b="f(compl fmt)l$,b)); + PROC show compl = ( STRING legend, COMPL v )VOID: + print( ( legend, fixed( re OF v, -8, 5 ), " I ", fixed( im OF v, -8, 5 ), newline ) ); + + show compl(" a=",a); + show compl(" b=",b); # addition # c := a + b; - printf(($x"a+b="f(compl fmt)l$,c)); + show compl("a+b=",c); # multiplication # c := a * b; - printf(($x"a*b="f(compl fmt)l$,c)); + show compl("a*b=",c); # inversion # c := 1.0 / a; - printf(($x"1/c="f(compl fmt)l$,c)); + show compl("1/c=",c); # negation # c := -a; - printf(($x"-a="f(compl fmt)l$,c)) + show compl(" -a=",c) ); compl operations -) +END diff --git a/Task/Arithmetic-Complex/Ballerina/arithmetic-complex.ballerina b/Task/Arithmetic-Complex/Ballerina/arithmetic-complex.ballerina new file mode 100644 index 0000000000..a17cb192ef --- /dev/null +++ b/Task/Arithmetic-Complex/Ballerina/arithmetic-complex.ballerina @@ -0,0 +1,67 @@ +import ballerina/io; + +class Complex { + float re; + float im; + + function init(float re, float im) { + self.re = re; + self.im = im; + } + + function neg() returns Complex { + return new Complex(-self.re, -self.im); + } + + function inv() returns Complex { + float denom = self.re * self.re + self.im * self.im; + return new Complex(self.re / denom, -self.im / denom); + } + + function add(Complex other) returns Complex { + return new Complex(self.re + other.re, self.im + other.im); + } + + function sub(Complex other) returns Complex { + return self.add(other.neg()); + } + + function mul(Complex other) returns Complex { + return new Complex( + self.re * other.re - self.im * other.im, + self.re * other.im + self.im * other.re + ); + } + + function div(Complex other) returns Complex { + return self.mul(other.inv()); + } + + function conj() returns Complex { + return new Complex(self.re, -self.im); + } + + function toString() returns string { + if self.re === -0.0 { self.re = 0.0; } + if self.im === -0.0 { self.im = 0.0; } + if self.im >= 0.0 { + return string `${self.re} + ${self.im}i`; + } else { + return string `${self.re} - ${-self.im}i`; + } + } +} + +public function main() { + var x = new Complex(1, 3); + var y = new Complex(5, 2); + io:println("x = ", x); + io:println("y = ", y); + io:println("x + y = ", x.add(y)); + io:println("x - y = ", x.sub(y)); + io:println("x * y = ", x.mul(y)); + io:println("x / y = ", x.div(y)); + io:println("-x = ", x.neg()); + io:println("1 / x = ", x.inv()); + io:println("x* = ", x.conj()); +} diff --git a/Task/Arithmetic-Complex/Crystal/arithmetic-complex.cr b/Task/Arithmetic-Complex/Crystal/arithmetic-complex.cr new file mode 100644 index 0000000000..bb024b95a6 --- /dev/null +++ b/Task/Arithmetic-Complex/Crystal/arithmetic-complex.cr @@ -0,0 +1,15 @@ +require "complex" + +a = Complex.new(1, 2) +b = 3 + 4.i + +puts "a = #{a}, b = #{b}" +puts +puts "a + b = #{a + b}" +puts "a - b = #{a - b}" +puts "a * b = #{a * b}" +puts "a / b = #{a / b}" +puts +puts "-a = #{-a}" +puts "1/a = #{a.inv}" +puts "ā = #{a.conj}" diff --git a/Task/Arithmetic-Complex/M2000-Interpreter/arithmetic-complex.m2000 b/Task/Arithmetic-Complex/M2000-Interpreter/arithmetic-complex-1.m2000 similarity index 100% rename from Task/Arithmetic-Complex/M2000-Interpreter/arithmetic-complex.m2000 rename to Task/Arithmetic-Complex/M2000-Interpreter/arithmetic-complex-1.m2000 diff --git a/Task/Arithmetic-Complex/M2000-Interpreter/arithmetic-complex-2.m2000 b/Task/Arithmetic-Complex/M2000-Interpreter/arithmetic-complex-2.m2000 new file mode 100644 index 0000000000..2b527fe51b --- /dev/null +++ b/Task/Arithmetic-Complex/M2000-Interpreter/arithmetic-complex-2.m2000 @@ -0,0 +1,35 @@ +module tstComplex { + // Var one as complex=(1,0i), A as complex=(8, -3i) + one=(1,0i) + A=(8, -3i) + Print "A=";A + Print " r=";Abs(A);" θ=";Arg(A);" rad" + B=one/A + Print "B=";B + Print " r=";Abs(B);" θ=";Arg(B);" rad" + Print A;"*";B;"=";A*B + Print one;"/";B;"=";one/B + Print A;"/";A;"=";A/A + Print A;"+";A;"=";A+A + Print A;"-";A;"=";A-A + Print "-"+A+"=";-A + Print "(round exp to 13th decimal)" + I=round(exp((0, pi i)),13)+1 + Print "e^(πi)+1=";i + Print "(without rounding)" + I=exp((0, pi i))+1 + Print "e^(πi)+1=";i + Print type$(i) = "Complex" + Dim a(10) as Complex=(1,0i) + Print (a(3)+a(3))^2=(4, 0i) + Print (a(3)+a(3))^2=4 + + Print cos(a) + Print sin(a) + Print atn(tan(a)) + Print tan(atn(a)) + Print Polar(abs(a), arg(a))=(8, -3i) + Print str$(a ,"0.00") + Print str$((8,-3i) ,"0.00") +} + tstComplex diff --git a/Task/Arithmetic-Complex/REXX/arithmetic-complex.rexx b/Task/Arithmetic-Complex/REXX/arithmetic-complex.rexx index fd21689cfc..7c72a01f37 100644 --- a/Task/Arithmetic-Complex/REXX/arithmetic-complex.rexx +++ b/Task/Arithmetic-Complex/REXX/arithmetic-complex.rexx @@ -1,38 +1,53 @@ +-- 19 May 2025 include Settings -say version; say 'Arithmetic numbers'; say -numeric digits 9 -divi. = 0; a = 0; c = 0 -do i = 1 -/* Is the number arithmetic? */ - if Arithmetic(i) then do - a = a+1 -/* Is the number composite? */ - if divi.0 > 2 then - c = c+1 -/* Output control */ - if a <= 100 then do - if a = 1 then - say 'First 100 arithmetic numbers are' - call Charout ,Right(i,4) - if a//10 = 0 then - say - if a = 100 then - say - end - if a = 100 | a = 1000 | a = 10000 | a = 100000 | a = 1000000 then do - say 'The' a'th arithmetic number is' i - say 'Of the first' a 'numbers' c 'are composite' - say - end -/* Max 1m, higher takes too long */ - if a = 1000000 then - leave - end -end -say Format(Time('e'),,3) 'seconds' +say 'COMPLEX ARITHMETIC' +say version +say +a = '1 2'; b = '3 4'; c = '5 6'; d = '7 8'; i = I() +say 'VALUES' +say 'a =' crec2form(a) +say 'b =' crec2form(b) +say 'c =' crec2form(c) +say 'd =' crec2form(d) +say +say 'BASICS' +say 'i*i =' crec2form(Csquare(i())) +say 'a+b =' crec2form(Cadd(a,b)) +say 'a-b =' crec2form(Csub(a,b)) +say 'a*b =' crec2form(Cmul(a,b)) +say 'a/b =' crec2form(Cdiv(a,b)) +say 'a^2 =' crec2form(Csquare(a,2)) +say 'a^5 =' crec2form(Cpow(a,5)) +say '-a =' crec2form(Cneg(a)) +say '1/a =' crec2form(Cinv(a)) +say 'a+b+c+d =' crec2form(Cadd(a,b,c,d)) +say 'a-b-c-d =' crec2form(Csub(a,b,c,d)) +say 'a*b*c*d =' crec2form(Cmul(a,b,c,d)) +say 'a/b/c/d =' crec2form(Cnormal(Cdiv(a,b,c,d))) +say +say 'FORMULA' +say 'a^2-2ab+3c-4ad^4+5 =' , +crec2form(Cadd(Csquare(a),Cmul(-2,a,b),Cmul(3,c),Cmul(-4,a,Cpower(d,4)),5)) +say +say 'BONUS' +say 'Argument(a) =' Carg(a)+0 +say 'Conjugate(a) =' crec2form(Cconj(a)) +say 'Imag(a) =' Cim(a) +say 'Modulus(a) =' Cmod(a)+0 +say 'Polar(a) =' Cpol2form(Cnormal(Crec2pol(a))) +say 'Real(a) =' Cre(a) +say +say 'MORE' +say 'Arcsin(a) =' crec2form(Cnormal(Carcsin(a))) +say 'Exp(a) =' crec2form(Cnormal(Cexp(a))) +say 'Ln(a) =' crec2form(Cnormal(Cln(a))) +say 'Sin(a) =' crec2form(Cnormal(Csin(a))) +say 'Sqrt(a) =' crec2form(Cnormal(Csqrt(a))) +say 'i^i =' crec2form(Cnormal(Cpower(i,i))) exit -include Numbers +include Complex include Functions +include Constants include Abend diff --git a/Task/Arithmetic-Integer/Ballerina/arithmetic-integer.ballerina b/Task/Arithmetic-Integer/Ballerina/arithmetic-integer.ballerina new file mode 100644 index 0000000000..0ab61725c4 --- /dev/null +++ b/Task/Arithmetic-Integer/Ballerina/arithmetic-integer.ballerina @@ -0,0 +1,24 @@ +import ballerina/io; + +function divmod(int a, int b) returns [int, int] { + return [a / b, a % b]; +} + +function pow(int n, int e) returns int { + if e < 1 { return 1; } + int prod = 1; + foreach int i in 1...e { prod *= n; } + return prod; +} + +public function main() returns error? { + int a = check int:fromString(io:readln("first number: ")); + int b = check int:fromString(io:readln("second number: ")); + io:println("sum: ", a + b); + io:println("difference: ", a - b); + io:println("product: ", a * b); + io:println("integer quotient: ", a / b); // rounds towards zero + io:println("remainder: ", a % b); // sign matches sign of first operand + io:println("exponentiation: ", pow(a, b)); + io:println("divmod ", divmod(a, b)); +} diff --git a/Task/Arithmetic-Integer/OPL/arithmetic-integer.opl b/Task/Arithmetic-Integer/OPL/arithmetic-integer.opl new file mode 100644 index 0000000000..57f4ee3106 --- /dev/null +++ b/Task/Arithmetic-Integer/OPL/arithmetic-integer.opl @@ -0,0 +1,14 @@ +PROC main: + LOCAL a%,b% + PRINT "Please enter a number:", + INPUT a% + PRINT "Please enter another number:", + INPUT b% + PRINT a%;"+";b%;"=";a%+b% + PRINT a%;"-";b%;"=";a%-b% + PRINT a%;"×";b%;"=";a%*b% + PRINT a%;"÷";b%;"=";a%/b% + PRINT a%;"%";b%;"=";a%-a%/b%*b% + PRINT a%;"^";b%;"=";a%**b% + GET +ENDP diff --git a/Task/Arithmetic-Integer/Wren/arithmetic-integer.wren b/Task/Arithmetic-Integer/Wren/arithmetic-integer.wren index df5b65f478..5e19a436e2 100644 --- a/Task/Arithmetic-Integer/Wren/arithmetic-integer.wren +++ b/Task/Arithmetic-Integer/Wren/arithmetic-integer.wren @@ -1,13 +1,13 @@ -import "io" for Stdin, Stdout -System.write("first number: ") -Stdout.flush() -var a = Num.fromString(Stdin.readLine()) -System.write("second number: ") -Stdout.flush() -var b = Num.fromString(Stdin.readLine()) +import "./ioutil" for Input, Stdin + +var divmod = Fn.new { |a, b| [(a / b).floor, a % b] } + +var a = Input.integer("first number: ") +var b = Input.integer("second number: ") System.print("sum: %(a + b)") System.print("difference: %(a - b)") System.print("product: %(a * b)") System.print("integer quotient: %((a / b).floor)") System.print("remainder: %(a % b)") System.print("exponentiation: %(a.pow(b))") +System.print("divmod: %(divmod.call(a, b))") diff --git a/Task/Arithmetic-Rational/Ballerina/arithmetic-rational.ballerina b/Task/Arithmetic-Rational/Ballerina/arithmetic-rational.ballerina new file mode 100644 index 0000000000..7c6dc57fb6 --- /dev/null +++ b/Task/Arithmetic-Rational/Ballerina/arithmetic-rational.ballerina @@ -0,0 +1,156 @@ +import ballerina/io; + +function gcd(int num, int den) returns int { + int n = num; // make mutable + int d = den; // ditto + while d != 0 { + int t = d; + d = n % d; + n = t; + } + return n; +} + +class Frac { + int num; + int den; + + function init(int num, int den) { + int n = num; // make mutable + int d = den; // ditto + if n == 0 { + d = 1; + } else if d < 0 { + n = -n; + d = -d; + } + int g = gcd(n, d).abs(); + if g > 1 { + n /= g; + d /= g; + } + self.num = n; + self.den = d; + } + + function fromInt(int i) returns Frac { + return new Frac(i, 1); + } + + function neg() returns Frac { + return new Frac(-self.num, self.den); + } + + function inv() returns Frac { + return new Frac(self.den, self.num); + } + + function copy() returns Frac { + return new Frac(self.num, self.den); + } + + function abs() returns Frac { + if self.num >= 0 { return self.copy(); } + return self.neg(); + } + + function add(Frac other) returns Frac { + return new Frac(self.num * other.den + self.den * other.num, self.den * other.den); + } + + function sub(Frac other) returns Frac { + return self.add(other.neg()); + } + + function mul(Frac other) returns Frac { + return new Frac(self.num * other.num, self.den * other.den); + } + + function div(Frac other) returns Frac { + return new Frac(self.num * other.den, self.den * other.num); + } + + function toFloat() returns float { + return self.num / self.den; + } + + function toInt() returns int { + float f = self.toFloat(); + f = f >= 0.0 ? f.floor() : f.ceiling(); + return f; + } + + function idiv(Frac other) returns Frac { + return new Frac(self.toInt(), 1); + } + + function mod(Frac other) returns Frac { + return self.sub(self.idiv(other).mul(other)); + } + + function lt(Frac other) returns boolean { + return self.toFloat() < other.toFloat(); + } + + function le(Frac other) returns boolean { + return self.toFloat() <= other.toFloat(); + } + + function gt(Frac other) returns boolean { + return self.toFloat() > other.toFloat(); + } + + function ge(Frac other) returns boolean { + return self.toFloat() >= other.toFloat(); + } + + function eq(Frac other) returns boolean { + return self.toFloat() == other.toFloat(); + } + + function ne(Frac other) returns boolean { + return self.toFloat() != other.toFloat(); + } + + function toString() returns string { + return string `${self.num} / ${self.den}`; + } +} + +function divisors(int n) returns int[] { + if n < 1 { return []; } + int[] divisors = []; + int[] divisors2 = []; + int i = 1; + int k = n % 2 == 0 ? 1 : 2; + while i * i <= n { + if n % i == 0 { + divisors.push(i); + int j = n / i; + if j != i { divisors2.push(j); } + } + i += k; + } + if divisors2.length() > 0 { + divisors.push(...divisors2.reverse()); + } + return divisors; +} + +function properDivisors(int n) returns int[] { + int[] d = divisors(n); + int c = d.length(); + return c <= 1 ? [] : d.slice(0, c - 1); +} + +public function main() { + final Frac one = new Frac(1, 1); + io:println("The following numbers (less than 2^19) are perfect:"); + foreach int i in 2..<(1<<19) { + var sum = new Frac(1, i); + foreach int j in properDivisors(i).slice(1) { + sum = sum.add(new Frac(1, j)); + } + if sum.eq(one) { io:println(" ", i); } + } +} diff --git a/Task/Arithmetic-Rational/REXX/arithmetic-rational.rexx b/Task/Arithmetic-Rational/REXX/arithmetic-rational.rexx index 16e57b5dcc..a7f3438a50 100644 --- a/Task/Arithmetic-Rational/REXX/arithmetic-rational.rexx +++ b/Task/Arithmetic-Rational/REXX/arithmetic-rational.rexx @@ -1,6 +1,8 @@ include Settings -say version; say 'Rational arithmetic'; say +say 'RATIONAL ARITHMETIC - 2 Mar 2025' +say version +say a = '1 2'; b = '-3 4'; c = '5 -6'; d = '-7 -8'; e = 3; f = 1.666666666 say 'VALUES' say 'a =' Rlst2form(a) diff --git a/Task/Arithmetic-derivative/00-TASK.txt b/Task/Arithmetic-derivative/00-TASK.txt index 7e36aa263c..6335ba8b8f 100644 --- a/Task/Arithmetic-derivative/00-TASK.txt +++ b/Task/Arithmetic-derivative/00-TASK.txt @@ -4,21 +4,21 @@ factorization, by analogy with the product rule for the derivative of a function used in mathematical analysis. Accordingly, for natural numbers n, the arithmetic derivative D(n) is defined as follows: -;*D(0) = D(1) = 0. -;*D(p) = 1 for any prime p. -;*D(mn) = D(m)n + mD(n) for any m,n ∈ N. (Leibniz rule for derivatives). +;*D(0) = D(1) = 0. +;*D(p) = 1 \;\text{for any prime}\; p. +;*D(mn) = D(m)n + mD(n) \;\text{for any}\; m,n \in N. (Leibniz rule for derivatives). -Additionally, for negative integers the arithmetic derivative may be defined as -D(-n) (n < 0). +Additionally, for negative integers the arithmetic derivative may be defined as -D(-n) \;\text{for}\; (n < 0). ; Examples -D(2) = 1 and D(3) = 1 (both are prime) so if mn = 2 * 3, D(6) = (1)(3) + (1)(2) = 5. +D(2) = 1 and D(3) = 1 (both are prime) so if mn = 2 \cdot 3, then D(6) = D(2\cdot 3) = D(2)\cdot 3 + 2\cdot D(3) = 1\cdot 3 + 2\cdot 1 = 5. -D(9) = D(3)(3) + D(3)(3) = 6 +D(9) = D(3)\cdot 3 + 3\cdot D(3) = 1\cdot 3 + 3\cdot 1 = 6 -D(27) = D(3)*9 + D(9)*3 = 9 + 18 = 27 +D(27) = D(3)\cdot 9 + 3\cdot D(9) = 1\cdot 9 + 3\cdot 6 = 27 -D(30) = D(5)(6) + D(6)(5) = 6 + 5 * 5 = 31. +D(30) = D(5)\cdot 6 + 5\cdot D(6) = 1\cdot 6 + 5 \cdot 5 = 31. ; Task @@ -26,7 +26,7 @@ Find and show the arithmetic derivatives for -99 through 100. ; Stretch task -Find (the arithmetic derivative of 10^m) then divided by 7, where m is from 1 to 20. +Find (the arithmetic derivative of 10^m) then divided by 7, where m is from 1 to 20. ; See also diff --git a/Task/Arithmetic-derivative/Arturo/arithmetic-derivative.arturo b/Task/Arithmetic-derivative/Arturo/arithmetic-derivative.arturo new file mode 100644 index 0000000000..38ff353852 --- /dev/null +++ b/Task/Arithmetic-derivative/Arturo/arithmetic-derivative.arturo @@ -0,0 +1,20 @@ +D: $[x][ + when [ + x < 0 -> neg D neg x + x = 0 -> 0 + x = 1 -> 0 + prime? x -> 1 + any [ + m: 2 + while [0 <> x % m] -> inc 'm + n: x / m + (n * D m) + m * D n + ] + ] +] + +(neg 99)..100 | map => D + | split.every:10 + | loop => [loop & 'n -> prints pad to :string n 5 print ""] +print "" +loop 20 'n -> print ~"D(10^|n|)/7 = |div D 10^n 7|" diff --git a/Task/Arithmetic-derivative/C-sharp/arithmetic-derivative.cs b/Task/Arithmetic-derivative/C-sharp/arithmetic-derivative.cs new file mode 100644 index 0000000000..bdfc86296d --- /dev/null +++ b/Task/Arithmetic-derivative/C-sharp/arithmetic-derivative.cs @@ -0,0 +1,30 @@ +using System.Numerics; + +static BigInteger Derivative(BigInteger k) +{ + if (k < 0) return -Derivative(-k); + if (k < 2) return 0; + if (k.IsEven) return 2 * Derivative(k / 2) + k / 2; + BigInteger m = 3; + + while (m * m <= k && (k % m) != 0) + m += 2; + + var n = k / m; + if (m * n != k || m == 1 || n == 1) return 1; + return n * Derivative(m) + m * Derivative(n); +} + +for (var i = -99; i <= 100; i++) +{ + Console.Write($"{Derivative(i),6}"); + if (i % 10 == 0) Console.WriteLine(); +} + +BigInteger p = 1; + +for (var n = 1; n <= 20; n++) +{ + p *= 10; + Console.WriteLine($"⅐ D(10^{n}) = {Derivative(p) / 7}"); +} diff --git a/Task/Arithmetic-derivative/EasyLang/arithmetic-derivative.easy b/Task/Arithmetic-derivative/EasyLang/arithmetic-derivative.easy index e7f21eef65..32e17c547e 100644 --- a/Task/Arithmetic-derivative/EasyLang/arithmetic-derivative.easy +++ b/Task/Arithmetic-derivative/EasyLang/arithmetic-derivative.easy @@ -1,18 +1,12 @@ func lagarias n . - if n < 0 - return -lagarias -n - . - if n = 0 or n = 1 - return 0 - . + if n < 0 : return -lagarias -n + if n = 0 or n = 1 : return 0 f = 2 while n mod f <> 0 f += 1 . q = n / f - if q = 1 - return 1 - . + if q = 1 : return 1 return q * lagarias f + f * lagarias q . for n = -99 to 100 diff --git a/Task/Arithmetic-evaluation/EasyLang/arithmetic-evaluation.easy b/Task/Arithmetic-evaluation/EasyLang/arithmetic-evaluation.easy index f8bbf4ec53..bf0629bde2 100644 --- a/Task/Arithmetic-evaluation/EasyLang/arithmetic-evaluation.easy +++ b/Task/Arithmetic-evaluation/EasyLang/arithmetic-evaluation.easy @@ -9,9 +9,7 @@ subr nch . # subr ntok - while ch$ = " " - nch - . + while ch$ = " " : nch if ch >= 48 and ch <= 58 tok$ = "n" s$ = "" @@ -33,14 +31,14 @@ subr init0 astright[] = [ ] err = 0 . -proc init s$ . . +proc init s$ . inp$[] = strchars s$ inp_ind = 1 nch ntok init0 . -proc ast_print nd . . +proc ast_print nd . write "AST:" for i to len astop$[] write " ( " diff --git a/Task/Arithmetic-geometric-mean-Calculate-Pi/EasyLang/arithmetic-geometric-mean-calculate-pi.easy b/Task/Arithmetic-geometric-mean-Calculate-Pi/EasyLang/arithmetic-geometric-mean-calculate-pi.easy index 0ebe1a31ba..3993aa60d6 100644 --- a/Task/Arithmetic-geometric-mean-Calculate-Pi/EasyLang/arithmetic-geometric-mean-calculate-pi.easy +++ b/Task/Arithmetic-geometric-mean-Calculate-Pi/EasyLang/arithmetic-geometric-mean-calculate-pi.easy @@ -11,5 +11,5 @@ while pn <= 5 pn *= 2 . mypi = (an + bn) * (an + bn) / (tn * 4) -numfmt 15 0 +numfmt 0 15 print mypi diff --git a/Task/Arithmetic-geometric-mean/C++/arithmetic-geometric-mean.cpp b/Task/Arithmetic-geometric-mean/C++/arithmetic-geometric-mean.cpp index e72ad24f16..71033b0d1f 100644 --- a/Task/Arithmetic-geometric-mean/C++/arithmetic-geometric-mean.cpp +++ b/Task/Arithmetic-geometric-mean/C++/arithmetic-geometric-mean.cpp @@ -1,28 +1,22 @@ -#include -using namespace std; -#define _cin ios_base::sync_with_stdio(0); cin.tie(0); -#define rep(a, b) for(ll i =a;i<=b;++i) +#include +#include -double agm(double a, double g) //ARITHMETIC GEOMETRIC MEAN -{ double epsilon = 1.0E-16,a1,g1; - if(a*g<0.0) - { cout<<"Couldn't find arithmetic-geometric mean of these numbers\n"; - exit(1); - } - while(fabs(a-g)>epsilon) - { a1 = (a+g)/2.0; - g1 = sqrt(a*g); - a = a1; - g = g1; - } - return a; +double agm(double a, double g, double tolerance = 1e-16) { + double an = a; + double gn = g; + + an = (a + g) / 2.0; + gn = std::sqrt(a*g); + while (std::abs(an-gn) > tolerance) { + an = (an + gn) / 2.0; + gn = std::sqrt(an*gn); + } + + return an; } -int main() -{ _cin; //fast input-output - double x, y; - cout<<"Enter X and Y: "; //Enter two numbers - cin>>x>>y; - cout<<"\nThe Arithmetic-Geometric Mean of "<= Float64::EPSILON + a, g = (a + g) / 2, Math.sqrt(a * g) + end + g +end + +p agm(1, 1 / Math.sqrt(2)) diff --git a/Task/Arithmetic-geometric-mean/EasyLang/arithmetic-geometric-mean.easy b/Task/Arithmetic-geometric-mean/EasyLang/arithmetic-geometric-mean.easy index 5f7ce66faf..978c4034e4 100644 --- a/Task/Arithmetic-geometric-mean/EasyLang/arithmetic-geometric-mean.easy +++ b/Task/Arithmetic-geometric-mean/EasyLang/arithmetic-geometric-mean.easy @@ -7,5 +7,5 @@ func agm a g . . return a . -numfmt 16 0 +numfmt 0 16 print agm 1 sqrt 0.5 diff --git a/Task/Arithmetic-numbers/Ballerina/arithmetic-numbers.ballerina b/Task/Arithmetic-numbers/Ballerina/arithmetic-numbers.ballerina new file mode 100644 index 0000000000..30f7f08c8e --- /dev/null +++ b/Task/Arithmetic-numbers/Ballerina/arithmetic-numbers.ballerina @@ -0,0 +1,98 @@ +import ballerina/io; + +function divisors(int n) returns int[] { + if n < 1 { return []; } + int[] divisors = []; + int[] divisors2 = []; + int i = 1; + int k = n % 2 == 0 ? 1 : 2; + while i * i <= n { + if n % i == 0 { + divisors.push(i); + int j = n / i; + if j != i { divisors2.push(j); } + } + i += k; + } + if divisors2.length() > 0 { + divisors.push(...divisors2.reverse()); + } + return divisors; +} + +function findNearest(int[] a, int value) returns int { + int count = a.length(); + int low = 0; + int high = count - 1; + while low <= high { + int mid = (low + high) / 2; + if a[mid] >= value { + high = mid - 1; + } else { + low = mid + 1; + } + } + return low < count ? low : count; +} + +function commatize(int n) returns string { + string s = n.toString(); + if n < 0 { s = s.substring(1); } + int le = s.length(); + foreach int i in int:range(le - 3, 0, -3) { + s = s.substring(0, i) + "," + s.substring(i); + } + if n >= 0 { return s; } + return "-" + s; +} + +function isPrime(int n) returns boolean { + if n < 2 { return false; } + if n % 2 == 0 { return n == 2; } + if n % 3 == 0 { return n == 3; } + int d = 5; + while d * d <= n { + if n % d == 0 { return false; } + d += 2; + if n % d == 0 { return false; } + d += 4; + } + return true; +} + +public function main() { + int[] arithmetic = [1]; + int[] primes = []; + final int lim = 1e6; + int n = 3; + while arithmetic.length() < lim { + int[] divs = divisors(n); + int len = divs.length(); + if len == 2 { + primes.push(n); + arithmetic.push(n); + } else { + int sum = int:sum(...divs); + if sum % len == 0 { arithmetic.push(n); } + } + n += 1; + } + io:println("The first 100 arithmetic numbers are:"); + foreach int i in 0...99 { + io:print(arithmetic[i].toString().padStart(4)); + if (i + 1) % 10 == 0 { io:println(); } + } + + foreach float f in [1e3, 1e4, 1e5, 1e6] { + int x = f; + int last = arithmetic[x - 1]; + string xc = commatize(x); + string lastc = commatize(last); + io:println("\nThe ", xc, "th arithmetic number is: ", lastc); + int pcount = findNearest(primes, last) + 1; + if !isPrime(last) { pcount -= 1; } + int comp = x - pcount - 1; // 1 is not composite + string compc = commatize(comp); + io:println(`"The count of such numbers <= ${lastc} which are composite is ${compc}.`); + } +} diff --git a/Task/Arithmetic-numbers/EasyLang/arithmetic-numbers.easy b/Task/Arithmetic-numbers/EasyLang/arithmetic-numbers.easy index cd8dc13f35..659573ce77 100644 --- a/Task/Arithmetic-numbers/EasyLang/arithmetic-numbers.easy +++ b/Task/Arithmetic-numbers/EasyLang/arithmetic-numbers.easy @@ -1,8 +1,5 @@ -print "The first 100 arithmetic numbers are:" -numfmt 0 3 -n = 1 -while aricnt <= 1e5 - divi = 1 ; divcnt = 0 ; sum = 0 +proc arith n &ari &comp . + divi = 1 repeat quot = n div divi until quot < divi @@ -17,20 +14,29 @@ while aricnt <= 1e5 . divi += 1 . - if sum mod divcnt = 0 - aricnt += 1 - if aricnt <= 100 - write n & " " - if aricnt mod 10 = 0 - print "" - . - . - if divcnt > 2 - compcnt += 1 - . - if aricnt = 1e3 or aricnt = 1e4 or aricnt = 1e5 + ari = if sum mod divcnt = 0 + comp = if divcnt > 2 +. +print "The first 100 arithmetic numbers are:" +n = 1 +while cnt < 100 + arith n ari comp + if ari = 1 + write n & " " + cnt += 1 + compcnt += comp + . + n += 1 +. +print "" +while cnt < 1e5 + arith n ari comp + if ari = 1 + cnt += 1 + compcnt += comp + if cnt = 1e3 or cnt = 1e4 or cnt = 1e5 print "" - print aricnt & "th arithmetic number: " & n + print cnt & "th arithmetic number: " & n print "Composite arithmetic numbers: " & compcnt . . diff --git a/Task/Arithmetic-numbers/REXX/arithmetic-numbers.rexx b/Task/Arithmetic-numbers/REXX/arithmetic-numbers.rexx index fd21689cfc..72dfe03689 100644 --- a/Task/Arithmetic-numbers/REXX/arithmetic-numbers.rexx +++ b/Task/Arithmetic-numbers/REXX/arithmetic-numbers.rexx @@ -1,16 +1,16 @@ +-- 8 May 2025 include Settings -say version; say 'Arithmetic numbers'; say +say 'ARITHMETIC NUMBERS' +say version +say numeric digits 9 -divi. = 0; a = 0; c = 0 -do i = 1 -/* Is the number arithmetic? */ +a = 0; c = 0 +do i = 1 to 1e6 if Arithmetic(i) then do a = a+1 -/* Is the number composite? */ - if divi.0 > 2 then + if Composite(i) then c = c+1 -/* Output control */ if a <= 100 then do if a = 1 then say 'First 100 arithmetic numbers are' @@ -25,14 +25,12 @@ do i = 1 say 'Of the first' a 'numbers' c 'are composite' say end -/* Max 1m, higher takes too long */ - if a = 1000000 then - leave end end say Format(Time('e'),,3) 'seconds' -exit +return include Numbers include Functions +include Special include Abend diff --git a/Task/Arithmetic-numbers/TypeScript/arithmetic-numbers.ts b/Task/Arithmetic-numbers/TypeScript/arithmetic-numbers.ts new file mode 100644 index 0000000000..617654bb18 --- /dev/null +++ b/Task/Arithmetic-numbers/TypeScript/arithmetic-numbers.ts @@ -0,0 +1,32 @@ +function divisors(n: number): number[] { + const divs = [1, n]; + const sqr = Math.sqrt(n); + for (let d = 2; d <= sqr; d++) { + if (n % d == 0) { + divs.push(d); + if (d != sqr) divs.push(n / d); + } + } // We don't really need to sort them for this task but it's nice to make + return divs.toSorted(function(a, b) {return a - b}); // functions reusable +} + +let count = 0; +let val = 0; +let composites = 0; +const arithList: number[] =[]; +const printValues = [1000, 10000, 100000, 1000000]; +while (count < 10**6) { + val += 1; + const divList = divisors(val); + const average = divList.reduce((a, b) => a + b) / divList.length; + if (Number.isInteger(average)) { + count += 1; + if (divList.length > 2) composites++; + if (count <= 100) arithList.push(val); + if (count == 100) console.log(arithList); + if (printValues.includes(count)) { + console.log("The " + count + "th arithmetic number is " + val); + console.log(composites + " of the first " + count + " are composite\n"); + } + } +} diff --git a/Task/Array-concatenation/Ballerina/array-concatenation.ballerina b/Task/Array-concatenation/Ballerina/array-concatenation.ballerina new file mode 100644 index 0000000000..3b036efa33 --- /dev/null +++ b/Task/Array-concatenation/Ballerina/array-concatenation.ballerina @@ -0,0 +1,7 @@ +import ballerina/io; + +public function main() { + int[3] a = [1, 2, 3]; + int[3] b = [4, 5, 6]; + io:println([...a, ...b]); +} diff --git a/Task/Array-concatenation/EasyLang/array-concatenation.easy b/Task/Array-concatenation/EasyLang/array-concatenation.easy index 80e53eb819..4776b79390 100644 --- a/Task/Array-concatenation/EasyLang/array-concatenation.easy +++ b/Task/Array-concatenation/EasyLang/array-concatenation.easy @@ -1,7 +1,5 @@ a[] = [ 1 2 3 ] b[] = [ 4 5 6 ] c[] = a[] -for h in b[] - c[] &= h -. +for h in b[] : c[] &= h print c[] diff --git a/Task/Array-concatenation/REXX/array-concatenation-1.rexx b/Task/Array-concatenation/REXX/array-concatenation-1.rexx deleted file mode 100644 index fe578fd7ad..0000000000 --- a/Task/Array-concatenation/REXX/array-concatenation-1.rexx +++ /dev/null @@ -1,3 +0,0 @@ -a.1 = 10 -a.2 = 22.7 -a.7 = -12 diff --git a/Task/Array-concatenation/REXX/array-concatenation-2.rexx b/Task/Array-concatenation/REXX/array-concatenation-2.rexx deleted file mode 100644 index c3441e86c0..0000000000 --- a/Task/Array-concatenation/REXX/array-concatenation-2.rexx +++ /dev/null @@ -1,9 +0,0 @@ -fact.0=8 -fact.1= 1 -fact.2= 2 -fact.3= 6 -fact.4= 24 -fact.5= 120 -fact.6= 720 -fact.7= 5040 -fact.8=40320 diff --git a/Task/Array-concatenation/REXX/array-concatenation-3.rexx b/Task/Array-concatenation/REXX/array-concatenation-3.rexx deleted file mode 100644 index ebea33a02e..0000000000 --- a/Task/Array-concatenation/REXX/array-concatenation-3.rexx +++ /dev/null @@ -1,22 +0,0 @@ -/*REXX program to demonstrates how to perform array concatenation.*/ - -p.= /*(below) a short list of primes.*/ -p.1=2; p.2=3; p.3=5; p.4=7; p.5=11; p.6=13 -p.7=17; p.8=19; p.9=23; p.10=27; p.11=31; p.12=37 - -f.= /*(below) a list of Fibonacci #s.*/ -f.0=0;f.1=1;f.2=1;f.3=2;f.4=3;f.5=5;f.6=8;f.7=13;f.8=21;f.9=34;f.10=55 - - do j=1 while p.j\=='' - c.j=p.j /*assign C array with some primes*/ - end /*j*/ -n=j-1 - do k=0 while f.k\==''; n=n+1 - c.n=f.k /*assign C array with fib numbers*/ - end /*k*/ -say 'elements=' n -say - do m=1 for n - say 'c.'m"="c.m /*show a "merged" C array nums.*/ - end /*m*/ - /*stick a fork in it, we're done.*/ diff --git a/Task/Array-concatenation/REXX/array-concatenation.rexx b/Task/Array-concatenation/REXX/array-concatenation.rexx new file mode 100644 index 0000000000..bed9e4bebc --- /dev/null +++ b/Task/Array-concatenation/REXX/array-concatenation.rexx @@ -0,0 +1,21 @@ +-- 1 Jun 2025 +include Settings + +say 'ARRAY CONCATENATION' +say version +say +say 'Two numbered arrays concatenated...' +a.1=1; a.2=4; a.3=9 +b.1=16; b.2=25; b.3=36 +a.0=3; b.0=3 +j=a.0 +do i = 1 to 3 + j=j+1; a.j=b.i +end +a.0=j +do i = 1 to a.0 + say i a.i +end +exit + +include Abend diff --git a/Task/Array-length/Ballerina/array-length.ballerina b/Task/Array-length/Ballerina/array-length.ballerina new file mode 100644 index 0000000000..527b36cba6 --- /dev/null +++ b/Task/Array-length/Ballerina/array-length.ballerina @@ -0,0 +1,6 @@ +import ballerina/io; + +public function main() { + string[2] fruits = ["apple", "orange"]; + io:println(fruits.length()); +} diff --git a/Task/Array-length/Uxntal/array-length.uxnatl b/Task/Array-length/Uxntal/array-length.uxnatl new file mode 100644 index 0000000000..8eea52095c --- /dev/null +++ b/Task/Array-length/Uxntal/array-length.uxnatl @@ -0,0 +1,18 @@ +%\0 { 00 } +%DBG { [ LIT2 01 -System/debug ] DEO } + +|0e @System/debug + +|100 + +;array len-arr DBG + +BRK + +@len-arr ( {array}* -- length* ) + LDA2k SWP2 INC2 INC2 SUB2 #01 SFT2 + JMP2r + +@array ={ =apple =orange } +@apple "apple \0 +@orange "orange \0 diff --git a/Task/Arrays/Ballerina/arrays.ballerina b/Task/Arrays/Ballerina/arrays.ballerina new file mode 100644 index 0000000000..4ee9e82094 --- /dev/null +++ b/Task/Arrays/Ballerina/arrays.ballerina @@ -0,0 +1,15 @@ +import ballerina/io; + +public function main() { + // fixed length array + int[4] a = [1, 4, 9, 16]; + // retrieve and print element at index 1 (zero indexing) + io:println(a[1]); + + // dynamic array + int[] b = []; + // push an element into it + b.push(42); + // retrieve and print last element added + io:println(b[b.length() - 1]); +} diff --git a/Task/Arrays/EasyLang/arrays.easy b/Task/Arrays/EasyLang/arrays.easy index a501a7a5e3..e336b8b6d3 100644 --- a/Task/Arrays/EasyLang/arrays.easy +++ b/Task/Arrays/EasyLang/arrays.easy @@ -1,8 +1,4 @@ len f[] 4 -for i = 1 to len f[] - f[i] = i -. -f[] &= 5 -for i = 1 to len f[] - print f[i] -. +for i = 1 to len f[] : f[i] = i +f[] &= 55 +print f[] diff --git a/Task/Arrays/Excel/arrays-1.excel b/Task/Arrays/Excel/arrays-1.excel new file mode 100644 index 0000000000..c183eeacbf --- /dev/null +++ b/Task/Arrays/Excel/arrays-1.excel @@ -0,0 +1,15 @@ +=LET( + ARRAY, LAMBDA(dim, [init], LET( + Y, LAMBDA(SELF, arr, + LAMBDA([a], [b], + IF(ISOMITTED(b), + INDEX(arr, a), + SELF(SELF, IF(SEQUENCE(ROWS(arr)) = a, b, arr)) + ) + ) + ), + Y(Y, IF(SEQUENCE(dim), IF(ISOMITTED(init), "", init))) + )), + my_arr, ARRAY(5, 0), + ... + ) diff --git a/Task/Arrays/Excel/arrays-2.excel b/Task/Arrays/Excel/arrays-2.excel new file mode 100644 index 0000000000..98da06bedd --- /dev/null +++ b/Task/Arrays/Excel/arrays-2.excel @@ -0,0 +1 @@ + new_arr, my_arr(1, "val1")(4, "val4") diff --git a/Task/Arrays/Excel/arrays-3.excel b/Task/Arrays/Excel/arrays-3.excel new file mode 100644 index 0000000000..19305e3c6e --- /dev/null +++ b/Task/Arrays/Excel/arrays-3.excel @@ -0,0 +1,16 @@ +=LET( + ARRAY, LAMBDA(dim, [init], LET( + Y, LAMBDA(SELF, arr, + LAMBDA([a], [b], + IF(ISOMITTED(b), + INDEX(arr, a), + SELF(SELF, IF(SEQUENCE(ROWS(arr)) = a, b, arr)) + ) + ) + ), + Y(Y, IF(SEQUENCE(dim), IF(ISOMITTED(init), "", init))) + )), + my_arr, ARRAY(5, 0), + new_arr, my_arr(1, "val1")(4, "val4"), + new_arr() + ) diff --git a/Task/Arrays/OPL/arrays.opl b/Task/Arrays/OPL/arrays.opl new file mode 100644 index 0000000000..74a007f56c --- /dev/null +++ b/Task/Arrays/OPL/arrays.opl @@ -0,0 +1,9 @@ +PROC main: + REM Declare an integer array of 10 elements and a string array of 10 elements, each up to 12 characters long. + LOCAL array1%(10),array2$(10,12) + REM Array element count starts at 1. + array1%(1)=128 + array2$(10)="Rosetta Code" + PRINT array1%(1),array2$(10) + GET +ENDP diff --git a/Task/Arrays/REXX/arrays-1.rexx b/Task/Arrays/REXX/arrays-1.rexx deleted file mode 100644 index d3a6e4d897..0000000000 --- a/Task/Arrays/REXX/arrays-1.rexx +++ /dev/null @@ -1,9 +0,0 @@ -/*REXX program demonstrates a simple array usage. */ -a.='not found' /*value for all a.xxx (so far).*/ - do j=1 to 100 /*start at 1, define 100 elements*/ - a.j=-j*1000 /*define as negative J thousand. */ - end /*j*/ /*the above defines 100 elements.*/ - -say 'element 50 is:' a.50 -say 'element 3000 is:' a.3000 - /*stick a fork in it, we're done.*/ diff --git a/Task/Arrays/REXX/arrays-2.rexx b/Task/Arrays/REXX/arrays-2.rexx deleted file mode 100644 index 83f0292649..0000000000 --- a/Task/Arrays/REXX/arrays-2.rexx +++ /dev/null @@ -1,11 +0,0 @@ -/*REXX program demonstrates array usage with mimicry. */ -a. = 'not found' /*value for all a.xxx (so far). */ - do j=1 to 100 /*start at 1, define 100 elements*/ - a.j = -j * 100 /*define element as -J hundred. */ - end /*j*/ /*the above defines 100 elements.*/ - -say 'element 50 is:' a(50) -say 'element 3000 is:' a(3000) -exit /*stick a fork in it, we're done.*/ -/*──────────────────────────────────A subroutine────────────────────────*/ -a: _a_ = arg(1); return a._a_ diff --git a/Task/Arrays/REXX/arrays-3.rexx b/Task/Arrays/REXX/arrays-3.rexx deleted file mode 100644 index cbcaccf54b..0000000000 --- a/Task/Arrays/REXX/arrays-3.rexx +++ /dev/null @@ -1,11 +0,0 @@ -/*REXX program demonstrates array usage with mimicry. */ -a. = 00 /*value for all a.xxx (so far). */ - do j=1 to 100 /*start at 1, define 100 elements*/ - a.j = -j * 100 /*define element as -J hundred. */ - end /*j*/ /*the above defines 100 elements.*/ - -say 'element 50 is:' a(50) -say 'element 3000 is:' a(3000) -exit /*stick a fork in it, we're done.*/ -/*──────────────────────────────────A subroutine────────────────────────*/ -a: _a_ = arg(1); return a._a_ diff --git a/Task/Arrays/REXX/arrays-4.rexx b/Task/Arrays/REXX/arrays-4.rexx deleted file mode 100644 index 6f976ce2ad..0000000000 --- a/Task/Arrays/REXX/arrays-4.rexx +++ /dev/null @@ -1,10 +0,0 @@ -/*REXX program demonstrates array usage (with elements out-of-range).*/ -array. = 'out of range' /*define ALL elements to this. */ - - do j=-3000 to 3000 /*start at -3k, going up to +3k.*/ - array.j=j**2 /*define element as its square. */ - end /*j*/ /* [↑] defines 6,001 elements. */ -g=-7 -say g "squared is:" array.g -say 7000 "squared is:" array.7000 - /*stick a fork in it, we're done.*/ diff --git a/Task/Arrays/REXX/arrays-5.rexx b/Task/Arrays/REXX/arrays-5.rexx deleted file mode 100644 index 9daf6ca54b..0000000000 --- a/Task/Arrays/REXX/arrays-5.rexx +++ /dev/null @@ -1,17 +0,0 @@ -/*REXX program demonstrates disjointed array usage. */ -yr. = 'year not supported' /*value for all yr.xxx (so far).*/ - - do k=600 to 1100 /*a bunch of years prior to 1800.*/ - yr.k=k "AD" /*Kth element as the year itself.*/ - end /*k*/ /* [↑] defines 501 elements.*/ - - do j=1800 to 2100 /*start at 1800, define a bunch. */ - yr.j=j 'AD' /*Jth element as the year itself.*/ - end /*j*/ /* [↑] defines 301 elements.*/ - -year=1946 -say 'DOB' year "is:" yr.year - -year=1744 -say 'DOB' year "is:" yr.year - /*stick a fork in it, we're done.*/ diff --git a/Task/Arrays/REXX/arrays-6.rexx b/Task/Arrays/REXX/arrays-6.rexx deleted file mode 100644 index 0d2e52addd..0000000000 --- a/Task/Arrays/REXX/arrays-6.rexx +++ /dev/null @@ -1,27 +0,0 @@ -/*REXX program demonstrates array usage: sparse and disjointed. */ - yyy = -55 /*REXX must use this mechanism···*/ -a.yyy = 1e9 /*··· when assigning neg indices.*/ - -a.1 = 1000 -a.2 = 2000.0001 -a.7 = 7000 -a.2012 = 'out here in left field.' -a.cat = 'civet, but not a true cat ─── belonging to the family Viverridae' -a.civet = "A.K.A.: toddycats" -/*┌────────────────────────────────────────────────────────────────────┐ - │ Array elements need not be continuous (nor even defined). They │ - │ can hold any manner of numbers, or strings (which can include any │ - │ characters, including null or '00'x characters). │ - │ │ - │ Array elements need not be numeric, as the above code demonstrates.│ - │ Indeed, the element "name" can be ANYTHING, even non-displayable │ - │ characters. To illustrate [↓]: │ - └────────────────────────────────────────────────────────────────────┘*/ -stuff=')g.u.t.s( or ½ of an intestine!' -a.stuff=44 -/*┌────────────────────────────────────────────────────────────────────┐ - │ where the element name has special characters: blanks, and the │ - │ glyph of one-half (½), as well as the symbol used in REXX to │ - │ identify stemmed arrays (the period). │ - └────────────────────────────────────────────────────────────────────┘*/ - /*stick a fork in it, we're done.*/ diff --git a/Task/Arrays/REXX/arrays.rexx b/Task/Arrays/REXX/arrays.rexx new file mode 100644 index 0000000000..74e20f3ddc --- /dev/null +++ b/Task/Arrays/REXX/arrays.rexx @@ -0,0 +1,67 @@ +-- 1 Jun 2025 +include Settings + +say 'ARRAYS' +say version +say +say 'A simple array...' +do i = 1 to 100 + a.i=i*i +end +say 'Square of' 5 'is' a.5 +say 'Square of' 55 'is' a.55 +say +say 'Mimic indexing...' +say 'Square of' 5 'is' a(5) +say 'Square of' 55 'is' a(55) +say +say 'A default value...' +b. = 'Out of range' +do i = 1 to 100 + b.i=1/i +end +say 'Inverse of' 5 'is' b.5 +say 'Inverse of' 55 'is' b.55 +say 'Inverse of' 555 'is' b.555 +say +say 'An other index range...' +do i = -100 to 100 + c.i=i*i*i +end +j=-55; say 'Cube of' j 'is' c.j +j=-5; say 'Cube of' j 'is' c.j +j=5; say 'Cube of' j 'is' c.j +j=55; say 'Cube of' j 'is' c.j +say +say 'A sparse array...' +d.='Not calculated' +do i = 2 by 2 to 100 + d.i=-i +end +say 'Negative of' 55 'is' d.55 +say 'Negative of' 56 'is' d.56 +say +say 'Special indices...' +e.cat='civet'; say 'e.cat =' e.cat +a1='dog'; e.a1='pitbull' +a2=a1; say 'e.'a2 '=' e.a2 +a1='x.y.z'; e.a1='periods' +a2=a1; say 'e.'a2 '=' e.a2 +a1='x y z'; e.a1='spaces' +a2=a1; say 'e.'a2 '=' e.a2 +a1='└┴┬├─┼'; e.a1='specials' +a2=a1; say 'e.'a2 '=' e.a2 +say +say 'Element has no value...' +signal off novalue +say 'f.notassigned =' f.notassigned +signal on novalue name Abend +say 'f.notassigned =' f.notassigned +exit + +A: +procedure expose a. +arg xx +return a.xx + +include Abend diff --git a/Task/Arrays/Tcl/arrays-1.tcl b/Task/Arrays/Tcl/arrays-1.tcl index 9d450d0cad..2c767014ca 100644 --- a/Task/Arrays/Tcl/arrays-1.tcl +++ b/Task/Arrays/Tcl/arrays-1.tcl @@ -1,8 +1,11 @@ -set ary {} +# empty list +set arr {} -lappend ary 1 -lappend ary 3 +# 10 integers +set arr [list 1 2 3 4 5 6 7 8 9 10 ] -lset ary 0 2 -puts [lindex $ary 0] +lappend arr 11 +lappend arr 12 + +puts stdout "$arr" diff --git a/Task/Arrays/Tcl/arrays-2.tcl b/Task/Arrays/Tcl/arrays-2.tcl index 89bc0d8cab..b899713d2a 100644 --- a/Task/Arrays/Tcl/arrays-2.tcl +++ b/Task/Arrays/Tcl/arrays-2.tcl @@ -1 +1,8 @@ -puts $ary; # Print the whole array +set x [lindex $arr 4] ; # x <= 5 + +foreach n $arr { + set idx [expr n -1] + lset arr $idx [expr $n * $n] +} + +puts stdout "$arr" diff --git a/Task/Arrays/Tcl/arrays-3.tcl b/Task/Arrays/Tcl/arrays-3.tcl new file mode 100644 index 0000000000..0348b27759 --- /dev/null +++ b/Task/Arrays/Tcl/arrays-3.tcl @@ -0,0 +1,2 @@ +set slice [lrange $arr 5 10] +puts stdout "$slice" diff --git a/Task/Arrays/Tcl/arrays-4.tcl b/Task/Arrays/Tcl/arrays-4.tcl new file mode 100644 index 0000000000..fb66cb8f7d --- /dev/null +++ b/Task/Arrays/Tcl/arrays-4.tcl @@ -0,0 +1,2 @@ +puts stdout "arr has [llength $arr] items." +puts stdout "slice has [llength $slice] items." diff --git a/Task/Arrays/Tcl/arrays-5.tcl b/Task/Arrays/Tcl/arrays-5.tcl new file mode 100644 index 0000000000..12cd8f0080 --- /dev/null +++ b/Task/Arrays/Tcl/arrays-5.tcl @@ -0,0 +1,4 @@ +set r [lreverse $arr] +set s [lsort -integer $r] +puts stdout $r +puts stdout $s diff --git a/Task/Arrays/Tcl/arrays-6.tcl b/Task/Arrays/Tcl/arrays-6.tcl new file mode 100644 index 0000000000..57c697ab42 --- /dev/null +++ b/Task/Arrays/Tcl/arrays-6.tcl @@ -0,0 +1,10 @@ +set term "calico" +set fd [open "cats.txt" "r"] +set contents [read $fd] +set lines [split $contents "\n"] + +foreach line $lines { + if { [lsearch $line $term] > 0 } { + puts "found $term in \"$line\"" + } +} diff --git a/Task/Ascending-primes/Ballerina/ascending-primes.ballerina b/Task/Ascending-primes/Ballerina/ascending-primes.ballerina new file mode 100644 index 0000000000..0134c472ca --- /dev/null +++ b/Task/Ascending-primes/Ballerina/ascending-primes.ballerina @@ -0,0 +1,38 @@ +import ballerina/io; + +function isPrime(int n) returns boolean { + if n < 2 { return false; } + if n % 2 == 0 { return n == 2; } + if n % 3 == 0 { return n == 3; } + int d = 5; + while d * d <= n { + if n % d == 0 { return false; } + d += 2; + if n % d == 0 { return false; } + d += 4; + } + return true; +} + +map ascPrimesSet = {}; // value will always be 1 to simulate a set + +function generate(int first, int cand, int digits) { + if digits == 0 { + if isPrime(cand) { ascPrimesSet[cand.toString()] = 1; } + return; + } + foreach int i in first...9 { + int next = cand * 10 + i; + generate(i + 1, next, digits - 1); + } +} + +public function main() returns error? { + foreach int digits in 1...9 { generate(1, 0, digits); } + int[] ascPrimes = ascPrimesSet.keys().map(k => check int:fromString(k)).sort(); + io:println("There are ", ascPrimes.length(), " ascending primes, namely:"); + foreach int i in 0 ..< ascPrimes.length() { + io:print(ascPrimes[i].toString().padStart(8), " "); + if (i + 1) % 10 == 0 { io:println(); } + } +} diff --git a/Task/Ascending-primes/EasyLang/ascending-primes.easy b/Task/Ascending-primes/EasyLang/ascending-primes.easy index 499d11769c..6f497f5811 100644 --- a/Task/Ascending-primes/EasyLang/ascending-primes.easy +++ b/Task/Ascending-primes/EasyLang/ascending-primes.easy @@ -1,25 +1,25 @@ -func isprim num . - if num < 2 - return 0 +proc sort &d[] . + for i = 1 to len d[] - 1 : for j = i + 1 to len d[] + if d[j] < d[i] : swap d[j] d[i] . +. +func isprim num . + if num < 2 : return 0 i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 . -proc nextasc n . . - if isprim n = 1 - write n & " " - . - if n > 123456789 - return - . +p[] = [ ] +proc nextasc n . + if isprim n = 1 : p[] &= n + if n > 123456789 : return for d = n mod 10 + 1 to 9 nextasc n * 10 + d . . nextasc 0 +sort p[] +print p[] diff --git a/Task/Ascending-primes/Rust/ascending-primes-1.rs b/Task/Ascending-primes/Rust/ascending-primes-1.rs new file mode 100644 index 0000000000..1342be405e --- /dev/null +++ b/Task/Ascending-primes/Rust/ascending-primes-1.rs @@ -0,0 +1,36 @@ +/// Call depth-first recursive function to generate increasing sizes of powerset integers whose +/// digits are strictly increasing. +/// +/// We then apply a primality test to each number (512 primality tests in total) +fn powerset_from_recursion() -> Vec { + let ps = powerset(123456789); + + ps.into_iter().filter(|n| is_prime(*n)).collect() +} + +/// Depth-first powerset integers generated through passed-in digits in base-10 +/// +/// Each returning `powerset` doubles its size, incorporating a new digit through each pass +/// +/// Ex: `rem = 3` and our `powerset = [0, 1, 2, 12]` +/// +/// `3` is "pushed back" to each value +/// +/// `[03, 13, 23, 123]` +/// +/// Which is then appended to the back of the original `powerset` +fn powerset(digits: u32) -> Vec { + let (rem, quo) = (digits % 10, digits / 10); + + // Base case + if rem == 0 { + // Having 0 allows adding `rem` as single digit to `new` + return vec![0]; + } + + let mut powerset = powerset(quo); + let new = powerset.clone().into_iter().map(|n| n * 10 + rem); + powerset.extend(new); + + powerset +} diff --git a/Task/Ascending-primes/Rust/ascending-primes-2.rs b/Task/Ascending-primes/Rust/ascending-primes-2.rs new file mode 100644 index 0000000000..798985fc37 --- /dev/null +++ b/Task/Ascending-primes/Rust/ascending-primes-2.rs @@ -0,0 +1,30 @@ +/// Uses a queue to calculate and store the next integer sequences to generate. +/// +/// The next sequence has the next power of 10 generated in lock-step from the front value +/// +/// Ex: `[1, 2, 3, 4, 5, 6, 7, 8, 9]` +/// +/// The front value `1` produces the next sequence +/// +/// `[12, 13, 14, 15, 16, 17, 18, 19]` +/// +/// Which is then appended to the back of the queue +/// +/// Due to the nature of this algorithm, no sorting is required but iteration is implemented in a +/// more procedural style +fn powerset_from_queue() -> Vec { + let mut dq = std::collections::VecDeque::from_iter(1..=9); + let mut primes = Vec::new(); + + while let Some(n) = dq.pop_front() { + if is_prime_v(n) { + primes.push(n); + } + + for rem in (n % 10 + 1)..=9 { + dq.push_back(n * 10 + rem); + } + } + + primes +} diff --git a/Task/Ascending-primes/Rust/ascending-primes-3.rs b/Task/Ascending-primes/Rust/ascending-primes-3.rs new file mode 100644 index 0000000000..e1a6b68a8b --- /dev/null +++ b/Task/Ascending-primes/Rust/ascending-primes-3.rs @@ -0,0 +1,43 @@ +/// Primality test by trial division. +/// +/// This algorithm avoids using hardware `div`s for 0-24 and from then on only checks with odd +/// factors that aren't themselves divisible by 3 up until √n +fn is_prime(n: u32) -> bool { + match n { + 0 | 1 => false, + _ if n % 2 == 0 => n == 2, + _ if n % 3 == 0 => n == 3, + _ => { + let mut factor = 5; + while factor * factor <= n { + if n % factor == 0 { + return false; + } + factor += 2; + if n % factor == 0 { + return false; + } + factor += 4; + } + + true + } + } +} + +fn main() { + let mut ps1 = powerset_from_recursion(); + let ps2 = powerset_from_queue(); + + ps1.sort(); + + assert_eq!(ps1, ps2); + + println!("There are {} ascending primes.", ps2.len()); + for row in ps2.chunks(10) { + for col in row { + print!("{:>9} ", col); + } + println!(); + } +} diff --git a/Task/Associative-array-Creation/Ballerina/associative-array-creation.ballerina b/Task/Associative-array-Creation/Ballerina/associative-array-creation.ballerina new file mode 100644 index 0000000000..6561149822 --- /dev/null +++ b/Task/Associative-array-Creation/Ballerina/associative-array-creation.ballerina @@ -0,0 +1,22 @@ +import ballerina/io; + +public function main() { + map fruit = {}; // creates an empty map + fruit["1"] = "orange"; // associates a key of "1" with "orange" + fruit["2"] = "apple"; // associates a key of "2" with "apple" + io:println(fruit["1"]); // retrieves the value with a key of "1" and prints it out + _ = fruit.remove("1"); // removes the entry with a key of "1" from the map + io:println(fruit); // prints the rest of the map + io:println(); + map capitals = { // creates a new map with three entries + "France": "Paris", + "Germany": "Berlin", + "Spain": "Madrid" + }; + capitals["Russia"] = "Moscow"; // adds another entry + io:println(capitals["France"]); // retrieves the "France" entry and prints out its capital + _ = capitals.remove("France"); // removes the "France" entry + io:println(capitals); // prints all remaining entries + io:println(capitals.length()); // prints the number of remaining entries + io:println(capitals["Sweden"]); // prints the entry for Sweden (nothing as there isn't one) +} diff --git a/Task/Associative-array-Creation/EasyLang/associative-array-creation.easy b/Task/Associative-array-Creation/EasyLang/associative-array-creation.easy index 5753f9d6ac..17858cd138 100644 --- a/Task/Associative-array-Creation/EasyLang/associative-array-creation.easy +++ b/Task/Associative-array-Creation/EasyLang/associative-array-creation.easy @@ -1,25 +1,22 @@ # use array of array for this -proc hashGet ind$ . ar$[][] item$ . - for i to len ar$[][] - if ar$[i][1] = ind$ - item$ = ar$[i][2] - return - . +func$ hget &arr$[][] ind$ . + for i to len arr$[][] + if arr$[i][1] = ind$ : return arr$[i][2] . - item$ = "" + return "" . -proc hashSet ind$ val$ . ar$[][] . - for i to len ar$[][] - if ar$[i][1] = ind$ - ar$[i][2] = val$ +proc hset &arr$[][] ind$ val$ . + for i to len arr$[][] + if arr$[i][1] = ind$ + arr$[i][2] = val$ return . . - ar$[][] &= [ ind$ val$ ] + arr$[][] &= [ ind$ val$ ] . clothing$[][] = [ [ "type" "t-shirt" ] [ "color" "red" ] ] clothing$[][] &= [ "size" "xl" ] # -hashSet "color" "green" clothing$[][] -hashGet "color" clothing$[][] col$ -print col$ +print hget clothing$[][] "color" +hset clothing$[][] "color" "green" +print hget clothing$[][] "color" diff --git a/Task/Associative-array-Iteration/Ballerina/associative-array-iteration.ballerina b/Task/Associative-array-Iteration/Ballerina/associative-array-iteration.ballerina new file mode 100644 index 0000000000..8281152635 --- /dev/null +++ b/Task/Associative-array-Iteration/Ballerina/associative-array-iteration.ballerina @@ -0,0 +1,22 @@ +import ballerina/io; + +public function main() { + // create a new map with four entries + map capitals = { + "France": "Paris", + "Germany": "Berlin", + "Russia": "Moscow", + "Spain": "Madrid" + }; + + // iterate through the map and print out the key/value pairs + foreach var e in capitals.entries() { io:println(e); } + io:println(); + + // iterate though the map and print out just the keys + foreach var k in capitals.keys() { io:println(k); } + io:println(); + + // iterate through the map and print out just the values + foreach var v in capitals { io:println(v); } +} diff --git a/Task/Associative-array-Merging/Ballerina/associative-array-merging.ballerina b/Task/Associative-array-Merging/Ballerina/associative-array-merging.ballerina new file mode 100644 index 0000000000..5f836afb1f --- /dev/null +++ b/Task/Associative-array-Merging/Ballerina/associative-array-merging.ballerina @@ -0,0 +1,15 @@ +import ballerina/io; + +function mergeMaps(map m1, map m2) returns map { + map m3 = {}; + foreach string key in m1.keys() { m3[key] = m1.get(key); } + foreach string key in m2.keys() { m3[key] = m2.get(key); } + return m3; +} + +public function main() { + map base = { "name": "Rocket Skates" , "price": 12.75, "color": "yellow" }; + map update = { "price": 15.25, "color": "red", "year": 1974 }; + map merged = mergeMaps(base, update); + io:println(re `,`.replaceAll(merged.toString(), ", ")); +} diff --git a/Task/Associative-array-Merging/Common-Lisp/associative-array-merging-3.lisp b/Task/Associative-array-Merging/Common-Lisp/associative-array-merging-3.lisp new file mode 100644 index 0000000000..f39c68a072 --- /dev/null +++ b/Task/Associative-array-Merging/Common-Lisp/associative-array-merging-3.lisp @@ -0,0 +1,28 @@ +(defun merge-hash-tables (hashtable &rest other-hashtables) + (let ((result (make-hash-table :test (hash-table-test hashtable)))) + (dolist (ht (list* hashtable other-hashtables)) + (maphash #'(lambda (k v) (setf (gethash k result) v)) ht)) + result)) + +;; aux functions +(defun make-hash-table-from-alist (alist &key (test 'equal)) + (let ((result (make-hash-table :test test))) + (loop for (k . v) in alist + do (setf (gethash k result) v)) + result)) +(defun make-alist-from-hash-table (hashtable) + (let ((result ())) + (maphash #'(lambda (k v) (setf result (acons k v result))) hashtable) + (nreverse result))) + +;; solving the task +(let ((base (make-hash-table-from-alist '(("name" . "Rocket Skates") + ("price" . 12.75) + ("color" . "yellow")))) + (update (make-hash-table-from-alist '(("price" . 15.25) + ("color" . "red") + ("year" . 1974))))) + (format t "base: ~a~%update: ~a~%merged: ~a~%" + (make-alist-from-hash-table base) + (make-alist-from-hash-table update) + (make-alist-from-hash-table (merge-hash-tables base update)))) diff --git a/Task/Associative-array-Merging/EasyLang/associative-array-merging.easy b/Task/Associative-array-Merging/EasyLang/associative-array-merging.easy index 7c929e84fc..9f95724e21 100644 --- a/Task/Associative-array-Merging/EasyLang/associative-array-merging.easy +++ b/Task/Associative-array-Merging/EasyLang/associative-array-merging.easy @@ -1,6 +1,6 @@ base$[][] = [ [ "name" "Rocket Skates" ] [ "price" 12.75 ] [ "color" "yellow" ] ] update$[][] = [ [ "price" 15.25 ] [ "color" "red" ] [ "year" 1974 ] ] -proc update . a$[][] b$[][] . +proc update &a$[][] &b$[][] . for b to len b$[][] for a to len a$[][] if a$[a][1] = b$[b][1] @@ -8,9 +8,7 @@ proc update . a$[][] b$[][] . break 1 . . - if a > len a$[][] - a$[][] &= b$[b][] - . + if a > len a$[][] : a$[][] &= b$[b][] . . update base$[][] update$[][] diff --git a/Task/Associative-array-Merging/JavaScript/associative-array-merging.js b/Task/Associative-array-Merging/JavaScript/associative-array-merging.js index 763232ea62..93ff25c9ef 100644 --- a/Task/Associative-array-Merging/JavaScript/associative-array-merging.js +++ b/Task/Associative-array-Merging/JavaScript/associative-array-merging.js @@ -1,18 +1,19 @@ -(() => { - 'use strict'; +const base = { + "name": "Rocket Skates", + "price": 12.75, + "color": "yellow" +}; - console.log(JSON.stringify( - Object.assign({}, // Fresh dictionary. - { // Base. - "name": "Rocket Skates", - "price": 12.75, - "color": "yellow" - }, { // Update. - "price": 15.25, - "color": "red", - "year": 1974 - } - ), - null, 2 - )) -})(); +const update = { + "price": 15.25, + "color": "red", + "year": 1974 +}; + +// While ES6 destructuring may be cleaner, using Object.assign (provided in the original answer) instead is about 15-20% faster. +// source: https://jsbench.me/jom7uh9o1t/1 + +const final = Object.assign(base, update); +// Using ES6 destructuring method: const final = { ...base, ...update }; + +console.log(JSON.stringify(final, null, 4)); diff --git a/Task/Attractive-numbers/EasyLang/attractive-numbers.easy b/Task/Attractive-numbers/EasyLang/attractive-numbers.easy index 6128796beb..b4f08ed64a 100644 --- a/Task/Attractive-numbers/EasyLang/attractive-numbers.easy +++ b/Task/Attractive-numbers/EasyLang/attractive-numbers.easy @@ -1,12 +1,8 @@ func isprim num . - if num < 2 - return 0 - . + if num < 2 : return 0 i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 @@ -26,7 +22,5 @@ func count n . . for i = 2 to 120 n = count i - if isprim n = 1 - write i & " " - . + if isprim n = 1 : write i & " " . diff --git a/Task/Attractive-numbers/OCaml/attractive-numbers.ml b/Task/Attractive-numbers/OCaml/attractive-numbers.ml new file mode 100644 index 0000000000..ea8520abef --- /dev/null +++ b/Task/Attractive-numbers/OCaml/attractive-numbers.ml @@ -0,0 +1,26 @@ +let is_prime (n : int) : bool = + if n = 2 then true else if n < 2 || n mod 2 = 0 then false else + let lim = (n |> float_of_int |> sqrt |> int_of_float) + 1 in + let rec loop = function + | i when i > lim -> true + | i when n mod i = 0 -> false + | i -> loop (i + 2) + in loop 3 + +let prime_factors (n : int) : int list = + let rec loop = function + | factors, i, r when r = 1 -> factors + | factors, i, r when is_prime i && r mod i = 0 + -> loop (i :: factors, i, r / i) + | factors, i, r -> loop (factors, i+1, r) + in loop ([], 2, n) + +let is_attractive (n : int) : bool = + n |> prime_factors |> List.length |> is_prime + +let () = + List.init 120 ((+) 1) + |> List.filter is_attractive + |> List.map string_of_int + |> String.concat "," + |> Printf.printf "[%s]" diff --git a/Task/Attractive-numbers/PARI-GP/attractive-numbers-1.parigp b/Task/Attractive-numbers/PARI-GP/attractive-numbers-1.parigp new file mode 100644 index 0000000000..73068e2021 --- /dev/null +++ b/Task/Attractive-numbers/PARI-GP/attractive-numbers-1.parigp @@ -0,0 +1 @@ +select(n->isprime(bigomega(n)), [1..120]) diff --git a/Task/Attractive-numbers/PARI-GP/attractive-numbers-2.parigp b/Task/Attractive-numbers/PARI-GP/attractive-numbers-2.parigp new file mode 100644 index 0000000000..0a6b81ede0 --- /dev/null +++ b/Task/Attractive-numbers/PARI-GP/attractive-numbers-2.parigp @@ -0,0 +1 @@ +forfactored(n=1,120, if(isprime(bigomega(n)), print1(n[1]", "))) diff --git a/Task/Average-loop-length/EasyLang/average-loop-length.easy b/Task/Average-loop-length/EasyLang/average-loop-length.easy index 664aba7a05..a0d216ea9d 100644 --- a/Task/Average-loop-length/EasyLang/average-loop-length.easy +++ b/Task/Average-loop-length/EasyLang/average-loop-length.easy @@ -1,9 +1,7 @@ func average n reps . for r to reps f[] = [ ] - for i to n - f[] &= random n - . + for i to n : f[] &= random n seen[] = [ ] len seen[] n x = 1 @@ -30,8 +28,8 @@ for n to 20 avg = average n 1e6 ana = analytical n err = (avg - ana) / ana * 100 - numfmt 0 2 + numfmt 2 0 write n - numfmt 4 9 + numfmt 9 4 print avg & ana & err & "%" . diff --git a/Task/Average-loop-length/JavaScript/average-loop-length.js b/Task/Average-loop-length/JavaScript/average-loop-length.js new file mode 100644 index 0000000000..68e1ae0b93 --- /dev/null +++ b/Task/Average-loop-length/JavaScript/average-loop-length.js @@ -0,0 +1,49 @@ +const MAX_N = 20 +const TIMES = 1000000 + +function factorial(n) { + let prod = 1; + for (let i = n; i > 1; i--) { + prod *= i; + } + return prod; +} + +function getRandomInt(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min + 1)) + min; +} + + +function analytical(n) { + let items = []; + + for (let i = 1; i < n+1; i++) { + items.push(factorial(n) / Math.pow(n, i) / factorial(n - i)); + } + + return items.reduce((p, v) => p + v, 0); +} + +function test(n, times) { + let count = 0; + for (let i = 0; i < times; i++) { + let x = 1, bits = 0; + + while (!(bits & x)) { + count += 1; + bits |= x; + x = 1 << getRandomInt(0, n-1); + } + } + return count / times; +} + +console.log(" n\tavg\texp.\tdiff\n-------------------------------"); +for(let n = 1; n < MAX_N+1; n++) { + const avg = test(n, TIMES); + const theory = analytical(n); + const diff = (avg / theory - 1) * 100; + console.log(`${n.toString().padStart(2)} ${avg.toFixed(4).padStart(8)} ${theory.toFixed(4).padStart(8)} ${diff.toFixed(3).padStart(6)}%`); +} diff --git a/Task/Averages-Arithmetic-mean/Ballerina/averages-arithmetic-mean.ballerina b/Task/Averages-Arithmetic-mean/Ballerina/averages-arithmetic-mean.ballerina new file mode 100644 index 0000000000..cc6dc8d288 --- /dev/null +++ b/Task/Averages-Arithmetic-mean/Ballerina/averages-arithmetic-mean.ballerina @@ -0,0 +1,22 @@ +import ballerina/io; + +function average(decimal[] a) returns decimal { + decimal sum = 0; + if a.length() == 0 { return 0d; } + foreach decimal i in a { sum += i; } + return sum / a.length(); +} + +public function main() { + // fixed length array + decimal[6] a = [1, 2, 3, 4, 5, 6]; + io:println(decimal:avg(...a)); + + // variable length array + decimal[] b = a; + io:println(average(b)); + + // empty variable length array + decimal[] c = []; + io:println(average(c)); +} diff --git a/Task/Averages-Arithmetic-mean/EasyLang/averages-arithmetic-mean.easy b/Task/Averages-Arithmetic-mean/EasyLang/averages-arithmetic-mean.easy index e14e43c02e..4e9bb83c20 100644 --- a/Task/Averages-Arithmetic-mean/EasyLang/averages-arithmetic-mean.easy +++ b/Task/Averages-Arithmetic-mean/EasyLang/averages-arithmetic-mean.easy @@ -1,9 +1,6 @@ -proc mean . f[] r . - for i = 1 to len f[] - s += f[i] - . - r = s / len f[] +func mean &f[] . + for i = 1 to len f[] : s += f[i] + return s / len f[] . f[] = [ 1 2 3 4 5 6 7 8 ] -mean f[] r -print r +print mean f[] diff --git a/Task/Averages-Mean-angle/Ballerina/averages-mean-angle.ballerina b/Task/Averages-Mean-angle/Ballerina/averages-mean-angle.ballerina new file mode 100644 index 0000000000..c654d6721f --- /dev/null +++ b/Task/Averages-Mean-angle/Ballerina/averages-mean-angle.ballerina @@ -0,0 +1,27 @@ +import ballerina/io; + +function meanAngle(float[] angles) returns float { + int n = angles.length(); + float sinSum = 0.0; + float cosSum = 0.0; + foreach float angle in angles { + float radians = angle * float:PI / 180.0; + sinSum += radians.sin(); + cosSum += radians.cos(); + } + return float:atan2(sinSum / n, cosSum / n) * 180.0 / float:PI; +} + +public function main() { + var angles = [ + [350.0, 10.0], + [90.0, 180.0, 270.0, 360.0], + [10.0, 20.0, 30.0] + ]; + int i = 1; + foreach var a in angles { + string mean = meanAngle(a).round(1).toString().padStart(5); + io:println("Mean for angles ", i, " is : ", mean); + i += 1; + } +} diff --git a/Task/Averages-Mean-time-of-day/Ballerina/averages-mean-time-of-day.ballerina b/Task/Averages-Mean-time-of-day/Ballerina/averages-mean-time-of-day.ballerina new file mode 100644 index 0000000000..382b905a35 --- /dev/null +++ b/Task/Averages-Mean-time-of-day/Ballerina/averages-mean-time-of-day.ballerina @@ -0,0 +1,42 @@ +import ballerina/io; + +function timeToDegs(string time) returns float|error { + var t = re `:`.split(time); + int h = check int:fromString(t[0]) * 3600; + int m = check int:fromString(t[1]) * 60; + int s = check int:fromString(t[2]); + return (h + m + s) / 240.0; +} + +function padInt(int i, int len) returns string { + return i.toString().padZero(len); +} + +function degsToTime(float degs) returns string { + float d = degs; + while d < 0.0 { d = d + 360.0; } + int s = (d * 240.00).round(); + int h = s / 3600; + int m = s % 3600; + s = m % 60; + m /= 60; + return padInt(h, 2) + ":" + padInt(m, 2) + ":" + padInt(s, 2); +} + +function meanAngle(float[] angles) returns float { + int n = angles.length(); + float sinSum = 0.0; + float cosSum = 0.0; + foreach float angle in angles { + float radians = angle * float:PI / 180.0; + sinSum += radians.sin(); + cosSum += radians.cos(); + } + return float:atan2(sinSum / n, cosSum / n) * 180.0 / float:PI; +} + +public function main() returns error? { + var times = ["23:00:17", "23:40:20", "00:12:45", "00:17:19"]; + var angles = times.map(t => check timeToDegs(t)); + io:println("Mean time of day is : ", degsToTime(meanAngle(angles))); +} diff --git a/Task/Averages-Median/Ballerina/averages-median.ballerina b/Task/Averages-Median/Ballerina/averages-median.ballerina new file mode 100644 index 0000000000..7b24c1ffa5 --- /dev/null +++ b/Task/Averages-Median/Ballerina/averages-median.ballerina @@ -0,0 +1,20 @@ +import ballerina/io; + +function median(float[] floats) returns float { + var fs = floats.sort(); + int len = fs.length(); + if (len % 2 == 1) { + return fs[len / 2]; + } + return (fs[len / 2 - 1] + fs[len / 2]) / 2.0; +} + +public function main() { + float[][] lists = [ + [5.0, 3.0, 4.0], + [3.0, 4.0, 1.0, -8.4, 7.2, 4.0, 1.0, 1.2] + ]; + foreach var list in lists { + io:println(median(list)); + } +} diff --git a/Task/Averages-Median/EasyLang/averages-median.easy b/Task/Averages-Median/EasyLang/averages-median.easy index 51e508db90..63c7dcaa3b 100644 --- a/Task/Averages-Median/EasyLang/averages-median.easy +++ b/Task/Averages-Median/EasyLang/averages-median.easy @@ -1,5 +1,4 @@ -proc quickselect k . list[] res . - # +func quickselect &list[] k . subr partition mid = left for i = left + 1 to right @@ -22,19 +21,16 @@ proc quickselect k . list[] res . left = right . . - res = list[k] + return list[k] . -proc median . list[] res . +func median &list[] . h = len list[] div 2 + 1 - quickselect h list[] res - if len list[] mod 2 = 0 - quickselect h - 1 list[] h - res = (res + h) / 2 - . + r1 = quickselect list[] h + if len list[] mod 2 = 1 : return r1 + r2 = quickselect list[] (h - 1) + return (r1 + r2) / 2 . test[] = [ 4.1 5.6 7.2 1.7 9.3 4.4 3.2 ] -median test[] med -print med +print median test[] test[] = [ 4.1 7.2 1.7 9.3 4.4 3.2 ] -median test[] med -print med +print median test[] diff --git a/Task/Averages-Mode/Ballerina/averages-mode.ballerina b/Task/Averages-Mode/Ballerina/averages-mode.ballerina new file mode 100644 index 0000000000..cfea56d7ed --- /dev/null +++ b/Task/Averages-Mode/Ballerina/averages-mode.ballerina @@ -0,0 +1,27 @@ +import ballerina/io; + +function mode(int[] arr) returns int[]|error { + map m = {}; + foreach int e in arr { + string k = e.toString(); + if !m.hasKey(k) { m[k] = 0; } + m[k] = m.get(k) + 1; + } + int max = int:MIN_VALUE; + int[] modes = []; + foreach string k in m.keys() { + int v = m.get(k); + if v > max { + max = v; + modes.removeAll(); + } + if v >= max { + modes.push(check int:fromString(k)); + } + } + return modes; +} + +public function main() { + io:println(mode([1, 2, 3, 4, 5, 5, 51, 2, 3])); +} diff --git a/Task/Averages-Mode/Crystal/averages-mode.cr b/Task/Averages-Mode/Crystal/averages-mode.cr new file mode 100644 index 0000000000..f8f01672a8 --- /dev/null +++ b/Task/Averages-Mode/Crystal/averages-mode.cr @@ -0,0 +1,6 @@ +def mode (seq) + seq.tally.group_by {|n, count| count }.max[1].map {|n, count| n } +end + +p mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]) +p mode([1, 1, 2, 4, 4]) diff --git a/Task/Averages-Mode/EasyLang/averages-mode.easy b/Task/Averages-Mode/EasyLang/averages-mode.easy index 5824a333b4..79a069b46a 100644 --- a/Task/Averages-Mode/EasyLang/averages-mode.easy +++ b/Task/Averages-Mode/EasyLang/averages-mode.easy @@ -1,4 +1,4 @@ -proc modes . in[] r[] . +proc modes &in[] &r[] . r[] = [ ] for v in in[] for i to len vals[] @@ -12,9 +12,7 @@ proc modes . in[] r[] . cnt[] &= 0 . for i to len cnt[] - if cnt[i] = max - r[] &= vals[i] - . + if cnt[i] = max : r[] &= vals[i] . . in[] = [ 1 3 6 6 6 6 7 7 12 12 17 ] diff --git a/Task/Averages-Pythagorean-means/Ballerina/averages-pythagorean-means.ballerina b/Task/Averages-Pythagorean-means/Ballerina/averages-pythagorean-means.ballerina new file mode 100644 index 0000000000..352cc79d99 --- /dev/null +++ b/Task/Averages-Pythagorean-means/Ballerina/averages-pythagorean-means.ballerina @@ -0,0 +1,21 @@ +import ballerina/io; + +public function main() { + final int n = 10; + var arr = from int i in 1...n select i; + float len = arr.length(); + + var sum = function(float total, float next) returns float => total + next; + var prod = function(float total, float next) returns float => total * next; + var rsum = function(float total, float next) returns float => total + 1.0 / next; + + var am = arr.reduce(sum, 0.0) / len; + var gm = arr.reduce(prod, 1.0).pow(1.0 / len); + var hm = arr.reduce(rsum, 0.0).pow(-1.0) * len; + + io:println("For the numbers 1 to ", n, ":"); + io:println(" Arithmetic mean = ", am); + io:println(" Geometric mean = ", gm); + io:println(" Harmonic mean = ", hm); + io:println(" A >= G >= H = ", am >= gm && gm >= hm); +} diff --git a/Task/Averages-Pythagorean-means/Crystal/averages-pythagorean-means.cr b/Task/Averages-Pythagorean-means/Crystal/averages-pythagorean-means.cr new file mode 100644 index 0000000000..508bb911fb --- /dev/null +++ b/Task/Averages-Pythagorean-means/Crystal/averages-pythagorean-means.cr @@ -0,0 +1,24 @@ +module Mean + def self.arithmetic (seq) + seq.sum / seq.size + end + + def self.geometric (seq) + seq.product ** (1/seq.size) + end + + def self.harmonic (seq) + seq.size / seq.sum {|x| 1/x } + end +end + +seq = (1..10) + +a = Mean.arithmetic(seq) +g = Mean.geometric(seq) +h = Mean.harmonic(seq) + +puts "A = #{a}" +puts "G = #{g}" +puts "H = #{h}" +puts "A >= G >= H = #{a >= g >= h}" diff --git a/Task/Averages-Pythagorean-means/EasyLang/averages-pythagorean-means.easy b/Task/Averages-Pythagorean-means/EasyLang/averages-pythagorean-means.easy index 3c7c1af491..f9aa5a43e0 100644 --- a/Task/Averages-Pythagorean-means/EasyLang/averages-pythagorean-means.easy +++ b/Task/Averages-Pythagorean-means/EasyLang/averages-pythagorean-means.easy @@ -1,4 +1,4 @@ -proc mean . v[] a g h . +proc mean &v[] &a &g &h . prod = 1 for v in v[] sum += v diff --git a/Task/Averages-Root-mean-square/Ballerina/averages-root-mean-square.ballerina b/Task/Averages-Root-mean-square/Ballerina/averages-root-mean-square.ballerina new file mode 100644 index 0000000000..6253aff98f --- /dev/null +++ b/Task/Averages-Root-mean-square/Ballerina/averages-root-mean-square.ballerina @@ -0,0 +1,8 @@ +import ballerina/io; + +public function main() { + int[] a = from int i in 1...10 select i; + var sumSq = function(int total, int i) returns int => total + i * i; + float rms = (a.reduce(sumSq, 0) / 10.0).sqrt(); + io:println(rms); +} diff --git a/Task/Averages-Simple-moving-average/Ballerina/averages-simple-moving-average.ballerina b/Task/Averages-Simple-moving-average/Ballerina/averages-simple-moving-average.ballerina new file mode 100644 index 0000000000..07c801246b --- /dev/null +++ b/Task/Averages-Simple-moving-average/Ballerina/averages-simple-moving-average.ballerina @@ -0,0 +1,33 @@ +import ballerina/io; + +function sma(int period) returns (function(float) returns float) { + int i = 0; + float sum = 0.0; + float[] storage = []; + + return function(float input) returns float { + if storage.length() < period { + sum += input; + storage.push(input); + } + sum += input - storage[i]; + storage[i] = input; + i = (i + 1) % period; + return sum / storage.length(); + }; +} + +function F(float f, int size, int prec) returns string { + string s = f.toFixedString(prec); + return size >= 0 ? s.padStart(size) : s.padEnd(size); +} + +public function main() { + var sma3 = sma(3); + var sma5 = sma(5); + io:println(" x sma3 sma5"); + float[] rng = [1, 2, 3, 4, 5, 5, 4, 3, 2, 1]; + foreach float x in rng { + io:println(`${F(x, 5, 3)} ${F(sma3(x), 5, 3)} ${F(sma5(x), 5, 3)}`); + } +} diff --git a/Task/Averages-Simple-moving-average/EasyLang/averages-simple-moving-average.easy b/Task/Averages-Simple-moving-average/EasyLang/averages-simple-moving-average.easy index e9bdc2bb67..7d437b97f3 100644 --- a/Task/Averages-Simple-moving-average/EasyLang/averages-simple-moving-average.easy +++ b/Task/Averages-Simple-moving-average/EasyLang/averages-simple-moving-average.easy @@ -23,7 +23,7 @@ prefix # sma5 = sma_new 5 sma3 = sma_new 3 -numfmt 2 4 +numfmt 4 2 for v in [ 1 2 3 4 5 5 4 3 2 1 ] print sma_get sma3 v & " " & sma_get sma5 v . diff --git a/Task/B-zier-curves-Intersections/Fortran/b-zier-curves-intersections.f b/Task/B-zier-curves-Intersections/Fortran/b-zier-curves-intersections.f new file mode 100644 index 0000000000..418fb69093 --- /dev/null +++ b/Task/B-zier-curves-Intersections/Fortran/b-zier-curves-intersections.f @@ -0,0 +1,286 @@ +program bezier_intersections + ! This program does not do any subdivision, but instead takes + ! advantage of monotonicity. + ! + ! It is possible for points accidentally to be counted twice, for + ! instance if they lie right on an interval boundary. We will avoid + ! that by the crude (but likely satisfactory) mechanism of requiring + ! a minimum max norm between intersections. + implicit none + + ! Constants + integer, parameter :: max_intersections = 4 + integer, parameter :: max_start_interv = 4 + integer, parameter :: max_workload = 1000 ! Maximum size for workload stack + double precision, parameter :: px0 = -1.0, px1 = 0.0, px2 = 1.0 + double precision, parameter :: py0 = 0.0, py1 = 10.0, py2 = 0.0 + double precision, parameter :: qx0 = 2.0, qx1 = -8.0, qx2 = 2.0 + double precision, parameter :: qy0 = 1.0, qy1 = 2.0, qy2 = 3.0 + double precision, parameter :: tol = 0.0000001 + double precision, parameter :: spacing = 100.0 * tol + + ! Variables + logical :: px_has_extreme_pt, py_has_extreme_pt + logical :: qx_has_extreme_pt, qy_has_extreme_pt + double precision :: px_extreme_pt, py_extreme_pt + double precision :: qx_extreme, qy_extreme + integer :: p_num_start_interv, q_num_start_interv + double precision :: p_start_interv(max_start_interv) + double precision :: q_start_interv(max_start_interv) + double precision :: workload(4, max_workload) ! tp0, tp1, tq0, tq1 + integer :: workload_size + integer :: num_intersections + double precision :: intersections_x(max_intersections) + double precision :: intersections_y(max_intersections) + integer :: i, j, k + double precision :: tp0, tp1, tq0, tq1 + double precision :: xp0, xp1, xq0, xq1 + double precision :: yp0, yp1, yq0, yq1 + logical :: exclude, accept + double precision :: x, y + double precision :: tp_middle, tq_middle + +! Main program logic + ! Find monotonic sections of the curves, and use those as the + ! starting jobs. + p_num_start_interv = 2 + p_start_interv(1) = 0.0 + p_start_interv(2) = 1.0 + call possibly_insert_extreme_point(px0, px1, px2, p_num_start_interv, p_start_interv) + call possibly_insert_extreme_point(py0, py1, py2, p_num_start_interv, p_start_interv) + q_num_start_interv = 2 + q_start_interv(1) = 0.0 + q_start_interv(2) = 1.0 + call possibly_insert_extreme_point(qx0, qx1, qx2, q_num_start_interv, q_start_interv) + call possibly_insert_extreme_point(qy0, qy1, qy2, q_num_start_interv, q_start_interv) + + workload_size = 0 + do i = 2, p_num_start_interv + do j = 2, q_num_start_interv + call defer_work(p_start_interv(i - 1), p_start_interv(i), & + q_start_interv(j - 1), q_start_interv(j)) + end do + end do + + ! Go through the workload, deferring work as necessary. + num_intersections = 0 + do while (.not. work_is_done()) + ! The following code recomputes values of the splines + ! sometimes. You may wish to store such values in the work pile, + ! to avoid recomputing them. + call do_some_work(tp0, tp1, tq0, tq1) + xp0 = schumaker_volk(px0, px1, px2, tp0) + yp0 = schumaker_volk(py0, py1, py2, tp0) + xp1 = schumaker_volk(px0, px1, px2, tp1) + yp1 = schumaker_volk(py0, py1, py2, tp1) + xq0 = schumaker_volk(qx0, qx1, qx2, tq0) + yq0 = schumaker_volk(qy0, qy1, qy2, tq0) + xq1 = schumaker_volk(qx0, qx1, qx2, tq1) + yq1 = schumaker_volk(qy0, qy1, qy2, tq1) + call test_intersection(xp0, xp1, yp0, yp1, xq0, xq1, yq0, yq1, tol, exclude, accept, x, y) + if (accept) then + call maybe_add_intersection(x, y, spacing) + else if (.not. exclude) then + tp_middle = 0.5 * (tp0 + tp1) + tq_middle = 0.5 * (tq0 + tq1) + call defer_work(tp0, tp_middle, tq0, tq_middle) + call defer_work(tp0, tp_middle, tq_middle, tq1) + call defer_work(tp_middle, tp1, tq0, tq_middle) + call defer_work(tp_middle, tp1, tq_middle, tq1) + end if + end do + + if (num_intersections == 0) then + print *, 'no intersections' + else + do k = 1, num_intersections + write (*, '(A, F12.8, A, F12.8, A)') '(', intersections_x(k), ', ', intersections_y(k), ')' + end do + end if + +contains + + ! Schumaker's and Volk's algorithm for evaluating a Bezier spline in + ! Bernstein basis. This is faster than de Casteljau, though not quite + ! as numerical stable. + double precision function schumaker_volk(c0, c1, c2, t) + double precision, intent(IN) :: c0, c1, c2, t + double precision :: s, u, v + s = 1.0 - t + if (t <= 0.5) then + ! Horner form in the variable u = t/s, taking into account the + ! binomial coefficients = 1,2,1. + u = t / s + v = c0 + (u * (c1 + c1 + (u * c2))) + ! Multiply by s raised to the degree of the spline. + v = v * s * s + else + ! Horner form in the variable u = s/t, taking into account the + ! binomial coefficients = 1,2,1. + u = s / t + v = c2 + (u * (c1 + c1 + (u * c0))) + ! Multiply by t raised to the degree of the spline. + v = v * t * t + end if + schumaker_volk = v + end function schumaker_volk + + ! Find extreme point of a quadratic Bezier spline + subroutine find_extreme_point(c0, c1, c2, lies_inside_01, extreme_point) + double precision, intent(IN) :: c0, c1, c2 + logical, intent(OUT) :: lies_inside_01 + double precision, intent(OUT) :: extreme_point + double precision :: numer, denom + ! If the spline has c0=c2 but not c0=c1=c2, then treat it as having + ! an extreme point at 0.5. + if (c0 == c2 .and. c0 /= c1) then + lies_inside_01 = .true. + extreme_point = 0.5 + else + ! Find the root of the derivative of the spline. + lies_inside_01 = .false. + numer = c0 - c1 + denom = c2 - c1 - c1 + c0 + if (denom /= 0.0 .and. numer * denom >= 0.0 .and. numer <= denom) then + lies_inside_01 = .true. + extreme_point = numer / denom + end if + end if + end subroutine find_extreme_point + + ! Insert extreme point into start intervals if it lies in (0,1) + subroutine possibly_insert_extreme_point(c0, c1, c2, num_start_interv, start_interv) + double precision, intent(IN) :: c0, c1, c2 + integer, intent(INOUT) :: num_start_interv + double precision, intent(INOUT) :: start_interv(max_start_interv) + logical :: lies_inside_01 + double precision :: extreme_pt + call find_extreme_point(c0, c1, c2, lies_inside_01, extreme_pt) + if (lies_inside_01 .and. extreme_pt > 0.0 .and. extreme_pt < 1.0) then + if (num_start_interv == 2) then + start_interv(3) = 1.0 + start_interv(2) = extreme_pt + num_start_interv = 3 + else if (extreme_pt < start_interv(2)) then + start_interv(4) = 1.0 + start_interv(3) = start_interv(2) + start_interv(2) = extreme_pt + num_start_interv = 4 + else if (extreme_pt > start_interv(2)) then + start_interv(4) = 1.0 + start_interv(3) = extreme_pt + num_start_interv = 4 + end if + end if + end subroutine possibly_insert_extreme_point + + ! Minimum of two values + double precision function minimum2(x, y) + double precision, intent(IN) :: x, y + minimum2 = min(x, y) + end function minimum2 + + ! Maximum of two values + double precision function maximum2(x, y) + double precision, intent(IN) :: x, y + maximum2 = max(x, y) + end function maximum2 + + ! Check if two rectangles overlap + logical function rectangles_overlap(xa0, ya0, xa1, ya1, xb0, yb0, xb1, yb1) + double precision, intent(IN) :: xa0, ya0, xa1, ya1, xb0, yb0, xb1, yb1 + ! It is assumed that xa0<=xa1, ya0<=ya1, xb0<=xb1, and yb0<=yb1. + rectangles_overlap = (xb0 <= xa1 .and. xa0 <= xb1 .and. yb0 <= ya1 .and. ya0 <= yb1) + end function rectangles_overlap + + ! Test for intersection between two line segments + subroutine test_intersection(xp0, xp1, yp0, yp1, xq0, xq1, yq0, yq1, tol, exclude, accept, x, y) + double precision, intent(IN) :: xp0, xp1, yp0, yp1, xq0, xq1, yq0, yq1, tol + logical, intent(OUT) :: exclude, accept + double precision, intent(OUT) :: x, y + double precision :: xpmin, ypmin, xpmax, ypmax + double precision :: xqmin, yqmin, xqmax, yqmax + double precision :: xmin, xmax, ymin, ymax + xpmin = minimum2(xp0, xp1) + ypmin = minimum2(yp0, yp1) + xpmax = maximum2(xp0, xp1) + ypmax = maximum2(yp0, yp1) + xqmin = minimum2(xq0, xq1) + yqmin = minimum2(yq0, yq1) + xqmax = maximum2(xq0, xq1) + yqmax = maximum2(yq0, yq1) + exclude = .true. + accept = .false. + if (rectangles_overlap(xpmin, ypmin, xpmax, ypmax, xqmin, yqmin, xqmax, yqmax)) then + exclude = .false. + xmin = maximum2(xpmin, xqmin) + xmax = minimum2(xpmax, xqmax) + if (xmax < xmin) stop 'Assertion failed: xmax >= xmin' + if (xmax - xmin <= tol) then + ymin = maximum2(ypmin, yqmin) + ymax = minimum2(ypmax, yqmax) + if (ymax < ymin) stop 'Assertion failed: ymax >= ymin' + if (ymax - ymin <= tol) then + accept = .true. + x = 0.5 * (xmin + xmax) + y = 0.5 * (ymin + ymax) + end if + end if + end if + end subroutine test_intersection + + ! Check if workload is empty + logical function work_is_done() + work_is_done = (workload_size == 0) + end function work_is_done + + ! Add work to the workload stack + subroutine defer_work(tp0, tp1, tq0, tq1) + double precision, intent(IN) :: tp0, tp1, tq0, tq1 + if (workload_size >= max_workload) stop 'Error: Workload stack overflow' + workload_size = workload_size + 1 + workload(1, workload_size) = tp0 + workload(2, workload_size) = tp1 + workload(3, workload_size) = tq0 + workload(4, workload_size) = tq1 + end subroutine defer_work + + ! Remove and return work from the workload stack + subroutine do_some_work(tp0, tp1, tq0, tq1) + double precision, intent(OUT) :: tp0, tp1, tq0, tq1 + if (work_is_done()) stop 'Assertion failed: Workload is empty' + tp0 = workload(1, workload_size) + tp1 = workload(2, workload_size) + tq0 = workload(3, workload_size) + tq1 = workload(4, workload_size) + workload_size = workload_size - 1 + end subroutine do_some_work + + ! Add intersection point if it's not too close to existing ones + subroutine maybe_add_intersection(x, y, spacing) + double precision, intent(IN) :: x, y, spacing + integer :: i + logical :: too_close + if (num_intersections == 0) then + intersections_x(1) = x + intersections_y(1) = y + num_intersections = 1 + else + too_close = .false. + do i = 1, num_intersections + if (abs(x - intersections_x(i)) < spacing .and. & + abs(y - intersections_y(i)) < spacing) then + too_close = .true. + exit + end if + end do + if (.not. too_close) then + if (num_intersections >= max_intersections) stop 'Too many intersections' + num_intersections = num_intersections + 1 + intersections_x(num_intersections) = x + intersections_y(num_intersections) = y + end if + end if + end subroutine maybe_add_intersection + +end program bezier_intersections diff --git a/Task/B-zier-curves-Intersections/Mathematica/b-zier-curves-intersections.math b/Task/B-zier-curves-Intersections/Mathematica/b-zier-curves-intersections.math new file mode 100644 index 0000000000..62d124f937 --- /dev/null +++ b/Task/B-zier-curves-Intersections/Mathematica/b-zier-curves-intersections.math @@ -0,0 +1,7 @@ +ClearAll[BezierFunc] +BezierFunc[pts_List, \[Alpha]_] := Nest[BlockMap[Apply[(1 - \[Alpha]) #1 + \[Alpha] #2 &], #, 2, 1] &, pts, Length[pts] - 1][[1]] +b1 = BezierFunc[{{-1, 0}, {0, 10}, {1, 0}}, s]; +b2 = BezierFunc[{{2, 1}, {-8, 2}, {2, 3}}, t]; +eqs = Thread[b1 == b2]; +{s, t, b1} /. Solve[%, {s, t}]; +Grid[N[%]] diff --git a/Task/B-zier-curves-Intersections/Rust/b-zier-curves-intersections.rs b/Task/B-zier-curves-Intersections/Rust/b-zier-curves-intersections.rs new file mode 100644 index 0000000000..44e656af33 --- /dev/null +++ b/Task/B-zier-curves-Intersections/Rust/b-zier-curves-intersections.rs @@ -0,0 +1,198 @@ +use std::f64; + +const TOLERANCE: f64 = 0.000_000_1; +const SPACING: f64 = 10.0 * TOLERANCE; + +// Replaces std::pair +#[derive(Debug, Clone, Copy, PartialEq, Default)] +struct Point { + x: f64, + y: f64, +} + +impl Point { + fn new(x: f64, y: f64) -> Self { + Point { x, y } + } +} + +// Replaces quad_spline class +#[derive(Debug, Clone, Copy, Default)] +struct QuadSpline { + c0: f64, + c1: f64, + c2: f64, +} + +impl QuadSpline { + fn new(c0: f64, c1: f64, c2: f64) -> Self { + QuadSpline { c0, c1, c2 } + } + + /// de Casteljau's algorithm for 1D spline subdivision + /// Returns two new splines, representing the curve from 0->t and t->1 + fn subdivide(&self, t: f64) -> (QuadSpline, QuadSpline) { + let s = 1.0 - t; + let u_c0 = self.c0; + let v_c2 = self.c2; + let u_c1 = s * self.c0 + t * self.c1; + let v_c1 = s * self.c1 + t * self.c2; + let u_c2 = s * u_c1 + t * v_c1; + let v_c0 = u_c2; + + let u = QuadSpline::new(u_c0, u_c1, u_c2); + let v = QuadSpline::new(v_c0, v_c1, v_c2); + (u, v) + } + + // Helper to get min/max control points for bounding box + fn min_max(&self) -> (f64, f64) { + let min_val = self.c0.min(self.c1).min(self.c2); + let max_val = self.c0.max(self.c1).max(self.c2); + (min_val, max_val) + } +} + +// Replaces quad_curve class +#[derive(Debug, Clone, Copy, Default)] +struct QuadCurve { + x: QuadSpline, + y: QuadSpline, +} + +impl QuadCurve { + fn new(x: QuadSpline, y: QuadSpline) -> Self { + QuadCurve { x, y } + } + + /// de Casteljau's algorithm for 2D curve subdivision + /// Returns two new curves, representing the curve from 0->t and t->1 + fn subdivide(&self, t: f64) -> (QuadCurve, QuadCurve) { + let (ux, vx) = self.x.subdivide(t); + let (uy, vy) = self.y.subdivide(t); + (QuadCurve::new(ux, uy), QuadCurve::new(vx, vy)) + } + + /// Calculate the axis-aligned bounding box (AABB) + fn bounding_box(&self) -> (f64, f64, f64, f64) { + let (px_min, px_max) = self.x.min_max(); + let (py_min, py_max) = self.y.min_max(); + (px_min, py_min, px_max, py_max) + } +} + +/// Checks if two axis-aligned rectangles overlap +fn rectangles_overlap( + xa0: f64, ya0: f64, xa1: f64, ya1: f64, + xb0: f64, yb0: f64, xb1: f64, yb1: f64, +) -> bool { + // Ensure coordinates are ordered min -> max if necessary, although bounding_box should handle this. + // let (xa0, xa1) = if xa0 > xa1 { (xa1, xa0) } else { (xa0, xa1) }; + // let (ya0, ya1) = if ya0 > ya1 { (ya1, ya0) } else { (ya0, ya1) }; + // let (xb0, xb1) = if xb0 > xb1 { (xb1, xb0) } else { (xb0, xb1) }; + // let (yb0, yb1) = if yb0 > yb1 { (yb1, yb0) } else { (yb0, yb1) }; + + xb0 <= xa1 && xa0 <= xb1 && yb0 <= ya1 && ya0 <= yb1 +} + +/// Test intersection candidacy based on bounding box overlap and size. +/// Returns: (accepted, excluded, potential_intersect_point) +fn test_intersection(p: &QuadCurve, q: &QuadCurve) -> (bool, bool, Point) { + let (px_min, py_min, px_max, py_max) = p.bounding_box(); + let (qx_min, qy_min, qx_max, qy_max) = q.bounding_box(); + + let mut accepted = false; + let mut excluded = true; + let mut intersect = Point::default(); // Default point (0.0, 0.0) + + if rectangles_overlap(px_min, py_min, px_max, py_max, qx_min, qy_min, qx_max, qy_max) { + excluded = false; + // Calculate overlap region + let x_min = px_min.max(qx_min); + let x_max = px_max.min(qx_max); // Corrected from C++ possible typo px_max.min(px_max) + if x_max - x_min <= TOLERANCE { + let y_min = py_min.max(qy_min); + let y_max = py_max.min(qy_max); + if y_max - y_min <= TOLERANCE { + accepted = true; + // Use midpoint of the tiny overlap box as the intersection point + intersect = Point::new(0.5 * (x_min + x_max), 0.5 * (y_min + y_max)); + } + } + } + (accepted, excluded, intersect) +} + +/// Check if a point is too close to existing intersection points +fn seems_to_be_duplicate(intersects: &[Point], pt: Point) -> bool { + for &intersect in intersects { + if (intersect.x - pt.x).abs() < SPACING && (intersect.y - pt.y).abs() < SPACING { + return true; + } + } + false +} + +/// Find intersection points between two quadratic Bezier curves using recursive subdivision. +fn find_intersects(p: &QuadCurve, q: &QuadCurve) -> Vec { + let mut result: Vec = Vec::new(); + // Use a Vec as a stack, storing pairs of curves to check + // Pushing/popping individual curves to mimic C++ stack behavior exactly + let mut stack: Vec = Vec::new(); + stack.push(*q); // Push q first (will be popped as qq) + stack.push(*p); // Push p second (will be popped as pp) + + while stack.len() >= 2 { + // Pop in the order that matches the C++ version's stack processing + let pp = stack.pop().unwrap(); // Pop p-curve segment + let qq = stack.pop().unwrap(); // Pop q-curve segment + + let (accepted, excluded, intersect) = test_intersection(&pp, &qq); + + if accepted { + if !seems_to_be_duplicate(&result, intersect) { + result.push(intersect); + } + } else if !excluded { + // Bounding boxes overlap significantly, subdivide both curves + let (p0, p1) = pp.subdivide(0.5); + let (q0, q1) = qq.subdivide(0.5); + + // Push the 4 pairs of sub-curves onto the stack for further testing. + // Order matches the C++ version's push order { p0, q0, p0, q1, p1, q0, p1, q1 } + // Processed pairs will be (p0,q0), (p0,q1), (p1,q0), (p1,q1) eventually. + // Push in reverse order of desired processing: + stack.push(q1); stack.push(p1); // For pair (p1, q1) + stack.push(q0); stack.push(p1); // For pair (p1, q0) + stack.push(q1); stack.push(p0); // For pair (p0, q1) + stack.push(q0); stack.push(p0); // For pair (p0, q0) + } + // If excluded, do nothing, this pair of segments cannot intersect. + } + result +} + +fn main() { + // QuadCurve vertical represents the Bezier curve having control points (-1, 0), (0, 10) and (1, 0) + let vertical = QuadCurve::new( + QuadSpline::new(-1.0, 0.0, 1.0), + QuadSpline::new(0.0, 10.0, 0.0), + ); + // QuadCurve horizontal represents the Bezier curve having control points (2, 1), (-8, 2) and (2, 3) + let horizontal = QuadCurve::new( + QuadSpline::new(2.0, -8.0, 2.0), + QuadSpline::new(1.0, 2.0, 3.0), + ); + + println!("The points of intersection are:"); + let intersects = find_intersects(&vertical, &horizontal); + + if intersects.is_empty() { + println!("No intersections found."); + } else { + for intersect in intersects { + // Format output similar to C++ version + println!("( {:9.6}, {:9.6} )", intersect.x, intersect.y); + } + } +} diff --git a/Task/Babylonian-spiral/EasyLang/babylonian-spiral.easy b/Task/Babylonian-spiral/EasyLang/babylonian-spiral.easy new file mode 100644 index 0000000000..888e9c378e --- /dev/null +++ b/Task/Babylonian-spiral/EasyLang/babylonian-spiral.easy @@ -0,0 +1,70 @@ +fastfunc findj a norm . + j = floor sqrt norm + 1 + repeat + b = j * j + if a + b < norm : return -1 + if a + b = norm : return j + until j = 0 + j -= 1 + . + return -1 +. +proc babylon_spiral nsteps &pts[][] . + pts[][] = [ [ 0 0 ] [ 0 1 ] ] + norm = 1 + last[] = pts[$][] + for k to nsteps - 2 + theta = atan2 last[2] last[1] + cands[][] = [ ] + while len cands[][] = 0 + norm += 1 + for i = 0 to nsteps + a = i * i + if a > norm div 2 : break 1 + j = findj a norm + if j <> -1 + cands[][] &= [ i, j ] + cands[][] &= [ -i, j ] + cands[][] &= [ i, -j ] + cands[][] &= [ -i, -j ] + cands[][] &= [ j, i ] + cands[][] &= [ -j, i ] + cands[][] &= [ j, -i ] + cands[][] &= [ -j, -i ] + . + . + . + min = 1 / 0 + for i to len cands[][] + h = (theta - atan2 cands[i][2] cands[i][1]) mod 360 + if h < min + min = h + mini = i + . + . + last[] = cands[mini][] + pts[][] &= pts[$][] + pts[$][1] += last[1] + pts[$][2] += last[2] + . +. +babylon_spiral 40 pts[][] +print pts[][] +# +babylon_spiral 10000 pts[][] +for i to len pts[][] + minx = lower minx pts[i][1] + maxx = higher maxx pts[i][1] + miny = lower miny pts[i][2] + maxy = higher maxy pts[i][2] +. +scx = 100 / (maxx - minx) * 0.96 +scy = 100 / (maxy - miny) * 0.96 +ty = -miny * scy + 2 +tx = -minx * scx + 2 +glinewidth 0.1 +for i to len pts[][] - 1 + gline 0 ty 100 ty + gline tx 0 tx 100 + gline pts[i][1] * scx + tx, pts[i][2] * scy + ty, pts[i + 1][1] * scx + tx, pts[i + 1][2] * scy + ty +. diff --git a/Task/Balanced-brackets/Ballerina/balanced-brackets.ballerina b/Task/Balanced-brackets/Ballerina/balanced-brackets.ballerina new file mode 100644 index 0000000000..bbae2976c8 --- /dev/null +++ b/Task/Balanced-brackets/Ballerina/balanced-brackets.ballerina @@ -0,0 +1,34 @@ +import ballerina/io; +import ballerina/random; + +function isBalanced(string s) returns boolean { + if s == "" { return true; } + int countLeft = 0; // number of left brackets so far unmatched + foreach var c in s { + if c == "[" { + countLeft += 1; + } else if countLeft > 0 { + countLeft -= 1; + } else { + return false; + } + } + return countLeft == 0; +} + +public function main() { + io:println("Checking examples in task description:"); + var brackets = ["", "[]", "][", "[][]", "][][", "[[][]]", "[]][[]"]; + foreach string b in brackets { + io:print((b != "") ? b : "(empty)"); + io:println("\t ", isBalanced(b) ? "OK" : "NOT OK"); + } + io:println("\nChecking 7 random strings of brackets of length 8:"); + foreach int i in 1...7 { + string s = ""; + foreach int j in 1...8 { + s += random:createIntInRange(0, 2) == 0 ? "[" : "]"; + } + io:println(s, " ", isBalanced(s) ? "OK" : "NOT OK"); + } +} diff --git a/Task/Balanced-brackets/Excel/balanced-brackets-3.excel b/Task/Balanced-brackets/Excel/balanced-brackets-3.excel new file mode 100644 index 0000000000..6a039e391e --- /dev/null +++ b/Task/Balanced-brackets/Excel/balanced-brackets-3.excel @@ -0,0 +1 @@ +=REDUCE(A2, SEQUENCE(MAX(1, LEN(A2))), LAMBDA(a, _, SUBSTITUTE(a, "[]", ))) = "" diff --git a/Task/Balanced-brackets/Excel/balanced-brackets-4.excel b/Task/Balanced-brackets/Excel/balanced-brackets-4.excel new file mode 100644 index 0000000000..64246d94af --- /dev/null +++ b/Task/Balanced-brackets/Excel/balanced-brackets-4.excel @@ -0,0 +1 @@ +=REDUCE(REGEXREPLACE(A2, "[^\[\]]", ), SEQUENCE(MAX(1, LEN(A2))), LAMBDA(a, _, SUBSTITUTE(a, "[]", ))) = "" diff --git a/Task/Balanced-ternary/00-TASK.txt b/Task/Balanced-ternary/00-TASK.txt index 6b6f6bb48f..f548e4c8c0 100644 --- a/Task/Balanced-ternary/00-TASK.txt +++ b/Task/Balanced-ternary/00-TASK.txt @@ -10,13 +10,13 @@ Decimal 6 = 32 − 31 + 0 × 30, thus it can b ;Task: Implement balanced ternary representation of integers with the following: # Support arbitrarily large integers, both positive and negative; -# Provide ways to convert to and from text strings, using digits '+', '-' and '0' (unless you are already using strings to represent balanced ternary; but see requirement 5). +# Provide ways to convert to and from text strings, using digits '+', '−' and '0' (unless you are already using strings to represent balanced ternary; but see requirement 5). # Provide ways to convert to and from native integer type (unless, improbably, your platform's native integer type ''is'' balanced ternary). If your native integers can't support arbitrary length, overflows during conversion must be indicated. # Provide ways to perform addition, negation and multiplication directly on balanced ternary integers; do ''not'' convert to native integers first. # Make your implementation efficient, with a reasonable definition of "efficient" (and with a reasonable definition of "reasonable"). -'''Test case''' With balanced ternaries ''a'' from string "+-0++0+", ''b'' from native integer -436, ''c'' "+-++-": +'''Test case''' With balanced ternaries ''a'' from string "+−0++0+", ''b'' from native integer −436, ''c'' "+−++−": * write out ''a'', ''b'' and ''c'' in decimal notation; * calculate ''a'' × (''b'' − ''c''), write out the result in both ternary and decimal notations. diff --git a/Task/Barnsley-fern/EasyLang/barnsley-fern.easy b/Task/Barnsley-fern/EasyLang/barnsley-fern.easy index 3d5e535c80..4176e236d7 100644 --- a/Task/Barnsley-fern/EasyLang/barnsley-fern.easy +++ b/Task/Barnsley-fern/EasyLang/barnsley-fern.easy @@ -1,21 +1,20 @@ -color 060 +gcolor 060 for i = 1 to 200000 - r = randomf - if r < 0.01 - nx = 0 - ny = 0.16 * y - elif r < 0.08 - nx = 0.2 * x - 0.26 * y - ny = 0.23 * x + 0.22 * y + 1.6 - elif r < 0.15 - nx = -0.15 * x + 0.28 * y - ny = 0.26 * x + 0.24 * y + 0.44 - else - nx = 0.85 * x + 0.04 * y - ny = -0.04 * x + 0.85 * y + 1.6 - . - x = nx - y = ny - move 50 + x * 15 y * 10 - rect 0.3 0.3 + r = randomf + if r < 0.01 + nx = 0 + ny = 0.16 * y + elif r < 0.08 + nx = 0.2 * x - 0.26 * y + ny = 0.23 * x + 0.22 * y + 1.6 + elif r < 0.15 + nx = -0.15 * x + 0.28 * y + ny = 0.26 * x + 0.24 * y + 0.44 + else + nx = 0.85 * x + 0.04 * y + ny = -0.04 * x + 0.85 * y + 1.6 + . + x = nx + y = ny + grect 50 + x * 15 y * 10 0.3 0.3 . diff --git a/Task/Bell-numbers/C-sharp/bell-numbers.cs b/Task/Bell-numbers/C-sharp/bell-numbers-1.cs similarity index 100% rename from Task/Bell-numbers/C-sharp/bell-numbers.cs rename to Task/Bell-numbers/C-sharp/bell-numbers-1.cs diff --git a/Task/Bell-numbers/C-sharp/bell-numbers-2.cs b/Task/Bell-numbers/C-sharp/bell-numbers-2.cs new file mode 100644 index 0000000000..f2da84e2ba --- /dev/null +++ b/Task/Bell-numbers/C-sharp/bell-numbers-2.cs @@ -0,0 +1,25 @@ +using System.Numerics; + +foreach (var row in BellTriangle().Take(15)) +{ + Console.WriteLine(row[0]); +} + +Console.WriteLine(BellTriangle().ElementAt(49)[0]); + +foreach (var row in BellTriangle().Take(10)) +{ + Console.WriteLine(string.Join(", ", row)); +} + +IEnumerable> BellTriangle() +{ + List row = [1]; + + while (true) + { + yield return row; + var scan = row[^1]; + row = [scan, .. row.Select(r => scan += r) ]; + } +} diff --git a/Task/Benfords-law/EasyLang/benfords-law.easy b/Task/Benfords-law/EasyLang/benfords-law.easy index 56624832fb..3a1d767aa2 100644 --- a/Task/Benfords-law/EasyLang/benfords-law.easy +++ b/Task/Benfords-law/EasyLang/benfords-law.easy @@ -6,14 +6,12 @@ func$ add a$ b$ . c = r div 10 r$ &= r mod 10 . - if c > 0 - r$ &= c - . + if c > 0 : r$ &= c return r$ . # len fibdist[] 9 -proc mkfibdist . . +proc mkfibdist . # generate 1000 fibonacci numbers as # (reversed) strings, because 53 bit # integers are too small @@ -36,14 +34,14 @@ proc mkfibdist . . mkfibdist # len benfdist[] 9 -proc mkbenfdist . . +proc mkbenfdist . for i to 9 benfdist[i] = log10 (1 + 1.0 / i) . . mkbenfdist # -numfmt 3 0 +numfmt 0 3 print "Actual Expected" for i to 9 print fibdist[i] & " " & benfdist[i] diff --git a/Task/Best-shuffle/EasyLang/best-shuffle.easy b/Task/Best-shuffle/EasyLang/best-shuffle.easy index ef0e2ef7bf..4f6a5e338f 100644 --- a/Task/Best-shuffle/EasyLang/best-shuffle.easy +++ b/Task/Best-shuffle/EasyLang/best-shuffle.easy @@ -1,4 +1,4 @@ -proc best_shuffle s$ . r$ diff . +proc best_shuffle s$ &r$ &diff . l = len s$ for c$ in strchars s$ s[] &= strcode c$ diff --git a/Task/Bifid-cipher/EasyLang/bifid-cipher.easy b/Task/Bifid-cipher/EasyLang/bifid-cipher.easy index 0a26b043a8..df84986ae6 100644 --- a/Task/Bifid-cipher/EasyLang/bifid-cipher.easy +++ b/Task/Bifid-cipher/EasyLang/bifid-cipher.easy @@ -1,4 +1,4 @@ -proc prepare . s$ . +proc prepare &s$ . for e$ in strchars s$ h = strcode e$ if h >= 97 diff --git a/Task/Bifid-cipher/JavaScript/bifid-cipher.js b/Task/Bifid-cipher/JavaScript/bifid-cipher.js new file mode 100644 index 0000000000..a4f210b4c0 --- /dev/null +++ b/Task/Bifid-cipher/JavaScript/bifid-cipher.js @@ -0,0 +1,199 @@ +// ADFGVX Cipher Implementation in JavaScript + +// Cipher squares +const squareRosetta = [ // from Rosetta Code + ['A', 'B', 'C', 'D', 'E'], + ['F', 'G', 'H', 'I', 'K'], + ['L', 'M', 'N', 'O', 'P'], + ['Q', 'R', 'S', 'T', 'U'], + ['V', 'W', 'X', 'Y', 'Z'], + ['J', '1', '2', '3', '4'] +]; + +const squareWikipedia = [ // from Wikipedia + ['B', 'G', 'W', 'K', 'Z'], + ['Q', 'P', 'N', 'D', 'S'], + ['I', 'O', 'A', 'X', 'E'], + ['F', 'C', 'L', 'U', 'M'], + ['T', 'H', 'Y', 'V', 'R'], + ['J', '1', '2', '3', '4'] +]; + +// Test text strings +const textRosetta = "0ATTACKATDAWN"; +const textRosettaEncoded = "DQBDAXDQPDQH"; // only for test +const textWikipedia = "FLEEATONCE"; +const textWikipediaEncoded = "UAEOLWRINS"; // only for test +const textTest = "The invasion will start on the first of January"; +const textTestEncoded = "RASOAQXFIOORXESXADETSWLTNIAZQOISBRGBALY"; // only for test + +// Coordinate class (equivalent to koord struct in Go) +class Coord { + constructor(x, y) { + this.x = x; + this.y = y; + } + + lessThan(other) { + if (this.y > other.y) { + return false; + } + if (this.y < other.y) { + return true; + } + if (this.x < other.x) { + return true; + } + return false; + } + + equalTo(other) { + return this.x === other.x && this.y === other.y; + } +} + +// Convert square to encryption and decryption maps +function squareToMaps(square) { + const encryptMap = new Map(); + const decryptMap = new Map(); + + for (let x = 0; x < square.length; x++) { + for (let y = 0; y < square[x].length; y++) { + const value = square[x][y]; + const coord = new Coord(x, y); + + // For encryption map, use character as key + encryptMap.set(value, coord); + + // For decryption map, use coordinate string as key + // (JavaScript Maps can't use objects as keys directly, so convert to string) + decryptMap.set(`${x},${y}`, value); + } + } + + return { encryptMap, decryptMap }; +} + +// Remove spaces and non-valid characters +function removeSpace(text, encryptMap) { + const upper = text.toUpperCase().replace(/\s/g, ''); + let result = ''; + + for (const char of upper) { + if (encryptMap.has(char)) { + result += char; + } + } + + return result; +} + +// Replace 'J' with 'I' (for specific Polybius square implementations) +function removeSpaceI(text) { + const upper = text.toUpperCase(); + let result = ''; + + for (const char of upper) { + // Use only ASCII characters from A to Z + if (char >= 'A' && char <= 'Z') { + result += char === 'J' ? 'I' : char; + } + } + + return result; +} + +// Encrypt using ADFGVX cipher +function encrypt(text, encryptMap, decryptMap) { + text = removeSpace(text, encryptMap); + + const row0 = []; + const row1 = []; + + // Get coordinates for each character + for (const char of text) { + const coord = encryptMap.get(char); + row0.push(coord.x); + row1.push(coord.y); + } + + // Combine coordinates + const combined = [...row0, ...row1]; + + let result = ''; + // Convert pairs of coordinates back to characters + for (let i = 0; i < combined.length; i += 2) { + const key = `${combined[i]},${combined[i+1]}`; + result += decryptMap.get(key); + } + + return result; +} + +// Decrypt using ADFGVX cipher +function decrypt(text, encryptMap, decryptMap) { + text = removeSpace(text, encryptMap); + + const coords = []; + + // Get coordinates for each character + for (const char of text) { + coords.push(encryptMap.get(char)); + } + + // Extract x and y values + const flatCoords = []; + for (const coord of coords) { + flatCoords.push(coord.x); + flatCoords.push(coord.y); + } + + const half = Math.floor(flatCoords.length / 2); + const firstHalf = flatCoords.slice(0, half); + const secondHalf = flatCoords.slice(half); + + let result = ''; + + // Recombine coordinates to get original text + for (let i = 0; i < firstHalf.length; i++) { + const key = `${firstHalf[i]},${secondHalf[i]}`; + result += decryptMap.get(key); + } + + return result; +} + +// Main function to test +function main() { + // Test with Rosetta square + let { encryptMap, decryptMap } = squareToMaps(squareRosetta); + + console.log("From Rosetta Code"); + console.log("original:\t", textRosetta); + let encoded = encrypt(textRosetta, encryptMap, decryptMap); + console.log("encoded:\t", encoded); + let decoded = decrypt(encoded, encryptMap, decryptMap); + console.log("and back:\t", decoded); + + // Test with Wikipedia square + ({ encryptMap, decryptMap } = squareToMaps(squareWikipedia)); + + console.log("\nFrom Wikipedia"); + console.log("original:\t", textWikipedia); + encoded = encrypt(textWikipedia, encryptMap, decryptMap); + console.log("encoded:\t", encoded); + decoded = decrypt(encoded, encryptMap, decryptMap); + console.log("and back:\t", decoded); + + // Test with longer text + console.log("\nFrom Rosetta Code (longer text)"); + console.log("original:\t", textTest); + encoded = encrypt(textTest, encryptMap, decryptMap); + console.log("encoded:\t", encoded); + // Note: If the text has an odd number of letters, the algorithm doesn't work! + decoded = decrypt(encoded, encryptMap, decryptMap); + console.log("and back:\t", decoded); +} + +// Run the main function +main(); diff --git a/Task/Bifid-cipher/Rust/bifid-cipher.rs b/Task/Bifid-cipher/Rust/bifid-cipher.rs new file mode 100644 index 0000000000..57868d8c09 --- /dev/null +++ b/Task/Bifid-cipher/Rust/bifid-cipher.rs @@ -0,0 +1,125 @@ +use std::collections::HashMap; + +type Point = (i32, i32); + + +struct Bifid { + grid: Vec>, + coordinates: HashMap, + n: i32, +} + +impl Bifid { + pub fn new(n: i32, text: &str) -> Result { + if (text.len() as i32) != n * n { + return Err("Incorrect length of text".to_string()); + } + + let mut grid = vec![vec!['\0'; n as usize]; n as usize]; + let mut coordinates: HashMap = HashMap::new(); + + let mut row: i32 = 0; + let mut col: i32 = 0; + + for ch in text.chars() { + grid[row as usize][col as usize] = ch; + coordinates.insert(ch, (row, col)); + + col += 1; + if col == n { + col = 0; + row += 1; + } + } + + if n == 5 { + if let Some(&i_coords) = coordinates.get(&'I') { + coordinates.insert('J', i_coords); + } + } + + Ok(Bifid { + grid, + coordinates, + n, + }) + } + + pub fn encrypt(&self, text: &str) -> String { + let mut row_one: Vec = Vec::new(); + let mut row_two: Vec = Vec::new(); + + for ch in text.chars() { + if let Some(coordinate) = self.coordinates.get(&ch) { + row_one.push(coordinate.0); + row_two.push(coordinate.1); + } + } + + row_one.extend(row_two.iter()); + let mut result = String::new(); + for i in (0..row_one.len() - 1).step_by(2) { + result.push(self.grid[row_one[i] as usize][row_one[i + 1] as usize]); + } + result + } + + pub fn decrypt(&self, text: &str) -> String { + let mut row: Vec = Vec::new(); + for ch in text.chars() { + if let Some(coordinate) = self.coordinates.get(&ch) { + row.push(coordinate.0); + row.push(coordinate.1); + } + } + + let middle = row.len() / 2; + let row_one: Vec = row[..middle].to_vec(); + let row_two: Vec = row[middle..].to_vec(); + + let mut result = String::new(); + for i in 0..middle { + result.push(self.grid[row_one[i] as usize][row_two[i] as usize]); + } + result + } + + pub fn display(&self) { + for row in &self.grid { + for ch in row { + print!("{} ", ch); + } + println!(); + } + } +} + +fn run_test(bifid: &Bifid, message: &str) { + println!("Using Polybius square:"); + bifid.display(); + println!("Message: {}", message); + let encrypted = bifid.encrypt(message); + println!("Encrypted: {}", encrypted); + let decrypted = bifid.decrypt(&encrypted); + println!("Decrypted: {}", decrypted); + println!(); +} + +fn main() -> Result<(), String> { + let message1 = "ATTACKATDAWN"; + let message2 = "FLEEATONCE"; + let message3 = "THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY"; + + let bifid1 = Bifid::new(5, "ABCDEFGHIKLMNOPQRSTUVWXYZ")?; + let bifid2 = Bifid::new(5, "BGWKZQPNDSIOAXEFCLUMTHYVR")?; + + run_test(&bifid1, message1); + run_test(&bifid2, message2); + run_test(&bifid2, message1); + run_test(&bifid1, message2); + + let bifid3 = Bifid::new(6, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")?; + run_test(&bifid3, message3); + + Ok(()) +} diff --git a/Task/Bin-given-limits/AppleScript/bin-given-limits.applescript b/Task/Bin-given-limits/AppleScript/bin-given-limits.applescript new file mode 100644 index 0000000000..9d4b93c9c4 --- /dev/null +++ b/Task/Bin-given-limits/AppleScript/bin-given-limits.applescript @@ -0,0 +1,42 @@ +property bins : {} + +local limits, theData, n, i, p, flag, output +set limits to {14, 18, 249, 312, 389, 392, 513, 591, 634, 720} +set theData to {445, 814, 519, 697, 700, 130, 255, 889, 481, 122, 932, 77, 323, 525, 570, 219, 367, 523, 442, 933, ¬ + 416, 589, 930, 373, 202, 253, 775, 47, 731, 685, 293, 126, 133, 450, 545, 100, 741, 583, 763, 306, ¬ + 655, 267, 248, 477, 549, 238, 62, 678, 98, 534, 622, 907, 406, 714, 184, 391, 913, 42, 560, 247, ¬ + 346, 860, 56, 138, 546, 38, 985, 948, 58, 213, 799, 319, 390, 634, 458, 945, 733, 507, 916, 123, ¬ + 345, 110, 720, 917, 313, 845, 426, 9, 457, 628, 410, 723, 354, 895, 881, 953, 677, 137, 397, 97, ¬ + 854, 740, 83, 216, 421, 94, 517, 479, 292, 963, 376, 981, 480, 39, 257, 272, 157, 5, 316, 395, ¬ + 787, 942, 456, 242, 759, 898, 576, 67, 298, 425, 894, 435, 831, 241, 989, 614, 987, 770, 384, 692, ¬ + 698, 765, 331, 487, 251, 600, 879, 342, 982, 527, 736, 795, 585, 40, 54, 901, 408, 359, 577, 237, ¬ + 605, 847, 353, 968, 832, 205, 838, 427, 876, 959, 686, 646, 835, 127, 621, 892, 443, 198, 988, 791, ¬ + 466, 23, 707, 467, 33, 670, 921, 180, 991, 396, 160, 436, 717, 918, 8, 374, 101, 684, 727, 749} + +repeat (count limits) + 1 times + set end of bins to 0 +end repeat + +repeat with n in theData + set flag to false + repeat with i from 1 to count limits + if n < item i of limits then + set flag to true + exit repeat + end if + end repeat + if flag then + set item i of bins to (item i of bins) + 1 + else + set item -1 of bins to (item -1 of bins) + 1 + end if +end repeat +set p to item 1 of limits +set output to "< " & p & " := " & (item 1 of bins) & linefeed +repeat with i from 2 to count limits + set n to item i of limits + set output to output & ">= " & p & " .. < " & n & " := " & (item i of bins) & linefeed + set p to n +end repeat +set output to output & ">= " & p & " := " & (item -1 of bins) +get output diff --git a/Task/Bin-given-limits/Crystal/bin-given-limits.cr b/Task/Bin-given-limits/Crystal/bin-given-limits.cr new file mode 100644 index 0000000000..84f3d18ad5 --- /dev/null +++ b/Task/Bin-given-limits/Crystal/bin-given-limits.cr @@ -0,0 +1,43 @@ +def bin (limits, seq) + bins = Array.new limits.size+1, 0 + seq.each do |v| + bins[limits.bsearch_index {|l, _| v < l } || -1] += 1 + end + bins +end + +def print_bins (limits, bins) + limit_width = limits.values_at(0, -1).map(&.to_s.size).max + tally_width = bins.max.to_s.size + bins.each_with_index do |n, i| + left = if i > 0; limits[i-1] end + right = if i < limits.size; limits[i] end + printf "%*s %s n %s %*s ⇒ %*s\n", + limit_width, left, left ? "≤" : " ", + right ? "<" : " ", limit_width, right, + tally_width, n + end +end + +limits = [23, 37, 43, 53, 67, 83] +data = [95,21,94,12,99,4,70,75,83,93,52,80,57,5,53,86,65,17,92,83,71,61,54,58,47, + 16, 8, 9,32,84,7,87,46,19,30,37,96,6,98,40,79,97,45,64,60,29,49,36,43,55] + +puts "P. 1" +print_bins(limits, bin(limits, data)) +puts + +limits = [14, 18, 249, 312, 389, 392, 513, 591, 634, 720] +data = [445,814,519,697,700,130,255,889,481,122,932, 77,323,525,570,219,367,523,442,933, + 416,589,930,373,202,253,775, 47,731,685,293,126,133,450,545,100,741,583,763,306, + 655,267,248,477,549,238, 62,678, 98,534,622,907,406,714,184,391,913, 42,560,247, + 346,860, 56,138,546, 38,985,948, 58,213,799,319,390,634,458,945,733,507,916,123, + 345,110,720,917,313,845,426, 9,457,628,410,723,354,895,881,953,677,137,397, 97, + 854,740, 83,216,421, 94,517,479,292,963,376,981,480, 39,257,272,157, 5,316,395, + 787,942,456,242,759,898,576, 67,298,425,894,435,831,241,989,614,987,770,384,692, + 698,765,331,487,251,600,879,342,982,527,736,795,585, 40, 54,901,408,359,577,237, + 605,847,353,968,832,205,838,427,876,959,686,646,835,127,621,892,443,198,988,791, + 466, 23,707,467, 33,670,921,180,991,396,160,436,717,918, 8,374,101,684,727,749] + +puts "P. 2" +print_bins(limits, bin(limits, data)) diff --git a/Task/Bin-given-limits/EasyLang/bin-given-limits.easy b/Task/Bin-given-limits/EasyLang/bin-given-limits.easy index 77d034ea2e..534a7c72d0 100644 --- a/Task/Bin-given-limits/EasyLang/bin-given-limits.easy +++ b/Task/Bin-given-limits/EasyLang/bin-given-limits.easy @@ -1,13 +1,10 @@ global limits[] data[] . # -proc count . . +proc count . len cnt[] len limits[] + 1 - # for e in data[] for i to len limits[] - if e < limits[i] - break 1 - . + if e < limits[i] : break 1 . cnt[i] += 1 . diff --git a/Task/Bin-given-limits/XPL0/bin-given-limits.xpl0 b/Task/Bin-given-limits/XPL0/bin-given-limits.xpl0 new file mode 100644 index 0000000000..ad0d939e9f --- /dev/null +++ b/Task/Bin-given-limits/XPL0/bin-given-limits.xpl0 @@ -0,0 +1,60 @@ +include xpllib; \for Print +int Bin(10+1); +def Marker = 0; + +proc PrintBins(Limits, Len); +int Limits, Len; +int I; +[Print(" < %3d:%3d\n", Limits(0), Bin(0)); +for I:= 1 to Len-1 do + Print(">= %3d and < %3d:%3d\n", Limits(I-1), Limits(I), Bin(I)); +Print(">= %3d :%3d\n", Limits(Len-1), Bin(Len)); +]; + +proc TallyBins(Limits, Len, Data); +int Limits, Len, Data; +int I, J, D; +[for I:= 0 to Len do + Bin(I):= 0; +I:= 0; +loop [D:= Data(I); + if D = Marker then quit; + I:= I+1; + for J:= 0 to Len-1 do \for each limit + if D < Limits(J) then + [Bin(J):= Bin(J)+1; + J:= Len; \exit for loop with J = Len+1 + ]; + if J = Len then \>= last limit + Bin(J):= Bin(J)+1; + ]; +]; + +int Limits, Data; +[Limits:= [23, 37, 43, 53, 67, 83]; +Data:= [95, 21, 94, 12, 99, 4, 70, 75, 83, 93, 52, 80, 57, + 5, 53, 86, 65, 17, 92, 83, 71, 61, 54, 58, 47, 16, + 8, 9, 32, 84, 7, 87, 46, 19, 30, 37, 96, 6, 98, + 40, 79, 97, 45, 64, 60, 29, 49, 36, 43, 55, Marker]; +TallyBins(Limits, 6, Data); +PrintBins(Limits, 6); +CrLf(0); +Limits:= [14, 18, 249, 312, 389, 392, 513, 591, 634, 720]; +Data:= [445, 814, 519, 697, 700, 130, 255, 889, 481, 122, 932, 77, 323, 525, + 570, 219, 367, 523, 442, 933, 416, 589, 930, 373, 202, 253, 775, 47, + 731, 685, 293, 126, 133, 450, 545, 100, 741, 583, 763, 306, 655, 267, + 248, 477, 549, 238, 62, 678, 98, 534, 622, 907, 406, 714, 184, 391, + 913, 42, 560, 247, 346, 860, 56, 138, 546, 38, 985, 948, 58, 213, + 799, 319, 390, 634, 458, 945, 733, 507, 916, 123, 345, 110, 720, 917, + 313, 845, 426, 9, 457, 628, 410, 723, 354, 895, 881, 953, 677, 137, + 397, 97, 854, 740, 83, 216, 421, 94, 517, 479, 292, 963, 376, 981, + 480, 39, 257, 272, 157, 5, 316, 395, 787, 942, 456, 242, 759, 898, + 576, 67, 298, 425, 894, 435, 831, 241, 989, 614, 987, 770, 384, 692, + 698, 765, 331, 487, 251, 600, 879, 342, 982, 527, 736, 795, 585, 40, + 54, 901, 408, 359, 577, 237, 605, 847, 353, 968, 832, 205, 838, 427, + 876, 959, 686, 646, 835, 127, 621, 892, 443, 198, 988, 791, 466, 23, + 707, 467, 33, 670, 921, 180, 991, 396, 160, 436, 717, 918, 8, 374, + 101, 684, 727, 749, Marker]; +TallyBins(Limits, 10, Data); +PrintBins(Limits, 10); +] diff --git a/Task/Binary-digits/C3/binary-digits.c3 b/Task/Binary-digits/C3/binary-digits.c3 new file mode 100644 index 0000000000..9b4073dfff --- /dev/null +++ b/Task/Binary-digits/C3/binary-digits.c3 @@ -0,0 +1,8 @@ +import std::io; +fn void main() +{ + io::printfn("%b", 0); + io::printfn("%b", 5); + io::printfn("%b", 50); + io::printfn("%b", 5000); +} diff --git a/Task/Binary-digits/EasyLang/binary-digits.easy b/Task/Binary-digits/EasyLang/binary-digits.easy index 471ba50912..222c41fe5e 100644 --- a/Task/Binary-digits/EasyLang/binary-digits.easy +++ b/Task/Binary-digits/EasyLang/binary-digits.easy @@ -1,10 +1,8 @@ func$ bin num . - while num > 1 - b$ = num mod 2 & b$ - num = num div 2 - . - return num & b$ + if num <= 1 : return num + return bin (num div 2) & num mod 2 . +print bin 0 print bin 5 print bin 50 print bin 9000 diff --git a/Task/Binary-search/EasyLang/binary-search.easy b/Task/Binary-search/EasyLang/binary-search.easy index c9318c5647..243fd82cfb 100644 --- a/Task/Binary-search/EasyLang/binary-search.easy +++ b/Task/Binary-search/EasyLang/binary-search.easy @@ -1,18 +1,17 @@ -proc binSearch val . a[] res . +func binSearch &a[] val . low = 1 high = len a[] - res = 0 - while low <= high and res = 0 + while low <= high mid = (low + high) div 2 if a[mid] > val high = mid - 1 elif a[mid] < val low = mid + 1 else - res = mid + return mid . . + return 0 . a[] = [ 2 4 6 8 9 ] -binSearch 8 a[] r -print r +print binSearch a[] 8 diff --git a/Task/Bioinformatics-Global-alignment/FreeBASIC/bioinformatics-global-alignment.basic b/Task/Bioinformatics-Global-alignment/FreeBASIC/bioinformatics-global-alignment.basic new file mode 100644 index 0000000000..5b43c15039 --- /dev/null +++ b/Task/Bioinformatics-Global-alignment/FreeBASIC/bioinformatics-global-alignment.basic @@ -0,0 +1,170 @@ +' Nucleotides +Dim Shared As Integer A, C, G, T, Total + +Sub PrintReport(text As String) + A = 0 : C = 0 : G = 0 : T = 0 + For i As Integer = 1 To Len(text) + Select Case Ucase(Mid(text, i, 1)) + Case "A": A += 1 + Case "C": C += 1 + Case "G": G += 1 + Case "T": T += 1 + End Select + Next + Total = Len(text) + + Print "Nucleotide counts for: "; Iif(Len(text) > 50, Chr(10), ""); + Print text + Print "Bases: A"; A; ", C:"; C; ", G:"; G; ", T:"; T; ", total:"; Total + Print +End Sub + +Function Concatenate(before As String, after As String) As String + For i As Integer = 1 To Len(before) + Dim As String suffix = Mid(before, i) + If Left(after, Len(suffix)) = suffix Then Return Left(before, i - 1) + after + Next + Return before + after +End Function + +' Remove duplicates and strings contained within a larger string from a list of strings +Sub Deduplicate(list() As String, result() As String) + Dim As Integer i, j + ' Remove duplicates + Dim As String unique(0 To Ubound(list)) + Dim As Integer uniqueCount = 0 + For i = 0 To Ubound(list) + Dim As Boolean exists = False + For j = 0 To uniqueCount - 1 + If list(i) = unique(j) Then exists = True : Exit For + Next + If Not exists Then + unique(uniqueCount) = list(i) + uniqueCount += 1 + End If + Next + + ' Remove substrings + Dim As String tempRes(0 To uniqueCount - 1) + Dim As Integer resCount = 0 + For i = 0 To uniqueCount - 1 + Dim As Boolean isSubstring = False + For j = 0 To uniqueCount - 1 + If i <> j And Instr(unique(j), unique(i)) > 0 Then + isSubstring = True + Exit For + End If + Next + If Not isSubstring Then + tempRes(resCount) = unique(i) + resCount += 1 + End If + Next + + Redim result(0 To resCount - 1) + For i = 0 To resCount - 1 + result(i) = tempRes(i) + Next +End Sub + +' Gets all permutations of a list of strings +Sub ProcessPermutation(perm() As String, result() As String, Byref minLength As Integer) + Dim As String candidate = perm(0) + For i As Integer = 1 To Ubound(perm) + candidate = Concatenate(candidate, perm(i)) + Next + + If Len(candidate) < minLength Then + Erase result + Redim result(0) + result(0) = candidate + minLength = Len(candidate) + Elseif Len(candidate) = minLength Then + Dim As Boolean exists = False + For s As Integer = 0 To Ubound(result) + If result(s) = candidate Then exists = True : Exit For + Next + If Not exists Then + Redim Preserve result(0 To Ubound(result) + 1) + result(Ubound(result)) = candidate + End If + End If +End Sub + +' Returns shortest common superstring of a list of strings +Sub ShortestCommonSuperstrings(list() As String, result() As String) + Dim As String deduplicated() + Deduplicate(list(), deduplicated()) + If Ubound(deduplicated) < 0 Then Exit Sub + + Dim As Integer i, j, minLength = 0 + For i = 0 To Ubound(list) + minLength += Len(list(i)) + Next + + Dim As Integer n = Ubound(deduplicated) + 1 + Dim As Integer indexes(n - 1) + Dim As String currentPerm(n - 1) + + For i = 0 To n - 1 + indexes(i) = 0 + currentPerm(i) = deduplicated(i) + Next + + ProcessPermutation(currentPerm(), result(), minLength) + + i = 0 + While i < n + If indexes(i) < i Then + j = Iif(i Mod 2 = 0, 0, indexes(i)) + Swap currentPerm(j), currentPerm(i) + + ProcessPermutation(currentPerm(), result(), minLength) + + indexes(i) += 1 + i = 0 + Else + indexes(i) = 0 + i += 1 + End If + Wend +End Sub + +' Test cases +Dim As String test_sequences(0 To 3, 0 To 12) = { _ +{"TA", "AAG", "TA", "GAA", "TA", "", "", "", "", "", "", "", ""}, _ +{"CATTAGGG", "ATTAG", "GGG", "TA", "", "", "", "", "", "", "", "", ""}, _ +{"AAGAUGGA", "GGAGCGCAUC", "AUCGCAAUAAGGA", "", "", "", "", "", "", "", "", "", ""}, _ +{ "ATGAAATGGATGTTCTGAGTTGGTCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTAT", _ +"GGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATCGAACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGT", _ +"CTATGTTCTTATGAAATGGATGTTCTGAGTTGGTCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTATA", _ +"TGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATC", _ +"AACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTT", _ +"GCGCATCGAACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTC", _ +"CGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTTCGATTCTGCTTATAACACTATGTTCT", _ +"TGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATC", _ +"CGTAAAAAATTACAACGTCCTTTGGCTATCTCTTAAACTCCTGCTAAATGCTCGTGC", _ +"GATGGAGCGCATCGAACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTTCGATT", _ +"TTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATC", _ +"CTATGTTCTTATGAAATGGATGTTCTGAGTTGGTCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTATA", _ +"TCTCTTAAACTCCTGCTAAATGCTCGTGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGA" } _ +} + +For i As Integer = 0 To 3 + Dim As String test_case() + For j As Integer = 0 To 12 + If Len(test_sequences(i, j)) > 0 Then + Redim Preserve test_case(Ubound(test_case) + 1) + test_case(Ubound(test_case)) = test_sequences(i, j) + End If + Next + + Dim As String superstrings() + ShortestCommonSuperstrings(test_case(), superstrings()) + + For s As Integer = 0 To Ubound(superstrings) + PrintReport(superstrings(s)) + Next +Next + +Sleep diff --git a/Task/Bioinformatics-Global-alignment/Rust/bioinformatics-global-alignment.rs b/Task/Bioinformatics-Global-alignment/Rust/bioinformatics-global-alignment.rs new file mode 100644 index 0000000000..a33f50c14a --- /dev/null +++ b/Task/Bioinformatics-Global-alignment/Rust/bioinformatics-global-alignment.rs @@ -0,0 +1,132 @@ +use std::collections::{HashMap, HashSet}; + +// Print a report of the given string to the standard output device. +fn print_report(text: &str) { + let mut bases: HashMap = HashMap::new(); + for ch in text.chars() { + *bases.entry(ch).or_insert(0) += 1; + } + + let total: i32 = bases.values().sum(); + + println!("Nucleotide counts for: {}", if text.len() > 50 { "\n" } else { "" }); + println!("{}", text); + println!("Bases: A {}, C: {}, G: {}, T: {}, total: {}\n", + bases.get(&'A').unwrap_or(&0), + bases.get(&'C').unwrap_or(&0), + bases.get(&'G').unwrap_or(&0), + bases.get(&'T').unwrap_or(&0), + total); +} + +// Return all permutations of the given list of strings. +fn permutations(list: &mut Vec) -> Vec> { + let mut indexes: Vec = vec![0; list.len()]; + let mut result: Vec> = Vec::new(); + result.push(list.clone()); + let mut i = 0; + while i < list.len() { + if indexes[i] < i as i32 { + let j = if i % 2 == 0 { 0 } else { indexes[i] as usize }; + list.swap(i, j); + result.push(list.clone()); + indexes[i] += 1; + i = 0; + } else { + indexes[i] = 0; + i += 1; + } + } + result +} + +// Return 'before' concatenated with 'after', removing the longest suffix of 'before' that matches a prefix of 'after'. +fn concatenate(before: &str, after: &str) -> String { + for i in 0..before.len() { + let suffix = &before[i..]; + if after.starts_with(suffix) { + return format!("{}{}", &before[0..i], after); + } + } + format!("{}{}", before, after) +} + +// Remove duplicate strings and strings which are substrings of other strings in the given list. +fn deduplicate(list: &[String]) -> Vec { + let mut singletons = list.to_vec(); + singletons.sort(); + singletons.dedup(); + + let result = singletons.clone(); + let mut marked_for_removal: HashSet = HashSet::new(); + + for test_word in &result { + for word in &singletons { + if word != test_word && word.contains(test_word) { + marked_for_removal.insert(test_word.clone()); + } + } + } + + result.into_iter().filter(|word| !marked_for_removal.contains(word)).collect() +} + +// Return a set containing all of the shortest common superstrings of the given list of strings. +fn shortest_common_superstrings(list: &[String]) -> HashSet { + let deduplicated = deduplicate(list); + let mut deduplicated_mut = deduplicated.clone(); + + let mut shortest: HashSet = HashSet::new(); + let mut joined = String::new(); + for word in list { + joined.push_str(word); + } + shortest.insert(joined); + + let mut shortest_length = list.iter().map(|s| s.len()).sum(); + + for permutation in permutations(&mut deduplicated_mut) { + let mut candidate = String::new(); + for word in permutation { + candidate = concatenate(&candidate, &word); + } + + if candidate.len() < shortest_length { + shortest.clear(); + shortest_length = candidate.len(); + shortest.insert(candidate); + } else if candidate.len() == shortest_length { + shortest.insert(candidate); + } + } + shortest +} + +fn main() { + let test_sequences: Vec> = vec![ + vec!["TA".to_string(), "AAG".to_string(), "TA".to_string(), "GAA".to_string(), "TA".to_string()], + vec!["CATTAGGG".to_string(), "ATTAG".to_string(), "GGG".to_string(), "TA".to_string()], + vec!["AAGAUGGA".to_string(), "GGAGCGCAUC".to_string(), "AUCGCAAUAAGGA".to_string()], + vec![ + "ATGAAATGGATGTTCTGAGTTGGTCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTAT".to_string(), + "GGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATCGAACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGT".to_string(), + "CTATGTTCTTATGAAATGGATGTTCTGAGTTGGTCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTATA".to_string(), + "TGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATC".to_string(), + "AACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTT".to_string(), + "GCGCATCGAACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTC".to_string(), + "CGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTTCGATTCTGCTTATAACACTATGTTCT".to_string(), + "TGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATC".to_string(), + "CGTAAAAAATTACAACGTCCTTTGGCTATCTCTTAAACTCCTGCTAAATGCTCGTGC".to_string(), + "GATGGAGCGCATCGAACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTTCGATT".to_string(), + "TTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATC".to_string(), + "CTATGTTCTTATGAAATGGATGTTCTGAGTTGGTCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTATA".to_string(), + "TCTCTTAAACTCCTGCTAAATGCTCGTGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGA".to_string(), + ], + ]; + + for test in test_sequences { + for superstring in shortest_common_superstrings(&test) { + print_report(&superstring); + } + } +} diff --git a/Task/Bioinformatics-Sequence-mutation/EasyLang/bioinformatics-sequence-mutation.easy b/Task/Bioinformatics-Sequence-mutation/EasyLang/bioinformatics-sequence-mutation.easy index a2743b199b..5ff9a347ef 100644 --- a/Task/Bioinformatics-Sequence-mutation/EasyLang/bioinformatics-sequence-mutation.easy +++ b/Task/Bioinformatics-Sequence-mutation/EasyLang/bioinformatics-sequence-mutation.easy @@ -1,21 +1,15 @@ base$[] = [ "A" "C" "T" "G" ] global seq[] seqnx[] seqpr[] . -proc prseq . . +proc prseq . len cnt[] 4 - numfmt 0 3 + numfmt 3 0 ind = 1 while seqnx[ind] <> 1 pos += 1 ind = seqnx[ind] - if pos mod 40 = 1 - print "" - . - if pos mod 40 = 1 - write pos & ":" - . - if pos mod 4 = 1 - write " " - . + if pos mod 40 = 1 : print "" + if pos mod 40 = 1 : write pos & ":" + if pos mod 4 = 1 : write " " cnt[seq[ind]] += 1 write base$[seq[ind]] . @@ -29,7 +23,7 @@ proc prseq . . print " " & sum print "" . -proc init . . +proc init . seq[] = [ 0 ] seqnx[] = [ 2 ] seqpr[] = [ 0 ] @@ -41,7 +35,7 @@ proc init . . seqpr[1] = len seq[] seqnx[$] = 1 . -proc delete pos . . +proc delete pos . nx = seqnx[pos] pre = seqpr[pos] seqnx[pre] = nx @@ -56,7 +50,7 @@ proc delete pos . . len seqnx[] -1 len seqpr[] -1 . -proc insert pos . . +proc insert pos . seq[] &= random 4 last = len seq[] seqnx[] &= pos @@ -64,7 +58,7 @@ proc insert pos . . seqnx[seqpr[pos]] = last seqpr[pos] = last . -proc mutate . . +proc mutate . op = random 3 pos = random (len seq[] - 1) + 1 if op = 1 @@ -78,8 +72,6 @@ proc mutate . . init print "Original:" prseq -for i to 10 - mutate -. +for i to 10 : mutate print "Mutated:" prseq diff --git a/Task/Bioinformatics-base-count/EasyLang/bioinformatics-base-count.easy b/Task/Bioinformatics-base-count/EasyLang/bioinformatics-base-count.easy index d7c2cc2230..8e535a0e24 100644 --- a/Task/Bioinformatics-base-count/EasyLang/bioinformatics-base-count.easy +++ b/Task/Bioinformatics-base-count/EasyLang/bioinformatics-base-count.easy @@ -1,20 +1,14 @@ len d[] 26 pos = 1 -numfmt 0 4 +numfmt 4 0 repeat s$ = input until s$ = "" for c$ in strchars s$ - if pos mod 40 = 1 - write pos & ":" - . - if pos mod 4 = 1 - write " " - . + if pos mod 40 = 1 : write pos & ":" + if pos mod 4 = 1 : write " " write c$ - if pos mod 40 = 0 - print "" - . + if pos mod 40 = 0 : print "" pos += 1 c = strcode c$ d[c - 64] += 1 diff --git a/Task/Bioinformatics-base-count/Uxntal/bioinformatics-base-count.uxnatl b/Task/Bioinformatics-base-count/Uxntal/bioinformatics-base-count.uxnatl new file mode 100644 index 0000000000..c40f9b70d9 --- /dev/null +++ b/Task/Bioinformatics-base-count/Uxntal/bioinformatics-base-count.uxnatl @@ -0,0 +1,80 @@ +%\n { 0a } %\s { 20 } %\0 { 00 } +%newline { [ LIT2 \n -Console/write ] DEO } + +|18 @Console/write + +|100 + +;data base-count + +BRK + +@base-count ( data* -- ) + LDAk + DUP #0a NEQ ?{ !/next } + DUP [ LIT "A ] NEQ ?{ + [ LIT2 &adenine $2 ] INC2 ,/adenine STR2 !/resume } + DUP [ LIT "C ] NEQ ?{ + [ LIT2 &cytosine $2 ] INC2 ,/cytosine STR2 !/resume } + DUP [ LIT "G ] NEQ ?{ + [ LIT2 &guanine $2 ] INC2 ,/guanine STR2 !/resume } + DUP [ LIT "T ] NEQ ?{ + [ LIT2 &thymine $2 ] INC2 ,/thymine STR2 } + + &resume + [ LIT2 &total $2 ] INC2 ,/total STR2 + + &next + POP + INC2 LDAk ?base-count + + POP2 + + ;msgs/sequence print/str + ;data print/str + ;msgs/header print/str + ;msgs/adenine print/str ,/adenine LDR2 print/dec newline + ;msgs/cytosine print/str ,/cytosine LDR2 print/dec newline + ;msgs/guanine print/str ,/guanine LDR2 print/dec newline + ;msgs/thymine print/str ,/thymine LDR2 print/dec newline + ;msgs/total print/str ,/total LDR2 print/dec newline + + JMP2r + +@print/str ( str* -- ) + LDAk .Console/write DEO + INC2 LDAk ?/str + POP2 JMP2r + +@print/dec ( short* -- ) + #000a SWP2 [ LITr ff ] + + &dec/get + SWP2k DIV2k MUL2 SUB2 STH + POP OVR2 DIV2 ORAk ?/dec/get + POP2 POP2 + + &dec/put + STHr INCk ?{ POP JMP2r } + [ LIT "0 ] ADD .Console/write DEO !/dec/put + +@data [ + "CGTAAAAAATTACAACGTCCTTTGG "CTATCTCTTAAACTCCTGCTAAATG \n + "CTCGTGCTTTCCAATTATGTAAGCG "TTCCGAGACGGGGTGGTCGATTCTG \n + "AGGACAAAGGTCAAGATGGAGCGCA "TCGAACGCAATAAGGATCATTTGAT \n + "GGGACGTTTCGTCGACAAAGTCTTG "TTTCGAGAGTAACGGCTACCGTCTT \n + "CGATTCTGCTTATAACACTATGTTC "TTATGAAATGGATGTTCTGAGTTGG \n + "TCAGTCCCAATGTGCGGGGTTTCTT "TTAGTACGTCGGGAGTGGTATTATA \n + "TTTAATTTTTCTATATAGCGATCTG "TATTTAAGCAATTCATTTAGGTTAT \n + "CGCCGCGATGCTCGGTTCGGACCGC "CAAGCATCTGGCTCCACTGCTAGTG \n + "TCCTAAATTTGAATGGCAAACACAA "ATAAGATTTAGCAATTCGTGTAGAC \n + "GACCGGGGACTTGCATGATGGGAGC "AGCTTTGTTAAACTACGAACGTAAT \n \0 ] + +@msgs [ + &header \n "BASE \s "COUNT: \n \0 + &sequence "SEQUENCE: \n \0 + &adenine \s \s \s "Adenine: \s \0 + &cytosine \s \s "Cytosine: \s \0 + &guanine \s \s \s "Guanine: \s \0 + &thymine \s \s \s "Thymine: \s \0 + &total \s \s \s \s \s "Total: \s \0 ] diff --git a/Task/Biorhythms/EasyLang/biorhythms.easy b/Task/Biorhythms/EasyLang/biorhythms.easy index ebb822d591..8f9bf9a6c9 100644 --- a/Task/Biorhythms/EasyLang/biorhythms.easy +++ b/Task/Biorhythms/EasyLang/biorhythms.easy @@ -8,35 +8,29 @@ func day d$ . d = number substr d$ 9 2 return 367 * y - 7 * (y + (m + 9) div 12) div 4 + 275 * m div 9 + d - 730530 . -textsize 4 +gtextsize 4 func init b$ d$ . - linewidth 0.2 - move 50 0 - line 50 100 - move 0 50 - line 100 50 + glinewidth 0.2 + gline 50 0 50 100 + gline 0 50 100 50 for d = -20 to 20 - move x 50 - circle 0.5 + gcircle x 50 0.5 x += 2.5 . - move 4 94 - text b$ - move 4 88 - text d$ + gtext 4 94 b$ + gtext 4 88 d$ days = day date$ - day birth$ - move 4 80 - text days & " days" + gtext 4 80 days & " days" return days . -proc cycle now cyc t$ col . . - color col - move 4 cyc * 1.2 - 20 - text t$ - linewidth 0.5 +proc cycle now cyc t$ col . + gcolor col + gtext 4 cyc * 1.2 - 20 t$ + glinewidth 0.5 for d = now - 20 to now + 20 - p = 20 * sin (360 * d / cyc) - line x 50 + p + yp = y + y = 50 + 20 * sin (360 * d / cyc) + if x > 0 : gline (x - 2.5) yp x y x += 2.5 . . diff --git a/Task/Bitcoin-address-validation/JavaScript/bitcoin-address-validation.js b/Task/Bitcoin-address-validation/JavaScript/bitcoin-address-validation.js new file mode 100644 index 0000000000..c53ff79496 --- /dev/null +++ b/Task/Bitcoin-address-validation/JavaScript/bitcoin-address-validation.js @@ -0,0 +1,53 @@ +const digits58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; + +async function hash(bytes) { + return new Uint8Array(await crypto.subtle.digest('SHA-256', bytes)); +} + +function toBytes(n, length) { + const bytes = []; + + for (let i = BigInt(length)-1n; i >= 0; i--) { + bytes.push((n >> i * 8n) & 0xffn); + } + + return bytes; +} + +function decode_base58(bc, length) { + let n = 0n; + for (const char of bc) { + n = n * 58n + BigInt(digits58.indexOf(char)); + } + + return toBytes(n, length); +} + +function toUint8Array(bytes) { + let nums = [] + + for (const byte of bytes) { + nums.push(Number(byte)); + } + + return new Uint8Array(nums); +} + +async function checkBc(bc) { + const bcbytes = decode_base58(bc, 25); + + const slice = bcbytes.slice(0, bcbytes.length-4); + const first = toUint8Array(slice); + + const firstHash = await hash(first); + const secondHash = await hash(firstHash); + + const checksum = toUint8Array(bcbytes.slice(-4)); + + return JSON.stringify(checksum) == JSON.stringify(toUint8Array(secondHash.slice(0, 4))); +} + +(async () => { + console.log(await checkBc('1AGNa15ZQXAZUgFiqJ3i7Z2DPU2J6hW62i')); + console.log(await checkBc("17NdbrSGoUotzeGCcMMCqnFkEvLymoou9j")) +})(); diff --git a/Task/Bitmap-B-zier-curves-Quadratic/EasyLang/bitmap-b-zier-curves-quadratic.easy b/Task/Bitmap-B-zier-curves-Quadratic/EasyLang/bitmap-b-zier-curves-quadratic.easy index 2edb8d1510..3aaf5eda4f 100644 --- a/Task/Bitmap-B-zier-curves-Quadratic/EasyLang/bitmap-b-zier-curves-quadratic.easy +++ b/Task/Bitmap-B-zier-curves-Quadratic/EasyLang/bitmap-b-zier-curves-quadratic.easy @@ -1,19 +1,18 @@ -proc quadraticbezier x1 y1 x2 y2 x3 y3 nseg . . +sysconf topleft +proc quadraticbezier x1 y1 x2 y2 x3 y3 nseg . for i = 0 to nseg t = i / nseg t1 = 1 - t a = t1 * t1 b = 2 * t * t1 c = t * t - currx = a * x1 + b * x2 + c * x3 + 0.5 - curry = a * y1 + b * y2 + c * y3 + 0.5 - if i = 0 - move currx curry - else - line currx curry - . + px = x + py = y + x = a * x1 + b * x2 + c * x3 + 0.5 + y = a * y1 + b * y2 + c * y3 + 0.5 + if i > 0 : gline px py x y . . -linewidth 0.5 -clear +glinewidth 0.5 +gclear quadraticbezier 1 1 30 37 59 1 100 diff --git a/Task/Bitmap-Bresenhams-line-algorithm/EasyLang/bitmap-bresenhams-line-algorithm.easy b/Task/Bitmap-Bresenhams-line-algorithm/EasyLang/bitmap-bresenhams-line-algorithm.easy index 536d330933..b0a250c7ec 100644 --- a/Task/Bitmap-Bresenhams-line-algorithm/EasyLang/bitmap-bresenhams-line-algorithm.easy +++ b/Task/Bitmap-Bresenhams-line-algorithm/EasyLang/bitmap-bresenhams-line-algorithm.easy @@ -1,8 +1,7 @@ -proc pset x y . . - move x / 4 y / 4 - rect 0.25 0.25 +proc pset x y . + grect x / 4 y / 4 0.25 0.25 . -proc drawline x0 y0 x1 y1 . . +proc drawline x0 y0 x1 y1 . dx = abs (x1 - x0) sx = -1 if x0 < x1 diff --git a/Task/Bitwise-operations/Uxntal/bitwise-operations.uxnatl b/Task/Bitwise-operations/Uxntal/bitwise-operations.uxnatl index 9e4335844f..695abf3123 100644 --- a/Task/Bitwise-operations/Uxntal/bitwise-operations.uxnatl +++ b/Task/Bitwise-operations/Uxntal/bitwise-operations.uxnatl @@ -1,67 +1,73 @@ -|00 @System [ &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1 ] -|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ] +%\n { 0a } %\s { 20 } %\0 { 00 } +%newline { [ LIT2 \n -Console/write ] DEO } + +%not { #ff EOR } +%and { AND } +%or { ORA } +%xor { EOR } +%shl { #40 SFT SFT } +%shr { SFT } +%rol { #40 SFT #00 ROT ROT SFT2 ORA } +%ror { SWP #00 ROT SFT2 ORA } + +|18 @Console/write + +|100 + +#0a02 +DUP2 SWP ;msgs/a print/arg ;msgs/b print/arg +bitwise -( program ) -|0100 @on-reset ( -> ) - #0a02 - DUP2 SWP ;Labels/a ;Labels/b - bitwise - halt BRK @bitwise ( a b -- ) - ;Labels/not ;Labels/a ;Labels/equ DUP2 [ POP #ff EOR ] - ;Labels/and DUP2 [ AND ] - ;Labels/or DUP2 [ ORA ] - ;Labels/xor DUP2 [ EOR ] - ;Labels/shl DUP2 [ #40 SFT SFT ] - ;Labels/shr DUP2 [ SFT ] - ;Labels/rol DUP2 [ #40 SFT #00 ROT ROT SFT2 ORA ] - ;Labels/ror [ SWP #00 ROT SFT2 ORA ] - JMP2r + ;msgs/not print/str ;msgs/a print/str + ;msgs/equ print/str OVR not print/result + ;msgs/and print/label DUP2 and print/result + ;msgs/or print/label DUP2 or print/result + ;msgs/xor print/label DUP2 xor print/result + ;msgs/shl print/label DUP2 shl print/result + ;msgs/shr print/label DUP2 shr print/result + ;msgs/rol print/label DUP2 rol print/result + ;msgs/ror print/label ror !print/result -@halt ( -- ) - #01 .System/halt DEO - BRK +@print/label ( label* -- ) + ;msgs/a /str + /str + ;msgs/b /str + ;msgs/equ !/str -@ ( a name* -- ) - ;Labels/equ - JMP2r - -@ ( a -- ) - ;Labels/newline - JMP2r - -@ ( label* -- ) - ;Labels/a - - ;Labels/b - ;Labels/equ - JMP2r - -@ ( byte -- ) +@print/byte ( byte -- ) [ LIT "$ ] .Console/write DEO - DUP #04 SFT /l - &l ( -- ) - #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD .Console/write DEO - JMP2r + DUP #04 SFT /nibble + ( >> ) + +@print/nibble ( -- ) + #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD .Console/write DEO + JMP2r -@ ( str* -- ) - &while ( -- ) - LDAk .Console/write DEO - INC2 LDAk ?&while +@print/arg ( a name* -- ) + /str ;msgs/equ /str + ( >> ) + +@print/result ( a -- ) + /byte newline + JMP2r + +@print/str ( str* -- ) + LDAk .Console/write DEO + INC2 LDAk ?/str POP2 JMP2r -@Labels - &a "a 20 $1 - &b "b 20 $1 - &equ "= 20 $1 - &newline 0a $1 - ¬ "NOT 20 $1 - &and "AND 20 $1 - &or "OR 20 $1 - &xor "XOR 20 $1 - &shl "SHL 20 $1 - &shr "SHR 20 $1 - &rol "ROL 20 $1 - &ror "ROR 20 $1 +@msgs [ + &a "a \s \0 + &b "b \s \0 + &equ "= \s \0 + ¬ "NOT \s \0 + &and "AND \s \0 + &or "OR \s \0 + &xor "XOR \s \0 + &shl "SHL \s \0 + &shr "SHR \s \0 + &rol "ROL \s \0 + &ror "ROR \s \0 ] diff --git a/Task/Blum-integer/EasyLang/blum-integer.easy b/Task/Blum-integer/EasyLang/blum-integer.easy index 7b73286f92..603f83fb51 100644 --- a/Task/Blum-integer/EasyLang/blum-integer.easy +++ b/Task/Blum-integer/EasyLang/blum-integer.easy @@ -2,32 +2,27 @@ fastfunc semiprim n . d = 3 while d * d <= n while n mod d = 0 - if c = 2 - return 0 - . + if c = 2 : return 0 n /= d c += 1 . d += 2 . - if c = 1 - return n - . + if c = 1 : return n + return 0 . print "The first 50 Blum integers:" n = 3 -numfmt 0 4 +numfmt 4 0 repeat prim1 = semiprim n - if prim1 <> 0 - if prim1 mod 4 = 3 - prim2 = n div prim1 - if prim2 <> prim1 and prim2 mod 4 = 3 - c += 1 - if c <= 50 - write n - if c mod 10 = 0 ; print "" ; . - . + if prim1 <> 0 and prim1 mod 4 = 3 + prim2 = n div prim1 + if prim2 <> prim1 and prim2 mod 4 = 3 + c += 1 + if c <= 50 + write n + if c mod 10 = 0 : print "" . . . diff --git a/Task/Blum-integer/Rust/blum-integer.rs b/Task/Blum-integer/Rust/blum-integer.rs new file mode 100644 index 0000000000..59feb1041f --- /dev/null +++ b/Task/Blum-integer/Rust/blum-integer.rs @@ -0,0 +1,91 @@ +fn is_prime_mod4(n: u32) -> bool { + match n { + 0..3 => false, + _ if n % 2 == 0 => false, + _ if n % 3 == 0 => n == 3, + _ if n % 4 == 3 => { + for d in (5..).step_by(2).take_while(|&d| d * d <= n) { + if n % d == 0 { + return false; + } + } + + true + } + _ => false, + } +} + +fn least_prime_factor(n: u32) -> u32 { + match n { + 1 => 1, + _ if n % 3 == 0 => 3, + _ if n % 5 == 0 => 5, + _ => { + for d in (7..).step_by(2).take_while(|&d| d * d <= n) { + if n % d == 0 { + return d; + } + } + + n + } + } +} + +fn blums() -> Blum { + Blum { number: 1 } +} + +struct Blum { + number: u32, +} + +impl Iterator for Blum { + type Item = u32; + + fn next(&mut self) -> Option { + loop { + let number = self.number; + let p = least_prime_factor(number); + + self.number = number.checked_add(if number % 5 == 3 { 4 } else { 2 })?; + + if p % 4 == 3 { + let q = number / p; + + if p != q && is_prime_mod4(q) { + return Some(number); + } + } + } + } +} + +fn main() { + println!("First 50 Blum integers:"); + + let last_digit_counts = blums() + .zip(1..=400_000) + .inspect(|&(blum, i)| match i { + 1..=50 => print!("{blum:>3}{}", if i % 10 != 0 { " " } else { "\n" }), + 51 => println!(), + 26_828 | 100_000 | 200_000 | 300_000 | 400_000 => { + println!("The {i:>6}th Blum integer is: {blum:>7}"); + } + _ => {} + }) + .fold([0; 10], |mut acc, (blum, _)| { + acc[blum as usize % 10] += 1; + + acc + }); + + println!("\nPercent distribution of the first 400000 Blum integers:"); + for i in [1, 3, 7, 9] { + println!( + "\t{:2.3}% end in {i}", + last_digit_counts[i] as f64 / 4_000.0 + ); + } +} diff --git a/Task/Boolean-values/Ballerina/boolean-values.ballerina b/Task/Boolean-values/Ballerina/boolean-values.ballerina new file mode 100644 index 0000000000..637f05cfc0 --- /dev/null +++ b/Task/Boolean-values/Ballerina/boolean-values.ballerina @@ -0,0 +1,12 @@ +import ballerina/io; + +public function main() { + boolean markova = true; + boolean keys = false; + if markova { + io:println("Alicia Markova was a famous ballerina."); + } + if !keys { + io:println("Alicia Keys is a famous singer."); + } +} diff --git a/Task/Box-the-compass/EasyLang/box-the-compass.easy b/Task/Box-the-compass/EasyLang/box-the-compass.easy index 03c6aa33d7..0bb02b538d 100644 --- a/Task/Box-the-compass/EasyLang/box-the-compass.easy +++ b/Task/Box-the-compass/EasyLang/box-the-compass.easy @@ -17,7 +17,7 @@ func$ expand cp$ . h$ = strchar (strcode substr r$ 1 1 - 32) return h$ & substr r$ 2 999 . -proc main . . +proc main . cp$[] = [ "N" "NbE" "N-NE" "NEbN" "NE" "NEbE" "E-NE" "EbN" "E" "EbS" "E-SE" "SEbE" "SE" "SEbS" "S-SE" "SbE" "S" "SbW" "S-SW" "SWbS" "SW" "SWbW" "W-SW" "WbS" "W" "WbN" "W-NW" "NWbW" "NW" "NWbN" "N-NW" "NbW" ] print "Index Degrees Compass point" print "----- ------- -------------" diff --git a/Task/Box-the-compass/Standard-ML/box-the-compass.ml b/Task/Box-the-compass/Standard-ML/box-the-compass.ml new file mode 100644 index 0000000000..a523bcd20a --- /dev/null +++ b/Task/Box-the-compass/Standard-ML/box-the-compass.ml @@ -0,0 +1,29 @@ +local + val box = Array.fromList [ + "North", "North by east", "North-northeast", "Northeast by north", + "Northeast", "Northeast by east", "East-northeast", "East by north", + "East", "East by south", "East-southeast", "Southeast by east", + "Southeast", "Southeast by south", "South-southeast", "South by east", + "South", "South by west", "South-southwest", "Southwest by south", + "Southwest", "Southwest by west", "West-southwest", "West by south", + "West", "West by north", "West-northwest", "Northwest by west", + "Northwest", "Northwest by north", "North-northwest", "North by west"] + + val phis = Array.fromList [ + 0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, + 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, + 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, + 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38 + ] +in +val _ = Array.app (fn phi => + let val i = Real.trunc ((phi * 32.0) / 360.0 + 0.5) mod 32 + in print (StringCvt.padLeft #" " 3 (Int.toString (i+1)) + ^ " " + ^ StringCvt.padLeft #" " 18 (Array.sub (box, i)) + ^ " " + ^ Real.fmt (StringCvt.FIX (SOME 2)) phi + ^ "\n") + end) + phis +end diff --git a/Task/Boyer-Moore-string-search/C-sharp/boyer-moore-string-search.cs b/Task/Boyer-Moore-string-search/C-sharp/boyer-moore-string-search.cs new file mode 100644 index 0000000000..6064d3eccb --- /dev/null +++ b/Task/Boyer-Moore-string-search/C-sharp/boyer-moore-string-search.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +/// +/// An implementation of the Boyer-Moore string search algorithm. +/// It finds all occurrences of a pattern in a text, performing a case-insensitive search on ASCII characters. +/// +/// For all full description of the algorithm visit: +/// https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm +/// +public static class BoyerMooreStringSearch +{ + public static void Main(string[] args) + { + List texts = new List + { + "GCTAGCTCTACGAGTCTA", + "GGCTATAATGCGTA", + "there would have been a time for such a word", + "needle need noodle needle", + "DKnuthusesandshowsanimaginarycomputertheMIXanditsassociatedmachinecodeandassemblylanguagestoillustrate", + "Farms grew an acre of alfalfa on the dairy's behalf, with bales of that alfalfa exchanged for milk." + }; + + List patterns = new List { "TCTA", "TAATAAA", "word", "needle", "put", "and", "alfalfa" }; + + for (int i = 0; i < texts.Count; i++) + { + Console.WriteLine("text" + (i + 1) + " = " + texts[i]); + } + Console.WriteLine(); + + for (int i = 0; i < patterns.Count; i++) + { + int j = (i < 5) ? i : i - 1; + Console.WriteLine("Found \"" + patterns[i] + "\" in 'text" + (j + 1) + "' at indexes " + + string.Join(", ", StringSearch(texts[j], patterns[i]))); + } + } + + /// + /// Return a list of indexes at which the given pattern matches the given text. + /// + private static List StringSearch(string aText, string aPattern) + { + if (string.IsNullOrEmpty(aPattern) || string.IsNullOrEmpty(aText) || aText.Length < aPattern.Length) + { + return new List(); + } + + List matches = new List(); + + // Preprocessing + List> R = BadCharacterTable(aPattern); + int[] L = GoodSuffixTable(aPattern); + int[] F = FullShiftTable(aPattern); + + int k = aPattern.Length - 1; // Represents the alignment of the end of aPattern relative to aText + int previousK = -1; // Represents the above alignment in the previous phase + while (k < aText.Length) + { + int i = aPattern.Length - 1; // Index of the character to compare in aPattern + int h = k; // Index of the character to compare in aText + while (i >= 0 && h > previousK && aPattern[i] == aText[h]) + { + i -= 1; + h -= 1; + } + if (i == -1 || h == previousK) + { // Match has been found + matches.Add(k - aPattern.Length + 1); + k += (aPattern.Length > 1) ? aPattern.Length - F[1] : 1; + } + else + { // No match, shift by the maximum of the bad character and good suffix rules + int suffixShift; + int charShift = i - R[AlphabetIndex(aText[h])][i]; + if (i + 1 == aPattern.Length) + { // Mismatch occurred on the first character + suffixShift = 1; + } + else if (L[i + 1] == -1) + { // Matched suffix does not appear anywhere in aPattern + suffixShift = aPattern.Length - F[i + 1]; + } + else + { // Matched suffix appears in aPattern + suffixShift = aPattern.Length - 1 - L[i + 1]; + } + int shift = Math.Max(charShift, suffixShift); + if (shift >= i + 1) + { // Galil's rule + previousK = k; + } + k += shift; + } + } + return matches; + } + + /// + /// Create the shift table, F, for the given text, which is an array such that + /// F[i] is the length of the longest suffix of, aText.substring(i), which is also a prefix of the given text. + /// + /// Use case: If a mismatch occurs at character index i - 1 in the pattern, + /// the magnitude of the shift of the pattern, P, relative to the text is: P.length() - F[i]. + /// + private static int[] FullShiftTable(string aText) + { + int[] F = new int[aText.Length]; + int[] Z = FundamentalPreprocess(aText); + int longest = 0; + Array.Reverse(Z); + for (int i = 0; i < Z.Length; i++) + { + int zv = Z[i]; + if (zv == i + 1) + { + longest = Math.Max(zv, longest); + } + F[F.Length - i - 1] = longest; + } + return F; + } + + /// + /// Create the good suffix table, L, for the given text, which is an array such that + /// L[i] = k, is the largest index in the given text, S, + /// such that S.substring(i) matches a suffix of S.substring(0, k). + /// + /// Use case: If a mismatch of characters occurs at index i - 1 in the pattern, P, + /// then a shift of magnitude, P.length() - L[i], is such that no instances of the pattern in the text are omitted. + /// Furthermore, a suffix of P.substring(0, L[i]) matches the same substring of the text that was matched by a + /// suffix in the pattern on the previous matching attempt. + /// In the case that L[i] = -1, the full shift table must be used. + /// + private static int[] GoodSuffixTable(string aText) + { + int[] L = Enumerable.Repeat(-1, aText.Length).ToArray(); + string reversed = new string(aText.Reverse().ToArray()); + int[] N = FundamentalPreprocess(reversed); + Array.Reverse(N); + for (int j = 0; j < aText.Length - 1; j++) + { + int i = aText.Length - N[j]; + if (i != aText.Length) + { + L[i] = j; + } + } + return L; + } + + /// + /// Create the bad character table, R, for the given text, + /// which is a list indexed by the ASCII value of a character, C, in the given text. + /// + /// Use case: The entry at index i of R is a list of size: 1 + length of the given text. + /// This inner list gives at each index j the next position at which character C will be found + /// while traversing the given text from right to left starting from index j. + /// + private static List> BadCharacterTable(string aText) + { + if (string.IsNullOrEmpty(aText)) + { + return new List>(); + } + + List> R = Enumerable.Range(0, ALPHABET_SIZE) + .Select(i => new List(Enumerable.Repeat(-1, 1))).ToList(); + List alpha = Enumerable.Repeat(-1, ALPHABET_SIZE).ToList(); + + for (int i = 0; i < aText.Length; i++) + { + alpha[AlphabetIndex(aText[i])] = i; + for (int j = 0; j < alpha.Count; j++) + { + R[j].Add(alpha[j]); + } + } + return R; + } + + /// + /// Create the fundamental preprocess, Z, of the given text, which is an array such that + /// Z[i] is the length of the substring of the given text beginning at index i which is also a prefix of the text. + /// + private static int[] FundamentalPreprocess(string aText) + { + if (string.IsNullOrEmpty(aText)) + { + return new int[0]; + } + if (aText.Length == 1) + { + return new int[] { 1 }; + } + + int[] Z = new int[aText.Length]; + Z[0] = aText.Length; + Z[1] = MatchLength(aText, 0, 1); + for (int i = 2; i <= Z[1]; i++) + { + Z[i] = Z[1] - i + 1; + } + + // Define the left and right limits of the z-box + int left = 0; + int right = 0; + for (int i = 2 + Z[1]; i < aText.Length; i++) + { + if (i <= right) + { // i falls within existing z-box + int k = i - left; + int b = Z[k]; + int a = right - i + 1; + if (b < a) + { // b ends within existing z-box + Z[i] = b; + } + else + { // b ends at or after the end of the z-box, + // an explicit match to the right of the z-box is required + Z[i] = a + MatchLength(aText, a, right + 1); + left = i; + right = i + Z[i] - 1; + } + } + else + { // i does not fall within existing z-box + Z[i] = MatchLength(aText, 0, i); + if (Z[i] > 0) + { + left = i; + right = i + Z[i] - 1; + } + } + } + return Z; + } + + /// + /// Return the length of the match of the two substrings of the given text beginning at each of the given indexes. + /// + private static int MatchLength(string aText, int aIndexOne, int aIndexTwo) + { + if (aIndexOne == aIndexTwo) + { + return aText.Length - aIndexOne; + } + + int matchCount = 0; + while (aIndexOne < aText.Length && aIndexTwo < aText.Length + && aText[aIndexOne] == aText[aIndexTwo]) + { + matchCount += 1; + aIndexOne += 1; + aIndexTwo += 1; + } + return matchCount; + } + + /// + /// Return the ASCII index of the given character, if it is such, otherwise throw an illegal argument exception. + /// + private static int AlphabetIndex(char aChar) + { + int result = (int)aChar; + if (result >= ALPHABET_SIZE) + { + throw new ArgumentException("Not an ASCII character:" + aChar); + } + return result; + } + + /* The range of ASCII characters is 0..255, both inclusive. */ + private const int ALPHABET_SIZE = 256; +} diff --git a/Task/Boyer-Moore-string-search/EasyLang/boyer-moore-string-search.easy b/Task/Boyer-Moore-string-search/EasyLang/boyer-moore-string-search.easy new file mode 100644 index 0000000000..c81b25fa98 --- /dev/null +++ b/Task/Boyer-Moore-string-search/EasyLang/boyer-moore-string-search.easy @@ -0,0 +1,67 @@ +# only works with ascii strings +# +func is_prefix &needle$[] pos . + pos -= 1 + for i to len needle$[] - pos + if needle$[i] <> needle$[pos + i] : return 0 + . + return 1 +. +func suffix_size &needle$[] pos . + i = pos + j = len needle$[] + while i >= 1 and needle$[i] = needle$[j] + i -= 1 + j -= 1 + size += 1 + . + return size +. +proc mk_good_tbl &needle$[] &tbl[] . + nlen = len needle$[] + len tbl[] nlen + lastpre = nlen + 1 + for i = nlen downto 1 + if is_prefix needle$[] i = 1 : lastpre = i + tbl[nlen - i + 1] = lastpre - i + nlen + . + for i to nlen - 1 + size = suffix_size needle$[] i + tbl[size + 1] = nlen - i + size + . +. +proc mk_bad_tbl &needle$[] &tbl[] . + len tbl[] 128 + for i to 128 : tbl[i] = len needle$[] + for i to len needle$[] - 1 + tbl[strcode needle$[i]] = len needle$[] - i + . +. +func[] find hayst$ needle$ . + if needle$ = "" : return [ ] + needle$[] = strchars needle$ + hayst$[] = strchars hayst$ + mk_bad_tbl needle$[] bad_tbl[] + mk_good_tbl needle$[] good_tbl[] + nelen = len needle$[] + i = nelen + while i <= len hayst$[] + j = nelen + while j > 1 and needle$[j] = hayst$[i] + i -= 1 + j -= 1 + . + if needle$[j] = hayst$[i] + r[] &= i + i += nelen + else + i += higher good_tbl[nelen - j + 1] bad_tbl[strcode hayst$[i]] + . + . + return r[] +. +texts$[] = [ "GCTAGCTCTACGAGTCTA" "GGCTATAATGCGTA" "there would have been a time for such a word" "needle need noodle needle" "alfalfa" ] +pat$[] = [ "TCTA" "TAATAAA" "word" "needle" "alfa" ] +for i to len texts$[] + print pat$[i] & " ? " & texts$[i] & " -> " & find texts$[i] pat$[i] +. diff --git a/Task/Boyer-Moore-string-search/Go/boyer-moore-string-search.go b/Task/Boyer-Moore-string-search/Go/boyer-moore-string-search.go new file mode 100644 index 0000000000..83c6bfb18d --- /dev/null +++ b/Task/Boyer-Moore-string-search/Go/boyer-moore-string-search.go @@ -0,0 +1,65 @@ +package main + +import ( + "fmt" + "strings" +) + +func display(numbers []int32) { + fmt.Print("[") + for i, num := range numbers { + if i > 0 { + fmt.Print(", ") + } + fmt.Print(num) + } + fmt.Println("]") +} + +func stringSearchSingle(haystack, needle string) int32 { + index := strings.Index(haystack, needle) + return int32(index) +} + +func stringSearch(haystack, needle string) []int32 { + var result []int32 + var start int64 = 0 + + for start < int64(len(haystack)) { + haystackReduced := haystack[start:] + index := stringSearchSingle(haystackReduced, needle) + + if index >= 0 { + result = append(result, int32(start)+index) + start += int64(index) + int64(len(needle)) + } else { + break + } + } + + return result +} + +func main() { + texts := []string{ + "GCTAGCTCTACGAGTCTA", + "GGCTATAATGCGTA", + "there would have been a time for such a word", + "needle need noodle needle", + "DKnuthusesandprogramsanimaginarycomputertheMIXanditsassociatedmachinecodeandassemblylanguages", + "Nearby farms grew an acre of alfalfa on the dairy's behalf, with bales of that alfalfa exchanged for milk.", + } + + patterns := []string{"TCTA", "TAATAAA", "word", "needle", "and", "alfalfa"} + + for i := 0; i < len(texts); i++ { + fmt.Printf("text%d = %s\n", i+1, texts[i]) + } + fmt.Println() + + for i := 0; i < len(texts); i++ { + indexes := stringSearch(texts[i], patterns[i]) + fmt.Printf("Found \"%s\" in 'text%d' at indexes ", patterns[i], i+1) + display(indexes) + } +} diff --git a/Task/Boyer-Moore-string-search/JavaScript/boyer-moore-string-search.js b/Task/Boyer-Moore-string-search/JavaScript/boyer-moore-string-search.js new file mode 100644 index 0000000000..4f1709739c --- /dev/null +++ b/Task/Boyer-Moore-string-search/JavaScript/boyer-moore-string-search.js @@ -0,0 +1,52 @@ +function display(numbers) { + console.log(`[${numbers.join(", ")}]`); +} + +function string_search_single(haystack, needle) { + const index = haystack.indexOf(needle); + return index; +} + +function string_search(haystack, needle) { + const result = []; + let start = 0; + let index = 0; + + while (index >= 0 && start < haystack.length) { + const haystackReduced = haystack.substring(start); + index = string_search_single(haystackReduced, needle); + if (index >= 0) { + result.push(start + index); + start += index + needle.length; + } + } + return result; +} + +function main() { + const texts = [ + "GCTAGCTCTACGAGTCTA", + "GGCTATAATGCGTA", + "there would have been a time for such a word", + "needle need noodle needle", + "DKnuthusesandprogramsanimaginarycomputertheMIXanditsassociatedmachinecodeandassemblylanguages", + "Nearby farms grew an acre of alfalfa on the dairy's behalf, with bales of that alfalfa exchanged for milk.", + ]; + + const patterns = ["TCTA", "TAATAAA", "word", "needle", "and", "alfalfa"]; + + for (let i = 0; i < texts.length; ++i) { + console.log(`text${i + 1} = ${texts[i]}`); + } + console.log(); + + for (let i = 0; i < texts.length; ++i) { + const indexes = string_search(texts[i], patterns[i]); + console.log( + `Found "${patterns[i]}" in 'text${i + 1}' at indexes ` + ); + display(string_search(texts[i], patterns[i])); + } +} + +main(); diff --git a/Task/Boyer-Moore-string-search/Rust/boyer-moore-string-search.rs b/Task/Boyer-Moore-string-search/Rust/boyer-moore-string-search.rs new file mode 100644 index 0000000000..15cf2485cd --- /dev/null +++ b/Task/Boyer-Moore-string-search/Rust/boyer-moore-string-search.rs @@ -0,0 +1,62 @@ +fn display(numbers: &Vec) { + print!("["); + for (i, num) in numbers.iter().enumerate() { + if i > 0 { + print!(", "); + } + print!("{}", num); + } + println!("]"); +} + +fn string_search_single(haystack: &str, needle: &str) -> i32 { + // Rust's standard library doesn't have Boyer-Moore searcher directly, + // but we can use the built-in find method which is efficient + match haystack.find(needle) { + Some(index) => index as i32, + None => -1, + } +} + +fn string_search(haystack: &str, needle: &str) -> Vec { + let mut result: Vec = Vec::new(); + let mut start: usize = 0; + + while start < haystack.len() { + let haystack_reduced = &haystack[start..]; + let index = string_search_single(haystack_reduced, needle); + + if index >= 0 { + result.push((start as i32) + index); + start += index as usize + needle.len(); + } else { + break; + } + } + + result +} + +fn main() { + let texts = vec![ + "GCTAGCTCTACGAGTCTA", + "GGCTATAATGCGTA", + "there would have been a time for such a word", + "needle need noodle needle", + "DKnuthusesandprogramsanimaginarycomputertheMIXanditsassociatedmachinecodeandassemblylanguages", + "Nearby farms grew an acre of alfalfa on the dairy's behalf, with bales of that alfalfa exchanged for milk." + ]; + + let patterns = vec!["TCTA", "TAATAAA", "word", "needle", "and", "alfalfa"]; + + for i in 0..texts.len() { + println!("text{} = {}", i + 1, texts[i]); + } + println!(); + + for i in 0..texts.len() { + let indexes = string_search(texts[i], patterns[i]); + print!("Found \"{}\" in 'text{}' at indexes ", patterns[i], i + 1); + display(&indexes); + } +} diff --git a/Task/Boyer-Moore-string-search/Scala/boyer-moore-string-search.scala b/Task/Boyer-Moore-string-search/Scala/boyer-moore-string-search.scala new file mode 100644 index 0000000000..e33f56aa21 --- /dev/null +++ b/Task/Boyer-Moore-string-search/Scala/boyer-moore-string-search.scala @@ -0,0 +1,329 @@ +import scala.collection.mutable.ListBuffer +import scala.collection.immutable.Vector // Using Vector for the bad character table outer structure + +/** + * An implementation of the Boyer-Moore string search algorithm in Scala. + * It finds all occurrences of a pattern in a text, performing a case-sensitive search on ASCII characters. + * (Note: The original Java comment mentioned case-insensitive, but the code was case-sensitive ASCII). + * + * For a full description of the algorithm visit: + * https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm + */ +object BoyerMooreStringSearch { + + /* The range of ASCII characters is 0..255, both inclusive. */ + private final val ALPHABET_SIZE = 256 + + def main(args: Array[String]): Unit = { + val texts = List( + "GCTAGCTCTACGAGTCTA", + "GGCTATAATGCGTA", + "there would have been a time for such a word", + "needle need noodle needle", + "DKnuthusesandshowsanimaginarycomputertheMIXanditsassociatedmachinecodeandassemblylanguagestoillustrate", + "Farms grew an acre of alfalfa on the dairy's behalf, with bales of that alfalfa exchanged for milk." + ) + + val patterns = List("TCTA", "TAATAAA", "word", "needle", "put", "and", "alfalfa") + + texts.zipWithIndex.foreach { case (text, i) => + println(s"text${i + 1} = $text") + } + println() + + patterns.zipWithIndex.foreach { case (pattern, i) => + // Replicate the original Java logic for selecting the text index 'j' + val j = if (i < 5) i else i - 1 + if (j >= 0 && j < texts.length) { // Ensure j is a valid index + val textToSearch = texts(j) + val matches = stringSearch(textToSearch, pattern) + // Use mkString for cleaner list output + println(s"""Found "$pattern" in 'text${j + 1}' at indexes [${matches.mkString(", ")}]""") + } else { + println(s"Skipping pattern '$pattern' - calculated text index $j is out of bounds.") + } + } + } + + /** + * Return a list of indexes at which the given pattern matches the given text. + */ + private def stringSearch(aText: String, aPattern: String): List[Int] = { + if (aPattern.isEmpty || aText.isEmpty || aText.length < aPattern.length) { + return List.empty[Int] // Use Scala's immutable empty list + } + + val matches = ListBuffer[Int]() // Use mutable ListBuffer for efficient appending + + // Preprocessing + val R = badCharacterTable(aPattern) // Returns Vector[Vector[Int]] + val L = goodSuffixTable(aPattern) // Returns Array[Int] + val F = fullShiftTable(aPattern) // Returns Array[Int] + + val m = aPattern.length + val n = aText.length + + var k = m - 1 // Represents the alignment of the end of aPattern relative to aText + var previousK = -1 // Represents the above alignment in the previous phase (for Galil's rule) + + while (k < n) { + var i = m - 1 // Index of the character to compare in aPattern (from right to left) + var h = k // Index of the character to compare in aText (aligned with i) + + // Character comparison loop + // Galil's rule optimization: h > previousK avoids re-comparing known matched prefix + while (i >= 0 && h > previousK && aPattern(i) == aText(h)) { + i -= 1 + h -= 1 + } + + if (i == -1 || h == previousK) { // Match has been found OR comparison skipped by Galil's rule up to a previously matched prefix + matches.append(k - m + 1) // Add start index of match + // Calculate shift based on the full shift table F for the next potential match + // F[1] represents the border length of P[1..m-1] + val shift = if (m > 1) m - F(1) else 1 + k += shift + // previousK is NOT reset here per original logic; it's related to shifts during *mismatches* + } else { // Mismatch occurred at aText(h) and aPattern(i) + // Bad Character Rule shift: + // R(char code)(index in pattern + 1) gives the index of the previous occurrence + // of the mismatched text character `aText(h)` in the pattern `aPattern` + // at or before index `i`. The +1 adjusts for the table structure. + val charShift = i - R(alphabetIndex(aText(h)))(i + 1) + + // Good Suffix Rule shift: + val suffixShift = + if (i + 1 == m) { // Mismatch occurred on the first character comparison (rightmost) + 1 + } else { + // L(i + 1) stores the starting index of the rightmost occurrence of + // the matched suffix P[i+1 .. m-1] in P that is not a suffix of P. + // F(i + 1) stores the length of the longest suffix of P[i+1..m-1] that is also a prefix of P. + if (L(i + 1) == -1) { // Matched suffix P[i+1..m-1] does not appear elsewhere in P preceded by a different char + // Shift based on the longest suffix of P[i+1..m-1] that is also a prefix of P (using F table) + m - F(i + 1) + } else { // Matched suffix P[i+1..m-1] appears starting at index L(i+1) + // Shift to align this previous occurrence with the text + m - 1 - L(i + 1) + } + } + + // Choose the maximum shift from the two rules + val shift = math.max(charShift, suffixShift) + + // Galil's rule: If the shift skips over the potential match area entirely, + // remember the current alignment `k` to optimize the next comparison loop. + if (shift >= i + 1) { + previousK = k + } + // Per original Java code: If Galil's rule does not apply (shift < i + 1), previousK is not modified here. + + k += shift // Apply the calculated shift + } + } // end while + + matches.toList // Convert mutable buffer to immutable list for the result + } + + /** + * Create the shift table, F, for the given pattern P, which is an array such that + * F[i] is the length of the longest suffix of P[i..m-1] which is also a prefix of P. + * + * Use case: If a mismatch occurs at character index i - 1 in the pattern, and the + * good suffix rule L[i] indicates no earlier occurrence, the shift is P.length() - F[i]. + */ + private def fullShiftTable(aPattern: String): Array[Int] = { + val m = aPattern.length + val F = new Array[Int](m) // Initialize with 0s + val Z = fundamentalPreprocess(aPattern) // Z[i] = length of longest substring starting at i that is prefix of pattern + val Z_reversed = Z.reverse // Reverse Z array + + var longest = 0 + // Iterate through the reversed Z array to build F from right-to-left effectively + for (i <- 0 until Z_reversed.length) { + val zv = Z_reversed(i) + // If Z value equals its length from the end, it's a suffix that's also a prefix + if (zv == i + 1) { + longest = math.max(zv, longest) + } + // Map the reversed index 'i' back to the original index for F + val originalIndex = m - 1 - i + if (originalIndex >= 0 && originalIndex < m) { // Bounds check + F(originalIndex) = longest + } + } + F + } + + /** + * Create the good suffix table, L', for the given pattern P (often denoted L' or L[i] in literature). + * L'[i] = k, is the largest index k < m such that P[i..m-1] is a suffix of P[0..k-1] + * and the character preceding the suffix P[k - (m-i) .. k-1] is different from P[i-1]. + * If no such k exists, L'[i] = -1. + * + * Use case: If a mismatch occurs at index i - 1, shift by m - 1 - L'[i]. + * This implementation calculates a related table L where L[i] stores j such that + * P[i..m-1] matches P[j-(m-i)..j]. + */ + private def goodSuffixTable(aPattern: String): Array[Int] = { + val m = aPattern.length + // Initialize L with -1. Size is m. + val L = Array.fill(m)(-1) + val reversedPattern = aPattern.reverse + // N[j] = length of longest substring starting at j that is prefix of reversedPattern + // This corresponds to matching suffixes of the original pattern. + val N = fundamentalPreprocess(reversedPattern) + // Reverse N to align indices with the original pattern's perspective + val N_reversed = N.reverse + + // N_reversed[j] = length of longest suffix of P ending at j that is also suffix of P + for (j <- 0 until m - 1) { + // i = position in P where the suffix match starts (from the right end) + val suffixLen = N_reversed(j) + val i = m - suffixLen + // L[i] should store the end position 'j' of the matching internal suffix. + // Condition i != m means the suffix is not the whole pattern itself. + if (i != m) { + if (i >= 0 && i < m) { // Bounds check for L index + L(i) = j + } + } + } + L + } + + /** + * Create the bad character table, R. + * R(c)(i) stores the index of the rightmost occurrence of character `c` + * in the pattern `P` at or before index `i-1`. If `c` does not occur + * before index `i`, it stores -1. + * The table is represented as Vector[Vector[Int]], indexed by char code, then pattern index + 1. + */ + private def badCharacterTable(aPattern: String): Vector[Vector[Int]] = { + if (aPattern.isEmpty) { + return Vector.empty // Return empty structure if pattern is empty + } + val m = aPattern.length + + // Use ListBuffer internally for efficient construction, then convert to Vector + val R_buffers = Array.fill(ALPHABET_SIZE)(ListBuffer(-1)) // Initialize inner lists with -1 + // 'alpha' tracks the most recent index seen for each character + val alpha = Array.fill(ALPHABET_SIZE)(-1) + + for (i <- 0 until m) { + val charIndex = alphabetIndex(aPattern(i)) + alpha(charIndex) = i // Update last seen position for this character + // For each character in the alphabet, append its *current* last seen position + // This builds the table column by column (for each pattern index i) + for (j <- 0 until ALPHABET_SIZE) { + R_buffers(j).append(alpha(j)) + } + } + // Convert the mutable buffers to immutable Vectors + R_buffers.map(_.toVector).toVector + } + + /** + * Create the fundamental preprocess array, Z, for the given text (or pattern). + * Z[i] is the length of the longest substring starting at index i + * which is also a prefix of the text. Z[0] is defined as the text length. + * This is used in calculating the Good Suffix and Full Shift tables. + */ + private def fundamentalPreprocess(aText: String): Array[Int] = { + val n = aText.length + if (n == 0) return Array.empty[Int] + if (n == 1) return Array(1) + + val Z = new Array[Int](n) + Z(0) = n + Z(1) = matchLength(aText, 0, 1) // Calculate Z[1] explicitly + + // Optimization for early part based on Z[1] + // Use Scala range 'until' for exclusive upper bound + var initial_z1_limit = math.min(Z(1) + 1, n) // Limit loop correctly + for (i <- 2 until initial_z1_limit) { + Z(i) = Z(1) - i + 1 + } + + // Define the left and right limits of the current Z-box [left, right] + var left = 0 + var right = 0 + // If Z(1) > 0, the initial Z-box is [1, Z(1)] ? No, Z-box related to previous calculations. + // Need to initialize left/right correctly based on Z[1] usage or start fresh. + // Let's restart Z-box calculation from where the optimization loop left off. + + val loopStart = if (Z(1) > 0) math.min(2 + Z(1), n) else 2 // Start after initial Z[1] optimization range + // Correct initialization of Z-box should be based on the *last* Z calculation that extended right boundary. + // Resetting left/right and letting the loop find the first Z-box might be simpler/safer. + left = 0 + right = 0 + + // Calculate remaining Z values using Z-box optimization + for (i <- loopStart until n) { + if (i <= right) { // i falls within existing Z-box [left, right] + val k = i - left // Corresponding index within the prefix + val b = Z(k) // Length of match starting at k + val a = right - i + 1 // Remaining length within the Z-box from i + + if (b < a) { // Match Z[k] is strictly contained within the Z-box suffix + Z(i) = b + } else { // Match Z[k] extends to or past the end of the Z-box + // Need explicit comparison beyond the Z-box + // Match length from text[a..] against text[right+1..] + val matchLen = matchLength(aText, a, right + 1) + Z(i) = a + matchLen + left = i // Start a new Z-box + right = i + Z(i) - 1 + } + } else { // i is outside the current Z-box + Z(i) = matchLength(aText, 0, i) // Calculate Z[i] by explicit comparison with prefix + if (Z(i) > 0) { // If a match is found, start a new Z-box + left = i + right = i + Z(i) - 1 + } + // else: Z[i] is 0, no Z-box formed, left/right remain unchanged + } + } + Z + } + + /** + * Return the length of the match of the two substrings of the given text + * beginning at each of the given indexes. + */ + private def matchLength(aText: String, aIndexOne: Int, aIndexTwo: Int): Int = { + if (aIndexOne < 0 || aIndexTwo < 0 || aIndexOne >= aText.length || aIndexTwo >= aText.length) { + return 0 // Added boundary checks + } + if (aIndexOne == aIndexTwo) { + // Match length from index to end of string + return aText.length - aIndexOne + } + + var matchCount = 0 + var idx1 = aIndexOne + var idx2 = aIndexTwo + // Use Scala's string indexing aText(idx) + while (idx1 < aText.length && idx2 < aText.length && aText(idx1) == aText(idx2)) { + matchCount += 1 + idx1 += 1 + idx2 += 1 + } + matchCount + } + + /** + * Return the ASCII index (0-255) of the given character. + * Throws IllegalArgumentException if the character code is outside the 0-255 range. + */ + private def alphabetIndex(aChar: Char): Int = { + val result = aChar.toInt + // Ensure character fits within the expected ASCII range for the table size + if (result < 0 || result >= ALPHABET_SIZE) { + // Consider if non-ASCII should be handled differently or error is correct. + // Sticking to original logic which assumes ASCII range 0-255. + throw new IllegalArgumentException(s"Character '$aChar' (code $result) is outside the expected ASCII range [0, ${ALPHABET_SIZE - 1}]") + } + result + } +} diff --git a/Task/Boyer-Moore-string-search/Wren/boyer-moore-string-search.wren b/Task/Boyer-Moore-string-search/Wren/boyer-moore-string-search.wren index f3410aec49..691956df2e 100644 --- a/Task/Boyer-Moore-string-search/Wren/boyer-moore-string-search.wren +++ b/Task/Boyer-Moore-string-search/Wren/boyer-moore-string-search.wren @@ -93,20 +93,20 @@ class BoyerMoore { } /* - * Uses the BoyerMoore class to find the indices of ALL non-overlapping matches of the specified substring - * and return a list of them. Returns an empty list if it's not a substring. + * Uses the BoyerMoore class to find the indices of ALL matches (overlapping or not) + * of the specified substring and return a list of them. + * Returns an empty list if it's not a substring. */ var indicesOf = Fn.new { |haystack, needle| var indices = [] var hc = haystack.bytes.count - var bc = needle.bytes.count var start = 0 while (true) { var haystack2 = haystack[start..-1] var index = BoyerMoore.indexOf(haystack2, needle) if (index == -1) return indices indices.add(start + index) - start = start + index + bc + start = start + index + 1 if (start >= hc) return indices } } @@ -117,9 +117,12 @@ var texts = [ "there would have been a time for such a word", "needle need noodle needle", "InhisbookseriesTheArtofComputerProgrammingpublishedbyAddisonWesleyDKnuthusesanimaginarycomputertheMIXanditsassociatedmachinecodeandassemblylanguagestoillustratetheconceptsandalgorithmsastheyarepresented", - "Nearby farms grew a half acre of alfalfa on the dairy's behalf, with bales of all that alfalfa exchanged for milk." + "Nearby farms grew a half acre of alfalfa on the dairy's behalf, with bales of all that alfalfa exchanged for milk.", + "Due to a malfunction, alfredo halfheartedly wore calfskin severalfold on behalf of alfa.", + "alfalfa", + "zzzzzz" ] -var pats = ["TCTA", "TAATAAA", "word", "needle", "put", "and", "alfalfa"] +var pats = ["TCTA", "TAATAAA", "word", "needle", "put", "and", "alfalfa", "alfa", "alfa", "zzz"] for (i in 0...texts.count) System.print("text%(i+1) = %(texts[i])") System.print() for (i in 0...pats.count) { diff --git a/Task/Brace-expansion/EasyLang/brace-expansion.easy b/Task/Brace-expansion/EasyLang/brace-expansion.easy index e9d898f73e..ef1c473c36 100644 --- a/Task/Brace-expansion/EasyLang/brace-expansion.easy +++ b/Task/Brace-expansion/EasyLang/brace-expansion.easy @@ -1,5 +1,5 @@ -procdecl getgroup depth . out$[] s$ ok . -proc getitem depth . s$ out$[] . +procdecl getgroup depth &out$[] &s$ &ok . +proc getitem depth &s$ &out$[] . out$[] = [ "" ] while s$ <> "" c$ = substr s$ 1 1 @@ -34,7 +34,7 @@ proc getitem depth . s$ out$[] . . . . -proc getgroup depth . out$[] s$ ok . +proc getgroup depth &out$[] &s$ &ok . out$[] = [ ] while s$ <> "" getitem depth s$ g$[] diff --git a/Task/Brazilian-numbers/EasyLang/brazilian-numbers.easy b/Task/Brazilian-numbers/EasyLang/brazilian-numbers.easy index 7fe5b6cc1a..c444438cb9 100644 --- a/Task/Brazilian-numbers/EasyLang/brazilian-numbers.easy +++ b/Task/Brazilian-numbers/EasyLang/brazilian-numbers.easy @@ -3,34 +3,23 @@ func sameDigits n b . repeat n = n div b until n = 0 - if n mod b <> f - return 0 - . + if n mod b <> f : return 0 . return 1 . func isBrazilian7 n . # n >= 7 - if n mod 2 = 0 - return 1 - . + if n mod 2 = 0 : return 1 for b = 2 to n - 2 - if sameDigits n b = 1 - return 1 - . + if sameDigits n b = 1 : return 1 . return 0 . func prime n . - if n mod 2 = 0 and n > 2 - return 0 - . + if n mod 2 = 0 and n > 2 : return 0 i = 3 - sq = sqrt n - while i <= sq - if n mod i = 0 - return 0 - . + while i <= sqrt n + if n mod i = 0 : return 0 i += 2 . return 1 diff --git a/Task/Brilliant-numbers/EasyLang/brilliant-numbers.easy b/Task/Brilliant-numbers/EasyLang/brilliant-numbers.easy index 410153777f..4c3d4f963c 100644 --- a/Task/Brilliant-numbers/EasyLang/brilliant-numbers.easy +++ b/Task/Brilliant-numbers/EasyLang/brilliant-numbers.easy @@ -1,34 +1,24 @@ fastfunc factor num . if num mod 2 = 0 - if num = 2 - return 1 - . + if num = 2 : return 1 return 2 . i = 3 while i <= sqrt num - if num mod i = 0 - return i - . + if num mod i = 0 : return i i += 2 . return 1 . func brilliant n . f1 = factor n - if f1 = 1 - return 0 - . + if f1 = 1 : return 0 f2 = n div f1 - if floor log10 f1 <> floor log10 f2 - return 0 - . - if factor f1 = 1 and factor f2 = 1 - return 1 - . + if floor log10 f1 <> floor log10 f2 : return 0 + if factor f1 = 1 and factor f2 = 1 : return 1 return 0 . -proc main . . +proc main . i = 2 while cnt < 100 if brilliant i = 1 diff --git a/Task/Brownian-tree/EasyLang/brownian-tree.easy b/Task/Brownian-tree/EasyLang/brownian-tree.easy index f0c9a26ba3..821e4bcf89 100644 --- a/Task/Brownian-tree/EasyLang/brownian-tree.easy +++ b/Task/Brownian-tree/EasyLang/brownian-tree.easy @@ -1,7 +1,6 @@ -color3 0 1 1 +gcolor3 0 1 1 len f[] 200 * 200 -move 50 50 -rect 0.5 0.5 +grect 50 50 0.5 0.5 f[100 * 200 + 100] = 1 n = 9000 while i < n @@ -19,12 +18,11 @@ while i < n break 1 . if f[y * 200 + x + 1] = 1 - move xo / 2 yo / 2 - rect 0.5 0.5 + grect xo / 2 yo / 2 0.5 0.5 f[yo * 200 + xo + 1] = 1 i += 1 if i mod 16 = 0 - color3 0.2 + i / n 1 1 + gcolor3 0.2 + i / n 1 1 sleep 0 . break 1 diff --git a/Task/Bulls-and-cows/APL/bulls-and-cows-1.apl b/Task/Bulls-and-cows/APL/bulls-and-cows-1.apl index 984eda7a85..fa91aa7235 100644 --- a/Task/Bulls-and-cows/APL/bulls-and-cows-1.apl +++ b/Task/Bulls-and-cows/APL/bulls-and-cows-1.apl @@ -6,5 +6,5 @@ guess ← ⍎¨input⍣(valid⊣) bulls ← +/= cows ← +/∊∧≠ game ← (output ⊣(bulls,cows) guess)⍣(4 0≡⊣) -random ← 1+4?9⍨ +random ← 1+4?9 moo ← 'You win!'⊣(random game⊢) diff --git a/Task/Bulls-and-cows/J/bulls-and-cows-1.j b/Task/Bulls-and-cows/J/bulls-and-cows-1.j index 74cb5c0578..3384f1c33b 100644 --- a/Task/Bulls-and-cows/J/bulls-and-cows-1.j +++ b/Task/Bulls-and-cows/J/bulls-and-cows-1.j @@ -1,5 +1,5 @@ -output=. [ 'Bulls: '&,:@'Cows: ' echo@,. ":@,. -valid =. *./@e.&'0123456789' *. 4 = # -guess =. [: ".&> :: ] $:^:(-.@valid)@(1!:1@1)@echo@'Guess:' -game =. [ $:^:(4 0-.@-:]) [ (+/@:= output@, e.+/@:*.~:) guess +output=. ['Bulls: '&,:@'Cows: 'echo@,.":@,. +valid =. *./@e.&Num_j_*.4=# +guess =. 0 ".&> [: > $:^:(-.@valid)@(1!:1@1)@echo@'Guess:'t.0 +game =. [ $:^:(4 0-.@-:]) [ (+/@:= output@, e. +/@:*. ~:) guess moo =. 'You win!'[ (1+4?9:) game ] diff --git a/Task/Bulls-and-cows/J/bulls-and-cows-2.j b/Task/Bulls-and-cows/J/bulls-and-cows-2.j index 9795e742c7..33fcb7bd55 100644 --- a/Task/Bulls-and-cows/J/bulls-and-cows-2.j +++ b/Task/Bulls-and-cows/J/bulls-and-cows-2.j @@ -1,9 +1,9 @@ U =. {{u^:(-.@:v)^:_.}} NB. apply u until v is true input =. 1!:1@1@echo@'Guess: ' output =. [ ('Bulls: ',:'Cows: ')echo@,.":@,. -isdigits=. *./@e.&'0123456789' +isdigits=. *./@e.&Num_j_ valid =. isdigits*.4=# -guess =. [:".&>input U(valid@]) +guess =. 0".&>input U(valid@]) bulls =. +/@:= cows =. [:+/e.*.~: game =. ([:output [(bulls,cows) guess)U(4 0-:]) diff --git a/Task/Burrows-Wheeler-transform/EasyLang/burrows-wheeler-transform.easy b/Task/Burrows-Wheeler-transform/EasyLang/burrows-wheeler-transform.easy index d3197d271a..2e078b2b25 100644 --- a/Task/Burrows-Wheeler-transform/EasyLang/burrows-wheeler-transform.easy +++ b/Task/Burrows-Wheeler-transform/EasyLang/burrows-wheeler-transform.easy @@ -3,7 +3,7 @@ stx$ = "¹" etx$ = "²" # -proc sort . d$[] . +proc sort &d$[] . for i = 2 to len d$[] h$ = d$[i] j = i - 1 @@ -22,16 +22,12 @@ func$ bwt s$ . tbl$[] &= b$ & a$ . sort tbl$[] - for s$ in tbl$[] - r$ &= substr s$ len s$ 1 - . + for s$ in tbl$[] : r$ &= substr s$ len s$ 1 return r$ . func$ ibwt r$ . le = len r$ - for i to le - tbl$[] &= "" - . + for i to le : tbl$[] &= "" for j to le for i to le tbl$[i] = substr r$ i 1 & tbl$[i] diff --git a/Task/Burrows-Wheeler-transform/JavaScript/burrows-wheeler-transform.js b/Task/Burrows-Wheeler-transform/JavaScript/burrows-wheeler-transform.js new file mode 100644 index 0000000000..dc7efff102 --- /dev/null +++ b/Task/Burrows-Wheeler-transform/JavaScript/burrows-wheeler-transform.js @@ -0,0 +1,76 @@ +class BWT { + static STX = "\u0002"; + static ETX = "\u0003"; + + static bwt(s) { + if (s.includes(BWT.STX) || s.includes(BWT.ETX)) { + throw new Error("String cannot contain STX or ETX"); + } + + const ss = BWT.STX + s + BWT.ETX; + const table = []; + for (let i = 0; i < ss.length; i++) { + const before = ss.substring(i); + const after = ss.substring(0, i); + table.push(before + after); + } + table.sort(); + + let sb = ""; + for (const str of table) { + sb += str.charAt(str.length - 1); + } + return sb; + } + + static ibwt(r) { + const len = r.length; + const table = []; + for (let i = 0; i < len; ++i) { + table.push(""); + } + for (let j = 0; j < len; ++j) { + for (let i = 0; i < len; ++i) { + table[i] = r.charAt(i) + table[i]; + } + table.sort(); + } + for (const row of table) { + if (row.endsWith(BWT.ETX)) { + return row.substring(1, len - 1); + } + } + return ""; + } + + static makePrintable(s) { + // substitute ^ for STX and | for ETX to print results + return s.replace(BWT.STX, "^").replace(BWT.ETX, "|"); + } + + static main() { + const tests = [ + "banana", + "appellee", + "dogwood", + "TO BE OR NOT TO BE OR WANT TO BE OR NOT?", + "SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES", + "\u0002ABC\u0003" + ]; + for (const test of tests) { + console.log(BWT.makePrintable(test)); + process.stdout.write(" --> "); + let t = ""; + try { + t = BWT.bwt(test); + console.log(BWT.makePrintable(t)); + } catch (e) { + console.log("ERROR: " + e.message); + } + const r = BWT.ibwt(t); + console.log(` --> ${r}\n`); + } + } +} + +BWT.main(); diff --git a/Task/CSV-data-manipulation/M2000-Interpreter/csv-data-manipulation.m2000 b/Task/CSV-data-manipulation/M2000-Interpreter/csv-data-manipulation.m2000 index 7ef687eccb..ebca3c0383 100644 --- a/Task/CSV-data-manipulation/M2000-Interpreter/csv-data-manipulation.m2000 +++ b/Task/CSV-data-manipulation/M2000-Interpreter/csv-data-manipulation.m2000 @@ -1,6 +1,7 @@ +Locale 1032 Module Checkit { Function Sum { - Long c=0 + DECIMAL c=0 while not empty { c+=number } @@ -8,7 +9,7 @@ Module Checkit { } Document CSV$ = {C1,C2,C3,C4,C5 1,5,9,13,17 - 2,6,10,14,18 + 2,6,10.3,14,18 3,7,11,15,19 4,8,12,16,20 } @@ -19,13 +20,13 @@ Module Checkit { \\ use standard decimal point char \\ use standard (non json style string) \\ True = use bare strings (without "") - Input With "",,,true - Write With"",,,true + Input With "","",,true + Write With chr$(9),locale$(0xE),,true \\ for excel csv use Input With chr$(9),,true, true Open "data1.csv" for Wide Input as #M Open "data2.csv" for Wide Output as #M1 Input #M, h1$, h2$, h3$, h4$, h5$ - Write #M1, h1$, h2$, h3$, h4$, h5$ + Write #M1, h1$, h2$, h3$, h4$, h5$, "SUM" Print h1$, h2$, h3$, h4$, h5$ While not Eof(#M) { @@ -35,13 +36,15 @@ Module Checkit { } close #M1 Close #M + Input With chr$(9),locale$(0xE),,true Open "data2.csv" for Wide Input as #M - Input #M, h1$, h2$, h3$, h4$, h5$ - Print h1$, h2$, h3$, h4$, h5$ + Input #M, h1$, h2$, h3$, h4$, h5$, h6$ + Print h1$, h2$, h3$, h4$, h5$, h6$ While not Eof(#M) { Input #M, A1, A2, A3, A4, A5, Sum Print A1, A2, A3, A4, A5, Sum } Close #M + Win "Excel", dir$+"data2.csv" } Checkit diff --git a/Task/CSV-data-manipulation/Nu/csv-data-manipulation-1.nu b/Task/CSV-data-manipulation/Nu/csv-data-manipulation-1.nu new file mode 100644 index 0000000000..d137dc1b65 --- /dev/null +++ b/Task/CSV-data-manipulation/Nu/csv-data-manipulation-1.nu @@ -0,0 +1,5 @@ +open 'test_in.csv' | + each { |row| + let sum = ($row | values | math sum); + $row | insert Sum $sum + } diff --git a/Task/CSV-data-manipulation/Nu/csv-data-manipulation-2.nu b/Task/CSV-data-manipulation/Nu/csv-data-manipulation-2.nu new file mode 100644 index 0000000000..82640ab976 --- /dev/null +++ b/Task/CSV-data-manipulation/Nu/csv-data-manipulation-2.nu @@ -0,0 +1 @@ +open 'test_in.csv' | upsert Sum {|row| $row | values | math sum } diff --git a/Task/Caesar-cipher/Ballerina/caesar-cipher.ballerina b/Task/Caesar-cipher/Ballerina/caesar-cipher.ballerina new file mode 100644 index 0000000000..c0061314bf --- /dev/null +++ b/Task/Caesar-cipher/Ballerina/caesar-cipher.ballerina @@ -0,0 +1,32 @@ +import ballerina/io; + +function encrypt(string s, int key) returns string { + final int offset = key % 26; + if offset == 0 { return s; } + int d; + int[] chars = []; + foreach int c in s.toCodePointInts() { + if c >= 64 && c <= 90 { + d = c + offset; + if d > 90 { d -= 26; } + } else if c >= 97 && c <= 122 { + d = c + offset; + if d > 122 { d -= 26; } + } else { + d = c; + } + chars.push(d); + } + return checkpanic string:fromCodePointInts(chars); +} + +function decrypt(string s, int key) returns string { + return encrypt(s, 26 - key); +} + +public function main() { + string encoded = encrypt("Bright vixens jump; dozy fowl quack.", 8); + io:println(encoded); + string decoded = decrypt(encoded, 8); + io:println(decoded); +} diff --git a/Task/Calculating-the-value-of-e/Ballerina/calculating-the-value-of-e.ballerina b/Task/Calculating-the-value-of-e/Ballerina/calculating-the-value-of-e.ballerina new file mode 100644 index 0000000000..126270884a --- /dev/null +++ b/Task/Calculating-the-value-of-e/Ballerina/calculating-the-value-of-e.ballerina @@ -0,0 +1,17 @@ +import ballerina/io; + +const EPSILON = 1e-15; + +public function main() { + int fact = 1; + float e = 2.0; + int n = 2; + while true { + float e0 = e; + fact *= n; + n += 1; + e += 1.0 / fact; + if (e - e0).abs() < EPSILON { break; } + } + io:println("e = ", e); +} diff --git a/Task/Calculating-the-value-of-e/EasyLang/calculating-the-value-of-e.easy b/Task/Calculating-the-value-of-e/EasyLang/calculating-the-value-of-e.easy index d7d8e38d52..2c5eb9d8bf 100644 --- a/Task/Calculating-the-value-of-e/EasyLang/calculating-the-value-of-e.easy +++ b/Task/Calculating-the-value-of-e/EasyLang/calculating-the-value-of-e.easy @@ -1,4 +1,4 @@ -numfmt 15 0 +numfmt 0 15 fact = 1 n = 2 e = 2 diff --git a/Task/Calendar---for-REAL-programmers/Rust/calendar---for-real-programmers.rs b/Task/Calendar---for-REAL-programmers/Rust/calendar---for-real-programmers.rs new file mode 100644 index 0000000000..493487a05c --- /dev/null +++ b/Task/Calendar---for-REAL-programmers/Rust/calendar---for-real-programmers.rs @@ -0,0 +1,216 @@ +struct Months { + pub name: String, + pub days: i16, + pub start_wday: i16, + pub at: i16, +} +impl Months { + fn new_month(name: &str, days: i16) -> Self { + Months { + name: String::from(name), + days, + start_wday: 0, + at: 0, + } + } +} +struct Calendar { + year: i16, + width: i16, + cols: i16, + lead: i16, + gap: i16, + months: [Months; 12], + wdays: [&'static str; 7], +} +impl Calendar { + fn new_calendar(year: i16, width: i16) -> Self { + let mut calendar = Calendar { + year, + width, + cols: 0, + lead: 0, + gap: 0, + months: [ + Months::new_month("JANUARY", 31), + Months::new_month("FEBRUARY", 28), + Months::new_month("MARCH", 31), + Months::new_month("APRIL", 30), + Months::new_month("MAY", 31), + Months::new_month("JUNE", 30), + Months::new_month("JULY", 31), + Months::new_month("AUGUST", 31), + Months::new_month("SEPTEMBER", 30), + Months::new_month("OCTOBER", 31), + Months::new_month("NOVEMBER", 30), + Months::new_month("DECEMBER", 31), + ], + wdays: ["SU", "MO", "TU", "WE", "TH", "FR", "SA"], + }; + calendar.init_months(); + calendar + } + fn init_months(&mut self) { + // Check for leap year and adjust February + if (self.year % 4 == 0 && self.year % 100 != 0) || self.year % 400 == 0 { + self.months[1].days = 29; + } + // Calculate starting weekday for January + let y = self.year - 1; + let year_days = (y % 7) * (365 % 7) % 7; // (y * 365) % 7 + let leap_days = ((y >> 2) - y / 100 + y / 400) % 7; + self.months[0].start_wday = (year_days + leap_days + 1) % 7; + // Calculate starting weekdays for remaining months + for i in 1..12 { + self.months[i].start_wday = + ((self.months[i-1].start_wday as i16 + self.months[i-1].days as i16) % 7) as i16; + } + // Layout calculations + self.cols = (self.width + 2) / 22; + while 12 % self.cols != 0 { + self.cols -= 1; + } + self.gap = if self.cols > 1 { + let gap = (self.width - 20 * self.cols) / (self.cols - 1); + if gap > 4 { 4 } else { gap } + } + else { + 0 + }; + // Calculate left margin to center the calendar + self.lead = (self.width - (20 + self.gap) * self.cols + self.gap + 1) >> 1; + } + // Helper method to print N spaces + fn print_spaces(&self, n: i16) { + print!("{}", " ".repeat(n as usize)); + } + // Print a horizontal row of month grids + fn print_row(&mut self, row: i16) { + let from = row * self.cols; + let to = from + self.cols; + // Print month names centered + self.print_spaces(self.lead); + for c in from..to { + let name_len = self.months[c as usize].name.len() as i16; + self.print_spaces((20 - name_len) >> 1); + print!("{}", self.months[c as usize].name); + let extra_spaces = 20 - name_len - ((20 - name_len) >> 1); + let gap_spaces = if c == to - 1 { 0 } else { self.gap }; + self.print_spaces(extra_spaces + gap_spaces); + } + println!(); + // Print weekday headers for each month + self.print_spaces(self.lead); + for c in from..to { + for i in 0..7 { + print!("{}", self.wdays[i as usize]); + if i < 6 { + print!(" "); + } + } + if c < to - 1 { + self.print_spaces(self.gap); + } else { + println!(); + } + } + // Print the calendar days for all months in this row + loop { + // Check if we've printed all days for all months in this row + let mut all_done = true; + for c in from..to { + if self.months[c as usize].at < self.months[c as usize].days { + all_done = false; + break; + } + } + if all_done { + break; + } + self.print_spaces(self.lead); + for c in from..to { + let c_usize = c as usize; + let mut i = 0; + // Print spaces for days before the 1st of the month + while i < self.months[c_usize].start_wday { + self.print_spaces(3); + i += 1; + } + // Print the days of the month + while i < 7 && self.months[c_usize].at < self.months[c_usize].days { + self.months[c_usize].at += 1; + let day = self.months[c_usize].at; + // Print day with padding + if day < 10 { + print!(" {}", day); + } else { + print!("{}", day); + } + if i < 6 || c < to - 1 { + print!(" "); + } + i += 1; + } + // Fill remaining spaces in week if needed + while i < 7 && c < to - 1 { + self.print_spaces(3); + i += 1; + } + if c < to - 1 { + self.print_spaces(self.gap - 1); + } + self.months[c_usize].start_wday = 0; // Reset for next week + } + println!(); + } + println!(); // Extra line between rows of months + } + // Print the entire year's calendar + fn print_year(&mut self) { + // Print centered year heading + let year_str = self.year.to_string(); + let spaces = (self.width - year_str.len() as i16) >> 1; + self.print_spaces(spaces); + println!("{}", year_str); + println!(); + // Print each row of months + let rows = 12 / self.cols; + for row in 0..rows { + self.print_row(row); + } + } +} +fn main() -> Result<(), String> { + let args: Vec = env::args().collect(); + let mut year: i16 = 1969; // Default year + let mut width: i16 = 80; // Default width + let mut year_set = false; + // Process command line arguments + let mut i = 1; + while i < args.len() { + if args[i] == "-W" { + i += 1; + if i < args.len() { + width = args[i].parse::().map_err(|_| "Invalid width")?; + if width < 20 { + return Err("Width must be at least 20".to_string()); + } + } else { + return Err("Missing width value after -W".to_string()); + } + } else if !year_set { + year = match args[i].parse::() { + Ok(y) if y > 0 => y, + _ => 1969, // Default to 1969 if year is invalid + }; + year_set = true; + } else { + return Err(format!("Too many arguments. Usage: {} YEAR [-W WIDTH (>= 20)]", args[0])); + } + i += 1; + } + // Generate and print the calendar + let mut calendar = Calendar::new_calendar(year, width); + calendar.print_year(); + Ok(()) +} diff --git a/Task/Calendar/00-TASK.txt b/Task/Calendar/00-TASK.txt index 2224cf4612..2ae49d8177 100644 --- a/Task/Calendar/00-TASK.txt +++ b/Task/Calendar/00-TASK.txt @@ -17,6 +17,8 @@ For further Kudos see task [[Calendar - for "real" programmers|CALENDAR]], where For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder. +;See Also: +:*   [https://jmvdveer.home.xs4all.nl/en.post.snoopy-calender.html Snoopy calendar 1969-2025 Marcel van der Veer] - The deck is credited as being one of the first FOSS programs. ;Related task: :*   [[Five weekends]] diff --git a/Task/Calendar/EasyLang/calendar.easy b/Task/Calendar/EasyLang/calendar.easy index b785fed23d..c5d5c9d0d4 100644 --- a/Task/Calendar/EasyLang/calendar.easy +++ b/Task/Calendar/EasyLang/calendar.easy @@ -17,29 +17,21 @@ func$ makewk fst lst day . . for i = fst to lst i$ = i - if i <= 9 - i$ = " " & i - . + if i <= 9 : i$ = " " & i wstr$ &= i$ & " " . return substr wstr$ & blank$ 1 20 . -proc dow y . ndow leap . +proc dow y &ndow &leap . leap = 0 - if y mod 4 = 0 - leap = 1 - . - if y mod 100 = 0 - leap = 0 - . - if y mod 400 = 0 - leap = 1 - . + if y mod 4 = 0 : leap = 1 + if y mod 100 = 0 : leap = 0 + if y mod 400 = 0 : leap = 1 ndow = y * 365 + y div 4 - y div 100 + y div 400 + 1 ndow = (ndow - leap) mod1 7 . len lin$[] 8 -proc prmonth nmonth newdow monsize . . +proc prmonth nmonth newdow monsize . lin$[1] &= " " & month$[nmonth] & " " lin$[2] &= wkdays$ & " " lin$[3] &= makewk 1 (8 - newdow) newdow & " " @@ -55,17 +47,13 @@ proc prmonth nmonth newdow monsize . . . . . -for i to pagewide - blank$ &= " " -. +for i to pagewide : blank$ &= " " dow year newdow leap print center "[ picture of Snoopy goes here ]" print center year for i = 1 to 12 monsize = days[i] - if i = 2 and leap = 1 - monsize = 29 - . + if i = 2 and leap = 1 : monsize = 29 prmonth i newdow monsize newdow = (monsize + newdow) mod1 7 . diff --git a/Task/Calkin-Wilf-sequence/C-sharp/calkin-wilf-sequence.cs b/Task/Calkin-Wilf-sequence/C-sharp/calkin-wilf-sequence.cs new file mode 100644 index 0000000000..c991ef30c3 --- /dev/null +++ b/Task/Calkin-Wilf-sequence/C-sharp/calkin-wilf-sequence.cs @@ -0,0 +1,48 @@ +IEnumerable Fusc() +{ + yield return 1; + var n = 1; + + foreach (var f in Fusc()) + { + yield return n + f; + yield return f; + n = f; + } +} + +IEnumerable ContFrac(int n, int d) +{ + while (d != 0) + { + yield return n / d; + (n, d) = (d, n % d); + } +} + +Console.WriteLine("First 20 terms of the Calkin-Wilf sequence:"); +var n = 1; + +foreach (var f in Fusc().Take(20)) +{ + Console.Write($"{n}/{f} "); + n = f; +} + +Console.WriteLine(); +var bits = 0L; +var bit = 1L; +var shift = 0; + +foreach (var c in ContFrac(83116, 51639)) +{ + for (var i = 0; i < c; i++) + { + bits |= bit << shift; + shift++; + } + + bit = 1 - bit; +} + +Console.WriteLine($"83116/51639 is at position {bits} in the sequence"); diff --git a/Task/Calkin-Wilf-sequence/EasyLang/calkin-wilf-sequence.easy b/Task/Calkin-Wilf-sequence/EasyLang/calkin-wilf-sequence.easy index 58bad99625..5ba9c6ad0d 100644 --- a/Task/Calkin-Wilf-sequence/EasyLang/calkin-wilf-sequence.easy +++ b/Task/Calkin-Wilf-sequence/EasyLang/calkin-wilf-sequence.easy @@ -1,7 +1,8 @@ subr first - n = 1 ; d = 1 + n = 1 + d = 1 . -proc next . . +proc next . n = 2 * (n div d) * d + d - n swap n d . diff --git a/Task/Call-a-function/EasyLang/call-a-function.easy b/Task/Call-a-function/EasyLang/call-a-function.easy index 7259ecaad6..08dbf24e42 100644 --- a/Task/Call-a-function/EasyLang/call-a-function.easy +++ b/Task/Call-a-function/EasyLang/call-a-function.easy @@ -3,7 +3,7 @@ func sqr n . . print sqr 3 # -proc divmod a b . q r . +proc divmod a b &q &r . q = a div b r = a mod b . diff --git a/Task/Camel-case-and-snake-case/JavaScript/camel-case-and-snake-case.js b/Task/Camel-case-and-snake-case/JavaScript/camel-case-and-snake-case.js new file mode 100644 index 0000000000..73b10c2641 --- /dev/null +++ b/Task/Camel-case-and-snake-case/JavaScript/camel-case-and-snake-case.js @@ -0,0 +1,82 @@ +const HYPHEN = '-'; +const SPACE = ' '; +const UNDERSCORE = '_'; +const WHITESPACE = " \n\r\t\f\v"; + +function leftTrim(text) { + const start = text.search(/\S/); // Find the index of the first non-whitespace character + return start === -1 ? "" : text.substring(start); +} + +function rightTrim(text) { + const end = text.search(/\S(?![\s\S]*\S)/); // Find the index of the last non-whitespace character + return end === -1 ? "" : text.substring(0, end + 1); +} + +function trim(text) { + return leftTrim(rightTrim(text)); +} + +function prepareForConversion(text) { + text = trim(text); + text = text.replace(new RegExp(SPACE, 'g'), UNDERSCORE); + text = text.replace(new RegExp(HYPHEN, 'g'), UNDERSCORE); + return text; // Return the modified text +} + +function toSnakeCase(camel) { + camel = prepareForConversion(camel); + let snake = ""; + let first = true; + for (const ch of camel) { + if (first) { + snake += ch; + first = false; + } else if (!first && ch >= 'A' && ch <= 'Z') { + if (snake.slice(-1) === UNDERSCORE) { + snake += ch.toLowerCase(); + } else { + snake += UNDERSCORE; + snake += ch.toLowerCase(); + } + } else { + snake += ch; + } + } + return snake; +} + +function toCamelCase(snake) { + snake = prepareForConversion(snake); + let camel = ""; + let underscore = false; + for (const ch of snake) { + if (ch === UNDERSCORE) { + underscore = true; + } else if (underscore) { + camel += ch.toUpperCase(); + underscore = false; + } else { + camel += ch; + } + } + return camel; +} + +function main() { + const variableNames = ["snakeCase", "snake_case", "variable_10_case", + "variable10Case", "ergo rE tHis", "hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", " spaces "]; + + console.log("".padEnd(48, " ") + "=== To snake_case ==="); + for (const text of variableNames) { + console.log("".padEnd(34, " ") + text + " --> " + toSnakeCase(text)); + } + + console.log("\n"); + console.log("".padEnd(48, " ") + "=== To camelCase ==="); + for (const text of variableNames) { + console.log("".padEnd(34, " ") + text + " --> " + toCamelCase(text)); + } +} + +main(); diff --git a/Task/Camel-case-and-snake-case/R/camel-case-and-snake-case.r b/Task/Camel-case-and-snake-case/R/camel-case-and-snake-case.r new file mode 100644 index 0000000000..bf208f540b --- /dev/null +++ b/Task/Camel-case-and-snake-case/R/camel-case-and-snake-case.r @@ -0,0 +1,56 @@ +library(stringr) + +test_strings <- c("snakeCase", "snake_case", "variable_10_case", "variable10Case", "ɛrgo rE tHis", + "hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", " spaces ") + +#Simple functions +snake2camel <- function(s){ + boundaries <- str_extract_all(s, "_+[^_]", simplify=TRUE) + boundaries <- str_replace_all(boundaries, "_", "") + for(b in boundaries){ + s <- str_replace_all(s, str_c("_+",b), str_to_upper(b)) + } + return(s) +} + +writeLines(c("Snake to camel case:", sapply(test_strings, camel2snake))) + +camel2snake <- function(s){ + boundaries <- str_extract_all(s, "[A-Z]", simplify=TRUE) + for(b in boundaries){ + s <- str_replace_all(s, b, str_c("_", str_to_lower(b))) + } + return(s) +} + +writeLines(c("Camel to snake case:", sapply(test_strings, camel2snake))) + +#More general functions +any2camel <- function(s){ + #strip leading and trailing whitespace + s <- str_replace_all(s, "^[\\h]+|[\\h]+$", "") + #Deal with specified separators + boundaries <- str_extract_all(s, "[ _-]+[^ _-]", simplify=TRUE) + boundaries <- str_replace_all(boundaries, "[ _-]", "") + for(b in boundaries){ + s <- str_replace_all(s, str_c("[ _-]+", b), str_to_upper(b)) + } + return(s) +} + +writeLines(c("Any separator to camel case:", sapply(test_strings, any2camel))) + +any2snake <- function(s){ + s <- str_replace_all(s, "^[\\h]+|[\\h]+$", "") + boundaries_camel <- str_extract_all(s, "[A-Z]", simplify=TRUE) + boundaries_other <- str_extract_all(s, "[ -]+", simplify=TRUE) + for(b in boundaries_camel){ + s <- str_replace_all(s, b, str_c("_", str_to_lower(b))) + } + for(b in boundaries_other){ + s <- str_replace_all(s, b, "_") + } + return(s) +} + +writeLines(c("Any separator to snake case:", sapply(test_strings, any2snake))) diff --git a/Task/Canonicalize-CIDR/ALGOL-68/canonicalize-cidr.alg b/Task/Canonicalize-CIDR/ALGOL-68/canonicalize-cidr.alg index 7befa0b1eb..6a3f49135f 100644 --- a/Task/Canonicalize-CIDR/ALGOL-68/canonicalize-cidr.alg +++ b/Task/Canonicalize-CIDR/ALGOL-68/canonicalize-cidr.alg @@ -1,22 +1,22 @@ BEGIN # show IPv4 addresses in CIDR notation in canonical form # # mode to hold an IPv4 address in CIDR notation # - MODE CIDR = STRUCT( BITS address - , INT network bits - , BOOL valid - , STRING error + MODE CIDR = STRUCT( LONG BITS address + , INT network bits + , BOOL valid + , STRING error ); # returns a CIDR parsed from address # OP TOCIDR = ( STRING address text )CIDR: BEGIN - STRING addr = "." + address text + "$"; - STRING error := ""; - BITS address := 16r0; - INT bits count := 0; - INT dot count := 0; - INT slash count := 0; - BOOL valid := TRUE; - INT s pos := LWB addr; - INT s max = UPB addr; + STRING addr = "." + address text + "$"; + STRING error := ""; + LONG BITS address := 16r0; + INT bits count := 0; + INT dot count := 0; + INT slash count := 0; + BOOL valid := TRUE; + INT s pos := LWB addr; + INT s max = UPB addr; WHILE s pos < s max AND valid DO IF addr[ s pos ] = "." THEN # must have an octet next # @@ -70,7 +70,7 @@ BEGIN # show IPv4 addresses in CIDR notation in canonical form # address ELSE # valid address - retain the top most bits # - CIDR( address OF address AND ( 16rffffffff + CIDR( address OF address AND ( LONG 16rffffffff SHL ( 32 - network bits OF address ) ) , network bits OF address @@ -82,9 +82,9 @@ BEGIN # show IPv4 addresses in CIDR notation in canonical form # OP TOSTRING = ( CIDR address )STRING: BEGIN [ 1 : 4 ]INT octet; - BITS addr := address OF address; + LONG BITS addr := address OF address; FOR o pos FROM UPB octet BY -1 TO LWB octet DO - octet[ o pos ] := ABS ( addr AND 16rff ); + octet[ o pos ] := SHORTEN ABS ( addr AND 16rff ); addr := addr SHR 8 OD; STRING result := whole( octet[ LWB octet ], 0 ); diff --git a/Task/Canonicalize-CIDR/Zig/canonicalize-cidr.zig b/Task/Canonicalize-CIDR/Zig/canonicalize-cidr.zig new file mode 100644 index 0000000000..7d5877d51d --- /dev/null +++ b/Task/Canonicalize-CIDR/Zig/canonicalize-cidr.zig @@ -0,0 +1,70 @@ +const std = @import("std"); + +const Ipv4Cidr = struct { + address: u32, + mask_length: u8, + + pub fn parse(s: []const u8) !Ipv4Cidr { + var split = std.mem.splitSequence(u8, s, "/"); + const addr_str = split.first(); + const mask_str = split.next() orelse return error.InvalidFormat; + if (split.next() != null) return error.InvalidFormat; + + var octets: [4]u8 = undefined; + var addr_split = std.mem.splitSequence(u8, addr_str, "."); + for (0..4) |i| { + const part = addr_split.next() orelse return error.InvalidFormat; + octets[i] = std.fmt.parseInt(u8, part, 10) catch return error.InvalidFormat; + } + if (addr_split.next() != null) return error.InvalidFormat; + + const address = (@as(u32, octets[0]) << 24) | + (@as(u32, octets[1]) << 16) | + (@as(u32, octets[2]) << 8) | + octets[3]; + + const mask_length = std.fmt.parseInt(u8, mask_str, 10) catch return error.InvalidFormat; + if (mask_length < 1 or mask_length > 32) return error.InvalidMask; + + const shift = @as(u5, @intCast(32 - mask_length)); + const mask = ~((@as(u32, 1) << shift) - 1); + const masked_address = address & mask; + + return Ipv4Cidr{ + .address = masked_address, + .mask_length = mask_length, + }; + } + + pub fn format( + self: Ipv4Cidr, + comptime _: []const u8, + _: std.fmt.FormatOptions, + writer: anytype, + ) !void { + const a = (self.address >> 24) & 0xFF; + const b = (self.address >> 16) & 0xFF; + const c = (self.address >> 8) & 0xFF; + const d = self.address & 0xFF; + try writer.print("{}.{}.{}.{}/{}", .{a, b, c, d, self.mask_length}); + } +}; + +pub fn main() !void { + const tests = [_][]const u8{ + "87.70.141.1/22", + "36.18.154.103/12", + "62.62.197.11/29", + "67.137.119.181/4", + "161.214.74.21/24", + "184.232.176.184/18", + }; + + for (tests) |my_test| { + const cidr = Ipv4Cidr.parse(my_test) catch |err| { + std.debug.print("{s}: invalid CIDR ({s})\n", .{my_test, @errorName(err)}); + continue; + }; + std.debug.print("{s:<18} -> {}\n", .{my_test, cidr}); + } +} diff --git a/Task/Cantor-set/EasyLang/cantor-set.easy b/Task/Cantor-set/EasyLang/cantor-set.easy index 61ccf82fa3..6e79ec59bb 100644 --- a/Task/Cantor-set/EasyLang/cantor-set.easy +++ b/Task/Cantor-set/EasyLang/cantor-set.easy @@ -1,9 +1,8 @@ -color 555 -proc cantor x y sz . . +gcolor 555 +proc cantor x y sz . if sz > 0.1 sz3 = sz / 3 - move x y - sz3 - rect sz sz3 + grect x y - sz3 sz sz3 cantor x y - sz3 sz3 cantor x + 2 * sz3 y - sz3 sz3 . diff --git a/Task/Carmichael-3-strong-pseudoprimes/EasyLang/carmichael-3-strong-pseudoprimes.easy b/Task/Carmichael-3-strong-pseudoprimes/EasyLang/carmichael-3-strong-pseudoprimes.easy index cbe08cb092..a1d4f5ee2a 100644 --- a/Task/Carmichael-3-strong-pseudoprimes/EasyLang/carmichael-3-strong-pseudoprimes.easy +++ b/Task/Carmichael-3-strong-pseudoprimes/EasyLang/carmichael-3-strong-pseudoprimes.easy @@ -1,14 +1,12 @@ func isprim num . i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 . -proc carmichael3 p1 . . +proc carmichael3 p1 . for h3 = 1 to p1 - 1 for d = 1 to h3 + p1 - 1 if (h3 + p1) * (p1 - 1) mod d = 0 and -p1 * p1 mod h3 = d mod h3 diff --git a/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes-1.rexx b/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes-1.rexx deleted file mode 100644 index 5eefc267eb..0000000000 --- a/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes-1.rexx +++ /dev/null @@ -1,42 +0,0 @@ -/*REXX program calculates Carmichael 3─strong pseudoprimes (up to and including N). */ -numeric digits 18 /*handle big dig #s (9 is the default).*/ -parse arg N .; if N=='' | N=="," then N=61 /*allow user to specify for the search.*/ -tell= N>0; N= abs(N) /*N>0? Then display Carmichael numbers*/ -#= 0 /*number of Carmichael numbers so far. */ -@.=0; @.2=1; @.3=1; @.5=1; @.7=1; @.11=1; @.13=1; @.17=1; @.19=1; @.23=1; @.29=1; @.31=1 - /*[↑] prime number memoization array. */ - do p=3 to N by 2; pm= p-1; bot=0; top=0 /*step through some (odd) prime numbers*/ - if \isPrime(p) then iterate; nps= -p*p /*is P a prime? No, then skip it.*/ - c.= 0 /*the list of Carmichael #'s (so far).*/ - do h3=2 for pm-1; g= h3 + p /*get Carmichael numbers for this prime*/ - npsH3= ((nps // h3) + h3) // h3 /*define a couple of shortcuts for pgm.*/ - gPM= g * pm /*define a couple of shortcuts for pgm.*/ - /* [↓] perform some weeding of D values*/ - do d=1 for g-1; if gPM // d \== 0 then iterate - if npsH3 \== d//h3 then iterate - q= 1 + gPM % d; if \isPrime(q) then iterate - r= 1 + p * q % h3; if q * r // pm \== 1 then iterate - if \isPrime(r) then iterate - #= # + 1; c.q= r /*bump Carmichael counter; add to array*/ - if bot==0 then bot= q; bot= min(bot, q); top= max(top, q) - end /*d*/ - end /*h3*/ - $= /*build list of some Carmichael numbers*/ - if tell then do j=bot to top by 2; if c.j\==0 then $= $ p"∙"j'∙'c.j - end /*j*/ - - if $\=='' then say 'Carmichael number: ' strip($) - end /*p*/ -say -say '──────── ' # " Carmichael numbers found." -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: parse arg x; if @.x then return 1 /*is X a known prime?*/ - if x<37 then return 0; if x//2==0 then return 0; if x// 3==0 then return 0 - parse var x '' -1 _; if _==5 then return 0; if x// 7==0 then return 0 - if x//11==0 then return 0; if x//13==0 then return 0; if x//17==0 then return 0 - if x//19==0 then return 0; if x//23==0 then return 0; if x//29==0 then return 0 - do k=29 by 6 until k*k>x; if x//k ==0 then return 0 - if x//(k+2) ==0 then return 0 - end /*k*/ - @.x=1; return 1 diff --git a/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes-2.rexx b/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes-2.rexx deleted file mode 100644 index 586ab2e701..0000000000 --- a/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes-2.rexx +++ /dev/null @@ -1,59 +0,0 @@ -include Settings - -say version; say 'Carmichael 3 strong primes'; say -arg n -numeric digits 16 -if n = '' then - n = 61 -show = (n > 0); n = Abs(n) -c = Carmichaels(n) -if show then do - do i = 1 to capr.0 - say capr.prime1.i 'x' capr.prime2.i 'x' capr.prime3.i '=', - capr.prime1.i * capr.prime2.i * capr.prime3.i - end -end -say c 'Carmichael numbers found up to first prime' n -say time('e') 'seconds' -exit - -Carmichaels: -/* Carmichael 3 strong prime numbers */ -procedure expose capr. -parse arg x -n = 0 -do p1 = 3 by 2 to x -/* Method Janeson */ - if \ Prime(p1) then - iterate p1 - pm = p1-1; ps = -p1*p1 - do h3 = 1 to pm - t1 = (h3+p1) * pm; t2 = ps//h3 - if t2 < 0 then - t2 = t2+h3 - do d = 1 to h3+pm - if t1//d <> 0 then - iterate d - if t2 <> d//h3 then - iterate d - p2 = 1+t1%d - if \ Prime(p2) then - iterate d - p3 = 1+(p1*p2%h3) - if \ Prime(p3) then - iterate d - if (p2*p3)//pm <> 1 then - iterate d -/* Save results */ - n = n+1 - capr.prime1.n = p1; capr.prime2.n = p2; capr.prime3.n = p3 - end d - end h3 -end -capr.0 = n -/* Return count */ -return n - -include Numbers -include Functions -include Abend diff --git a/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes.rexx b/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes.rexx new file mode 100644 index 0000000000..9cce219003 --- /dev/null +++ b/Task/Carmichael-3-strong-pseudoprimes/REXX/carmichael-3-strong-pseudoprimes.rexx @@ -0,0 +1,26 @@ +-- 22 Mar 2025 +include Settings + +say 'CARMICHAEL 3 STRONG PSEUDOPRIMES' +say version +say +arg n +numeric digits 16 +if n = '' then + n = 61 +show = (n > 0); n = Abs(n) +c = Carmichaels(n) +if show then do + do i = 1 to carm.0 + say carm.1.i 'x' carm.2.i 'x' carm.3.i '=', + carm.1.i * carm.2.i * carm.3.i + end +end +say c 'Carmichael numbers found up to first prime' n +say time('e') 'seconds' +exit + +include Sequences +include Numbers +include Functions +include Abend diff --git a/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists-1.cpp b/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists-1.cpp new file mode 100644 index 0000000000..39cb7169a1 --- /dev/null +++ b/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists-1.cpp @@ -0,0 +1,66 @@ +#include +#include +#include + +void print_inner(const std::vector &v) { + std::cout << "("; + auto it = v.begin(); + if (!v.empty()) { + std::cout << *it++; // Yield beginning value, then advance + } + for (; it != v.end(); ++it) { + std::cout << ", " << *it; + } + std::cout << ")"; +} + +void print(const std::vector > &v) { + std::cout << "["; + auto it = v.begin(); + if (!v.empty()) { + print_inner(*it++); // Yield beginning value, then advance + } + for (; it != v.end(); ++it) { + std::cout << ", "; + print_inner(*it); + } + std::cout << "]\n"; +} + +auto product(const std::vector > &lists) { + std::vector > result; + if (std::find_if(std::begin(lists), std::end(lists), + [](const auto &e) -> bool { return e.empty(); }) != std::end(lists)) { + return result; + } + for (auto &e: lists[0]) { + result.push_back({e}); + } + for (size_t i = 1; i < lists.size(); ++i) { + std::vector > temp; + for (const auto &e: result) { + for (auto f: lists[i]) { + auto e_tmp = e; + e_tmp.push_back(f); + temp.push_back(e_tmp); + } + } + result = temp; + } + return result; +} + +int main() { + std::vector > prods[] = { + {{1, 2}, {3, 4}}, + {{3, 4}, {1, 2}}, + {{1, 2}, {}}, + {{}, {1, 2}}, + {{1776, 1789}, {7, 12}, {4, 14, 23}, {0, 1}}, + {{1, 2, 3}, {30}, {500, 100}}, + {{1, 2, 3}, {}, {500, 100}} + }; + for (const auto &p: prods) { + print(product(p)); + } +} diff --git a/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists-2.cpp b/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists-2.cpp new file mode 100644 index 0000000000..2c22d76f01 --- /dev/null +++ b/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists-2.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +template +using a = std::array; + +template +using t = std::tuple; + +template +constexpr auto product(const t& inputs) { + const auto rng = std::apply(std::views::cartesian_product, inputs); + + std::println("{}", rng); +} + +int main() { + // The size of each list of arrays needs to be known at compile-time in order to use `cartesian_product()` + // However, each array is a different size, thus a distinct type, so we use a tuple to hold all of them + // The brace-initialized constructor cannot deduce the type of empty array, so we spell them out manually + constexpr auto prods = t{ + t{a{1, 2}, a{3, 4}}, + t{a{3, 4}, a{1, 2}}, + t{a{1, 2}, a{}}, + t{a{}, a{1, 2}}, + t{a{1776, 1789}, a{7, 12}, a{4, 14, 23}, a{0, 1}}, + t{a{1, 2, 3}, a{30}, a{500, 100}}, + t{a{1, 2, 3}, a{}, a{500, 100}} + }; + + std::apply([](const auto &... test_cases) { + (product(test_cases), ...); + }, prods); +} diff --git a/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists.cpp b/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists.cpp deleted file mode 100644 index e4a99032bd..0000000000 --- a/Task/Cartesian-product-of-two-or-more-lists/C++/cartesian-product-of-two-or-more-lists.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include - -void print(const std::vector>& v) { - std::cout << "{ "; - for (const auto& p : v) { - std::cout << "("; - for (const auto& e : p) { - std::cout << e << " "; - } - std::cout << ") "; - } - std::cout << "}" << std::endl; -} - -auto product(const std::vector>& lists) { - std::vector> result; - if (std::find_if(std::begin(lists), std::end(lists), - [](auto e) -> bool { return e.size() == 0; }) != std::end(lists)) { - return result; - } - for (auto& e : lists[0]) { - result.push_back({ e }); - } - for (size_t i = 1; i < lists.size(); ++i) { - std::vector> temp; - for (auto& e : result) { - for (auto f : lists[i]) { - auto e_tmp = e; - e_tmp.push_back(f); - temp.push_back(e_tmp); - } - } - result = temp; - } - return result; -} - -int main() { - std::vector> prods[] = { - { { 1, 2 }, { 3, 4 } }, - { { 3, 4 }, { 1, 2} }, - { { 1, 2 }, { } }, - { { }, { 1, 2 } }, - { { 1776, 1789 }, { 7, 12 }, { 4, 14, 23 }, { 0, 1 } }, - { { 1, 2, 3 }, { 30 }, { 500, 100 } }, - { { 1, 2, 3 }, { }, { 500, 100 } } - }; - for (const auto& p : prods) { - print(product(p)); - } - std::cin.ignore(); - std::cin.get(); - return 0; -} diff --git a/Task/Cartesian-product-of-two-or-more-lists/EasyLang/cartesian-product-of-two-or-more-lists.easy b/Task/Cartesian-product-of-two-or-more-lists/EasyLang/cartesian-product-of-two-or-more-lists.easy index 011a8d1706..0bef4f64ad 100644 --- a/Task/Cartesian-product-of-two-or-more-lists/EasyLang/cartesian-product-of-two-or-more-lists.easy +++ b/Task/Cartesian-product-of-two-or-more-lists/EasyLang/cartesian-product-of-two-or-more-lists.easy @@ -1,16 +1,10 @@ -proc cart2 a[] b[] . p[][] . - p[][] = [ ] - for a in a[] - for b in b[] - p[][] &= [ a b ] - . +func[][] cart a[] b[] . + for a in a[] : for b in b[] + p[][] &= [ a b ] . + return p[][] . -cart2 [ 1 2 ] [ 3 4 ] r[][] -print r[][] -cart2 [ 3 4 ] [ 1 2 ] r[][] -print r[][] -cart2 [ 1 2 ] [ ] r[][] -print r[][] -cart2 [ ] [ 1 2 ] r[][] -print r[][] +print cart [ 1 2 ] [ 3 4 ] +print cart [ 3 4 ] [ 1 2 ] +print cart [ 1 2 ] [ ] +print cart [ ] [ 1 2 ] diff --git a/Task/Cartesian-product-of-two-or-more-lists/M2000-Interpreter/cartesian-product-of-two-or-more-lists.m2000 b/Task/Cartesian-product-of-two-or-more-lists/M2000-Interpreter/cartesian-product-of-two-or-more-lists.m2000 new file mode 100644 index 0000000000..61a8c22897 --- /dev/null +++ b/Task/Cartesian-product-of-two-or-more-lists/M2000-Interpreter/cartesian-product-of-two-or-more-lists.m2000 @@ -0,0 +1,52 @@ +module checkit { + showTuple = lambda (a as array) -> { + k=lambda m=1 ->{ + shift 2 + if m=1 then + m=0:drop + push "("+array#str$(",")+")" + else + push letter$+",("+array#str$(",")+")" + end if + } + ="("+a#fold$(k)+")" + } + function cartesian_prod(a as array, b as array) { + rest=[] + aa=each(a) + while aa + bb=each(b) + while bb + data (array(aa), array(bb)) + end while + end while + ccc=(,) + if len(rest)>0 then + cc=each(rest) + while cc + ccc=stackitem(cc) + d=array([]) + dd=each(d) + while dd + ee=each(ccc) + while ee + data array(dd)#end((array(ee),)) + end while + end while + end while + end if + =array([]) + } + open "out.txt" for output as #f + print #f,"(1,2)x(3,4)=";showTuple(cartesian_prod((1,2), (3,4))) + print #f,"(3,4)x(1,2)=";showTuple(cartesian_prod((3,4), (1,2))) + print #f,"(1,2)x()=";showTuple(cartesian_prod((1,2), (,))) + print #f,"()x(1,2)=";showTuple(cartesian_prod((,), (1,2))) + print #f,"(1776,1789)x(7,12)x(4,14,23)x(0,1)=";showTuple(cartesian_prod((1776,1789), (7,12), (4,14,23), (0,1))) + print #f,"(1,2,3)x(30)x(500,100)=";showTuple(cartesian_prod((1,2,3), (30,), (500,100))) + print #f,"(1,2,3)x()x(500,100)=";showTuple(cartesian_prod((1,2,3), (,), (500,100))) + print #f,"(1,2,3)x(500,100)x()=";showTuple(cartesian_prod((1,2,3), (,), (500,100), (,))) + close #f + win notepad, dir$+"out.txt" +} +checkit diff --git a/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-1.rs b/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-1.rs index 9345a4ad79..4bde4f9f43 100644 --- a/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-1.rs +++ b/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-1.rs @@ -1,41 +1,42 @@ -fn cartesian_product(lists: &Vec>) -> Vec> { - let mut res = vec![]; +fn cartesian_product<'a, T>(lists: &[&'a [T]]) -> Vec> { + let mut res = vec![vec![]]; + + for &list in lists { + let mut tmp = Vec::new(); - let mut list_iter = lists.iter(); - if let Some(first_list) = list_iter.next() { - for &i in first_list { - res.push(vec![i]); - } - } - for l in list_iter { - let mut tmp = vec![]; for r in res { - for &el in l { - let mut tmp_el = r.clone(); - tmp_el.push(el); - tmp.push(tmp_el); + for item in list { + let mut r = r.clone(); + r.push(item); + tmp.push(r); } } + res = tmp; } + res } fn main() { - let cases = vec![ - vec![vec![1, 2], vec![3, 4]], - vec![vec![3, 4], vec![1, 2]], - vec![vec![1, 2], vec![]], - vec![vec![], vec![1, 2]], - vec![vec![1776, 1789], vec![7, 12], vec![4, 14, 23], vec![0, 1]], - vec![vec![1, 2, 3], vec![30], vec![500, 100]], - vec![vec![1, 2, 3], vec![], vec![500, 100]], + let cases: [&[&[u32]]; 7] = [ + &[&[1, 2], &[3, 4]], + &[&[3, 4], &[1, 2]], + &[&[1, 2], &[]], + &[&[], &[1, 2]], + &[&[1776, 1789], &[7, 12], &[4, 14, 23], &[0, 1]], + &[&[1, 2, 3], &[30], &[500, 100]], + &[&[1, 2, 3], &[], &[500, 100]], ]; + for case in cases { println!( "{}\n{:?}\n", - case.iter().map(|c| format!("{:?}", c)).collect::>().join(" × "), - cartesian_product(&case) + case.iter() + .map(|c| format!("{:?}", c)) + .collect::>() + .join(" × "), + cartesian_product(case) ) } } diff --git a/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-2.rs b/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-2.rs index c23d3c4ce3..88f569f91f 100644 --- a/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-2.rs +++ b/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-2.rs @@ -1,23 +1,2 @@ -fn cartesian_product(sets: &[Vec]) -> Vec> { - if sets.is_empty() { - return vec![vec![]]; - } - - let mut result = vec![vec![]]; - - for set in sets { - let mut temp = Vec::new(); - - for res in &result { - for item in set { - let mut new_res = res.clone(); - new_res.push(item.clone()); - temp.push(new_res); - } - } - - result = temp; - } - - result -} +[dependencies] +itertools = { version = "0.14.0", features = ["use_alloc"] } diff --git a/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-3.rs b/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-3.rs new file mode 100644 index 0000000000..e8d4eff8e3 --- /dev/null +++ b/Task/Cartesian-product-of-two-or-more-lists/Rust/cartesian-product-of-two-or-more-lists-3.rs @@ -0,0 +1,28 @@ +use itertools::{Itertools, MultiProduct}; + +fn cartesian_product<'a, T>(inputs: &[&'a [T]]) -> MultiProduct> { + inputs + .iter() + .map(|slice| slice.iter()) + .multi_cartesian_product() +} + +fn main() { + let cases: [&[&[u32]]; 7] = [ + &[&[1, 2], &[3, 4]], + &[&[3, 4], &[1, 2]], + &[&[1, 2], &[]], + &[&[], &[1, 2]], + &[&[1776, 1789], &[7, 12], &[4, 14, 23], &[0, 1]], + &[&[1, 2, 3], &[30], &[500, 100]], + &[&[1, 2, 3], &[], &[500, 1000]], + ]; + + for case in cases { + println!( + "{:?}\n[{:?}]\n", + case.iter().format(" × "), + cartesian_product(case).format(", ") + ); + } +} diff --git a/Task/Case-sensitivity-of-identifiers/Ballerina/case-sensitivity-of-identifiers.ballerina b/Task/Case-sensitivity-of-identifiers/Ballerina/case-sensitivity-of-identifiers.ballerina new file mode 100644 index 0000000000..6b87eea744 --- /dev/null +++ b/Task/Case-sensitivity-of-identifiers/Ballerina/case-sensitivity-of-identifiers.ballerina @@ -0,0 +1,8 @@ +import ballerina/io; + +public function main() { + string dog = "Benjamin"; + string Dog = "Samba"; + string DOG = "Bernie"; + io:println(`The three dogs are named ${dog}, ${Dog} and ${DOG}.`); +} diff --git a/Task/Catalan-numbers/EasyLang/catalan-numbers.easy b/Task/Catalan-numbers/EasyLang/catalan-numbers.easy index 6ec582b534..7c0b3976d0 100644 --- a/Task/Catalan-numbers/EasyLang/catalan-numbers.easy +++ b/Task/Catalan-numbers/EasyLang/catalan-numbers.easy @@ -1,9 +1,7 @@ func catalan n . - if n = 0 - return 1 - . + if n = 0 : return 1 return 2 * (2 * n - 1) * catalan (n - 1) div (1 + n) . for i = 0 to 14 - print catalan i + write catalan i & " " . diff --git a/Task/Catalan-numbers/REXX/catalan-numbers-1.rexx b/Task/Catalan-numbers/REXX/catalan-numbers-1.rexx index 64d93b2fb9..b523782cf9 100644 --- a/Task/Catalan-numbers/REXX/catalan-numbers-1.rexx +++ b/Task/Catalan-numbers/REXX/catalan-numbers-1.rexx @@ -1,23 +1,51 @@ -/*REXX program calculates and displays Catalan numbers using four different methods. */ -parse arg LO HI . /*obtain optional arguments from the CL*/ -if LO=='' | LO=="," then do; HI=15; LO=0; end /*No args? Then use a range of 0 ──► 15*/ -if HI=='' | HI=="," then HI=LO /*No HI? Then use LO for the default*/ -numeric digits max(20, 5*HI) /*this allows gihugic Catalan numbers. */ -w=length(HI) /*W: is used for aligning the output. */ -call hdr 1A; do j=LO to HI; say ' Catalan' right(j, w)": " Cat1A(j); end -call hdr 1B; do j=LO to HI; say ' Catalan' right(j, w)": " Cat1B(j); end -call hdr 2 ; do j=LO to HI; say ' Catalan' right(j, w)": " Cat2(j) ; end -call hdr 3 ; do j=LO to HI; say ' Catalan' right(j, w)": " Cat3(j) ; end -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -!: arg z; if !.z\==. then return !.z; !=1; do k=2 to z; !=!*k; end; !.z=!; return ! -Cat1A: procedure expose !.; parse arg n; return comb(n+n, n) % (n+1) -Cat1B: procedure expose !.; parse arg n; return !(n+n) % ((n+1) * !(n)**2) -Cat3: procedure expose c.; arg n; if c.n==. then c.n=(4*n-2)*cat3(n-1)%(n+1); return c.n -comb: procedure; parse arg x,y; return pFact(x-y+1, x) % pFact(2, y) -hdr: !.=.; c.=.; c.0=1; say; say center('Catalan numbers, method' arg(1),79,'─'); return -pFact: procedure; !=1; do k=arg(1) to arg(2); !=!*k; end; return ! -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Cat2: procedure expose c.; parse arg n; $=0; if c.n\==. then return c.n - do k=0 for n; $=$ + Cat2(k) * Cat2(n-k-1); end - c.n=$; return $ /*use a memoization technique.*/ +/* REXX --------------------------------------------------------------- +* 01.07.2014 Walter Pachl +*--------------------------------------------------------------------*/ +Numeric Digits 1000 +Parse Arg m . +If m='' Then m=20 +Do i=0 To m + c1.i=c1(i) + End +c2.=1 +Do i=1 To m + c2.i=c2(i) + End +c3.=1 +Do i=1 To m + im1=i-1 + c3.i=2*(2*i-1)*c3.im1/(i+1) + End +l=length(c3.m) +hdr=' n' right('c1.n',l), + right('c2.n',l), + right('c3.n',l) +Say hdr +Do i=0 To m + Say right(i,2) format(c1.i,l), + format(c2.i,l), + format(c3.i,l) + End +Say hdr +Exit + +c1: Procedure +Parse Arg n +return fact(2*n)/(fact(n)*fact(n+1)) + +c2: Procedure Expose c2. +Parse Arg n +res=0 +Do i=0 To n-1 + nmi=n-i-1 + res=res+c2.i*c2.nmi + End +Return res + +fact: Procedure +Parse Arg n +f=1 +Do i=1 To n + f=f*i + End +Return f diff --git a/Task/Catalan-numbers/REXX/catalan-numbers-2.rexx b/Task/Catalan-numbers/REXX/catalan-numbers-2.rexx index b523782cf9..16a319accc 100644 --- a/Task/Catalan-numbers/REXX/catalan-numbers-2.rexx +++ b/Task/Catalan-numbers/REXX/catalan-numbers-2.rexx @@ -1,51 +1,47 @@ -/* REXX --------------------------------------------------------------- -* 01.07.2014 Walter Pachl -*--------------------------------------------------------------------*/ -Numeric Digits 1000 -Parse Arg m . -If m='' Then m=20 -Do i=0 To m - c1.i=c1(i) - End -c2.=1 -Do i=1 To m - c2.i=c2(i) - End -c3.=1 -Do i=1 To m - im1=i-1 - c3.i=2*(2*i-1)*c3.im1/(i+1) - End -l=length(c3.m) -hdr=' n' right('c1.n',l), - right('c2.n',l), - right('c3.n',l) -Say hdr -Do i=0 To m - Say right(i,2) format(c1.i,l), - format(c2.i,l), - format(c3.i,l) - End -Say hdr -Exit +-- 22 Mar 2025 +include Settings -c1: Procedure -Parse Arg n -return fact(2*n)/(fact(n)*fact(n+1)) +say 'CATALAN NUMBERS' +say version +say +call GetCatalan 15 +call First 15 +call GetCatalan 10000 +call CalcCatalan 1000000,16 +exit -c2: Procedure Expose c2. -Parse Arg n -res=0 -Do i=0 To n-1 - nmi=n-i-1 - res=res+c2.i*c2.nmi - End -Return res +GetCatalan: +procedure expose cata. +call Time('r') +arg xx +say 'Get Catalan numbers up to the' xx'th with full precision...' +call Catalans(-xx-1) +say Format(Time('e'),,3) 'seconds'; say +return -fact: Procedure -Parse Arg n -f=1 -Do i=1 To n - f=f*i - End -Return f +First: +procedure expose cata. +call Time('r') +arg xx +say 'The first' xx 'Catalan numbers...' +do i = 0 to xx-1 + say 'C['i'] =' cata.i +end +say Format(Time('e'),,3) 'seconds'; say +return + +CalcCatalan: +procedure expose cata. +call Time('r') +arg xx,yy +say 'Calculate Catalan('xx') with' yy 'digits precision...' +numeric digits yy +say catalann(xx)+0 +say Format(Time('e'),,3) 'seconds'; say +return + +include Sequences +include Numbers +include Functions +include Constants +include Abend diff --git a/Task/Chaocipher/EasyLang/chaocipher.easy b/Task/Chaocipher/EasyLang/chaocipher.easy index 3d9af716be..f2eb029db7 100644 --- a/Task/Chaocipher/EasyLang/chaocipher.easy +++ b/Task/Chaocipher/EasyLang/chaocipher.easy @@ -1,8 +1,8 @@ -proc index c$ . a$[] ind . +func index a$[] c$ . for ind = 1 to len a$[] - if a$[ind] = c$ : return + if a$[ind] = c$ : return ind . - ind = 0 + return 0 . left$ = "HXUCZVAMDSLKPEFJRIGTWOBNYQ" right$ = "PTLNBQDEOYSFAVZKGJRIHWXUMC" @@ -13,11 +13,11 @@ func$ chao txt$ mode . len tmp$[] 26 for c$ in strchars txt$ if mode = 1 - index c$ right$[] ind + ind = index right$[] c$ if ind = 0 : return "" r$ &= left$[ind] else - index c$ left$[] ind + ind = index left$[] c$ if ind = 0 print c$ return "" diff --git a/Task/Chaos-game/EasyLang/chaos-game.easy b/Task/Chaos-game/EasyLang/chaos-game.easy index 80ec728f53..20f9411330 100644 --- a/Task/Chaos-game/EasyLang/chaos-game.easy +++ b/Task/Chaos-game/EasyLang/chaos-game.easy @@ -1,11 +1,10 @@ -color 900 +gcolor 900 x[] = [ 0 100 50 ] -y[] = [ 7 7 93 ] +y[] = [ 14 14 100 ] x = randomf * 100 y = randomf * 100 for i = 1 to 100000 - move x y - rect 0.3 0.3 + grect x y 0.3 0.3 h = random 3 x = (x + x[h]) / 2 y = (y + y[h]) / 2 diff --git a/Task/Character-codes/Ballerina/character-codes.ballerina b/Task/Character-codes/Ballerina/character-codes.ballerina new file mode 100644 index 0000000000..c16ce85fc2 --- /dev/null +++ b/Task/Character-codes/Ballerina/character-codes.ballerina @@ -0,0 +1,15 @@ +import ballerina/io; + +public function main() returns error? { + int[] cps = []; + foreach string c in ["a", "π", "字", "🐘"] { + int cp = c[0].toCodePointInt(); + cps.push(cp); + io:println(`${c} = ${cp}`); + } + io:println(); + foreach int i in cps { + var c = check string:fromCodePointInt(i); + io:println(`${i} = ${c}`); + } +} diff --git a/Task/Character-codes/Crystal/character-codes.cr b/Task/Character-codes/Crystal/character-codes.cr new file mode 100644 index 0000000000..5fb1cfa9e7 --- /dev/null +++ b/Task/Character-codes/Crystal/character-codes.cr @@ -0,0 +1,2 @@ +'Ω'.ord # => 937 +937.chr # => 'Ω' diff --git a/Task/Character-codes/M2000-Interpreter/character-codes.m2000 b/Task/Character-codes/M2000-Interpreter/character-codes.m2000 index f334be9e7a..2f909d53d2 100644 --- a/Task/Character-codes/M2000-Interpreter/character-codes.m2000 +++ b/Task/Character-codes/M2000-Interpreter/character-codes.m2000 @@ -7,16 +7,33 @@ Print ChrCode$(ChrCode("a")) \\ (,) is an empty array. -Function Codes(a$) { - If Len(A$)=0 then =(,) : Exit - Buffer Mem as byte*Len(a$) - \\ Str$(string) return one byte character - Return Mem, 0:=Str$(a$) - Inventory Codes - For i=0 to len(Mem)-1 - Append Codes, i:=Eval(Mem, i) - Next i - =Codes +Function Codes(a$, localeID=1033) { + If Len(A$)=0 then =(,) : Exit + \\ Str$(string) return one byte character + oldlocale=locale + locale localeID + a=Str$(a$) + locale oldlocale + Codes=(,) + locale 1033 + // 1 byte length returns 0.5 from len() ' 1 for 2 bytes. + // chr$(string) convert to UTF16LE with current LOCALE + For i=1 to len(a)*2 + Append Codes, (chrcode(chr$(mid$(a,i,1 as byte))),) + Next i + locale oldlocale + =Codes } -Print Codes("abcd") -\\ 97 98 99 100 +Print Codes("abcdΩ", 1032)#str$(", ") +\\ 97, 98, 99, 100, 217 + +Function CodesUNICODE(a) { + If Len(a)=0 then =(,) : Exit + Codes=(,) + For i=1 to len(a) + Append Codes, (chrcode(mid$(a,i,1)),) + Next i + =Codes +} +Print CodesUNICODE("abcdΩ")#str$(", ") +\\ 97, 98, 99, 100, 937 diff --git a/Task/Character-codes/OPL/character-codes.opl b/Task/Character-codes/OPL/character-codes.opl new file mode 100644 index 0000000000..05ff6d3090 --- /dev/null +++ b/Task/Character-codes/OPL/character-codes.opl @@ -0,0 +1,5 @@ +PROC main: + PRINT "a ->",ASC("a") + PRINT "97 ->",CHR$(97) + GET +ENDP diff --git a/Task/Character-codes/S-BASIC/character-codes.basic b/Task/Character-codes/S-BASIC/character-codes.basic new file mode 100644 index 0000000000..c3a772f23b --- /dev/null +++ b/Task/Character-codes/S-BASIC/character-codes.basic @@ -0,0 +1,14 @@ +var ch = char +var n = integer + +ch = 'a' +n = ch +print ch; " = "; n +print ch; " = "; asc(ch) + +n = 97 +ch = n +print n; " = "; ch +print n; " = "; chr$(n) + +end diff --git a/Task/Character-codes/Uxntal/character-codes.uxnatl b/Task/Character-codes/Uxntal/character-codes.uxnatl index 0429ace25f..f2fd52e587 100644 --- a/Task/Character-codes/Uxntal/character-codes.uxnatl +++ b/Task/Character-codes/Uxntal/character-codes.uxnatl @@ -1,26 +1,19 @@ -( uxnasm char-codes.tal char-codes.rom && uxncli char-codes.rom ) +%\n { 0a } +%newline { [ LIT2 \n -Console/write ] DEO } -|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1 -|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 +|18 @Console/write -|0100 - [ LIT "a ] print-hex - newline - #61 .Console/write DEO - newline +|100 + +[ LIT "a ] print/byte newline +#61 .Console/write DEO newline - ( exit ) - #80 .System/state DEO BRK -@print-hex - DUP #04 SFT print-digit #0f AND print-digit -JMP2r - -@print-digit - DUP #09 GTH #27 MUL ADD #30 ADD .Console/write DEO -JMP2r - -@newline - #0a .Console/write DEO -JMP2r +@print/byte ( byte -- ) + DUP #04 SFT /nibble + ( >> ) + +@print/nibble ( byte -- ) + #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD .Console/write DEO + JMP2r diff --git a/Task/Check-Machin-like-formulas/00-TASK.txt b/Task/Check-Machin-like-formulas/00-TASK.txt index d6db6e1191..c28978d512 100644 --- a/Task/Check-Machin-like-formulas/00-TASK.txt +++ b/Task/Check-Machin-like-formulas/00-TASK.txt @@ -35,7 +35,7 @@ These identities are useful in calculating the values:
You can store the equations in any convenient data structure, but for extra credit parse them from human-readable [[Check_Machin-like_formulas/text_equations|text input]]. -Note: to formally prove the formula correct, it would have to be shown that ''{-3 pi \over 4} < right hand side < {5 pi \over 4}'' due to ''\tan()'' periodicity. +Note: to formally prove the formula correct, it would have to be shown that ''{-3 \pi \over 4} < right hand side < {5 \pi \over 4}'' due to ''\tan()'' periodicity.

diff --git a/Task/Check-input-device-is-a-terminal/Lua/check-input-device-is-a-terminal.lua b/Task/Check-input-device-is-a-terminal/Lua/check-input-device-is-a-terminal.lua new file mode 100644 index 0000000000..53aa2d1991 --- /dev/null +++ b/Task/Check-input-device-is-a-terminal/Lua/check-input-device-is-a-terminal.lua @@ -0,0 +1,6 @@ +local posix = require"posix" +print( + posix.unistd.isatty(posix.stdio.fileno(io.stdin)) + and "stdin is a terminal" + or "stdin is not a terminal" +) diff --git a/Task/Check-that-file-exists/Lua/check-that-file-exists-3.lua b/Task/Check-that-file-exists/Lua/check-that-file-exists-3.lua new file mode 100644 index 0000000000..625b373fee --- /dev/null +++ b/Task/Check-that-file-exists/Lua/check-that-file-exists-3.lua @@ -0,0 +1,10 @@ +function Verify(filename) + print(filename + , os.rename(filename, filename) and "exists" or "void" + ) +end + +for _, v in ipairs{"input.txt","docs"} do + Verify("/" .. v) + Verify(v) +end diff --git a/Task/Chernicks-Carmichael-numbers/00-TASK.txt b/Task/Chernicks-Carmichael-numbers/00-TASK.txt index 24b0de17b9..328b8a9863 100644 --- a/Task/Chernicks-Carmichael-numbers/00-TASK.txt +++ b/Task/Chernicks-Carmichael-numbers/00-TASK.txt @@ -1,18 +1,18 @@ [[category:Prime Numbers]] -In 1939, Jack Chernick proved that, for '''n ≥ 3''' and '''m ≥ 1''': +In 1939, Jack Chernick proved that, for '''n \ge 3''' and '''m \ge 1''': - U(n, m) = (6m + 1) * (12m + 1) * Product_{i=1..n-2} (2^i * 9m + 1) + U(n, m) = (6m + 1) (12m + 1) \prod_{k=1}^{n-2} (2^k \, 9m + 1) -is a [https://en.wikipedia.org/wiki/Carmichael_number Carmichael number] if all the factors are primes and, for '''n > 4''', '''m''' is a multiple of '''2^(n-4)'''. +is a [https://en.wikipedia.org/wiki/Carmichael_number Carmichael number] if all the factors are primes and, for '''n > 4''', '''m''' is a multiple of '''2^{(n-4)}'''. ;Example - U(3, m) = (6m + 1) * (12m + 1) * (18m + 1) - U(4, m) = U(3, m) * (2^2 * 9m + 1) - U(5, m) = U(4, m) * (2^3 * 9m + 1) - ... - U(n, m) = U(n-1, m) * (2^(n-2) * 9m + 1) + U(3, m) = (6m + 1) (12m + 1) (18m + 1) + U(4, m) = U(3, m) (2^2 9m + 1) + U(5, m) = U(4, m) (2^3 9m + 1) + \cdots + U(n, m) = U(n-1, m) (2^{(n-2)} 9m + 1) * The smallest Chernick's Carmichael number with '''3''' prime factors, is: U(3, 1) = 1729. * The smallest Chernick's Carmichael number with '''4''' prime factors, is: U(4, 1) = 63973. @@ -42,7 +42,7 @@ For '''n ≥ 3''', let '''a(n)''' be the smallest Chernick's Carmichael number w ;See also -* [http://www.ams.org/journals/bull/1939-45-04/S0002-9904-1939-06953-X/S0002-9904-1939-06953-X.pdf Jack Chernick, On Fermat's simple theorem (PDF)] +* [http://www.ams.org/journals/bull/1939-45-04/S0002-9904-1939-06953-X/S0002-9904-1939-06953-X.pdf Jack Chernick, On Fermat's simple theorem (PDF)], equation (8) * [https://oeis.org/A318646 OEIS A318646: The least Chernick's "universal form" Carmichael number with n prime factors] diff --git a/Task/Chernicks-Carmichael-numbers/REXX/chernicks-carmichael-numbers.rexx b/Task/Chernicks-Carmichael-numbers/REXX/chernicks-carmichael-numbers.rexx index c85f58b9a7..12d100bc75 100644 --- a/Task/Chernicks-Carmichael-numbers/REXX/chernicks-carmichael-numbers.rexx +++ b/Task/Chernicks-Carmichael-numbers/REXX/chernicks-carmichael-numbers.rexx @@ -1,6 +1,8 @@ include Settings -say version; say 'Chernick''s Carmichael numbers'; say +say 'CHERNICKS'' CARMICHAEL NUMBERS - 3 Mar 2025' +say version +say numeric digits 80 say Copies('-',80) say 'n m(n) a(n)' diff --git a/Task/Chinese-remainder-theorem/EasyLang/chinese-remainder-theorem.easy b/Task/Chinese-remainder-theorem/EasyLang/chinese-remainder-theorem.easy index bd49a7065b..f5d8249052 100644 --- a/Task/Chinese-remainder-theorem/EasyLang/chinese-remainder-theorem.easy +++ b/Task/Chinese-remainder-theorem/EasyLang/chinese-remainder-theorem.easy @@ -1,4 +1,4 @@ -func mul_inv a b . +func mulinv a b . b0 = b x1 = 1 if b <> 1 @@ -11,25 +11,21 @@ func mul_inv a b . x0 = x1 - q * x0 x1 = t . - if x1 < 0 - x1 += b0 - . + if x1 < 0 : x1 += b0 . return x1 . -proc remainder . n[] a[] r . +func remainder &n[] &a[] . prod = 1 - sum = 0 for i = 1 to len n[] prod *= n[i] . for i = 1 to len n[] p = prod / n[i] - sum += a[i] * (mul_inv p n[i]) * p - r = sum mod prod + sum += a[i] * (mulinv p n[i]) * p . + return sum mod prod . n[] = [ 3 5 7 ] a[] = [ 2 3 2 ] -remainder n[] a[] h -print h +print remainder n[] a[] diff --git a/Task/Chinese-zodiac/EasyLang/chinese-zodiac.easy b/Task/Chinese-zodiac/EasyLang/chinese-zodiac.easy index 09078eb7fb..9ce1c61692 100644 --- a/Task/Chinese-zodiac/EasyLang/chinese-zodiac.easy +++ b/Task/Chinese-zodiac/EasyLang/chinese-zodiac.easy @@ -4,7 +4,7 @@ yingyang$[] = [ "Yang" "Yin" ] animal_ch$[] = strchars "子丑寅卯辰巳午未申酉戌亥" stem_ch$[] = strchars "甲乙丙丁戊己庚辛壬癸" # -proc get year . el$ an$ yy$ anch$ stch$ . +proc get year &el$ &an$ &yy$ &anch$ &stch$ . idx = (year - 4) mod 10 el$ = element$[idx div 2 + 1] stch$ = stem_ch$[idx + 1] @@ -13,7 +13,7 @@ proc get year . el$ an$ yy$ anch$ stch$ . anch$ = animal_ch$[idx + 1] yy$ = yingyang$[year mod 2 + 1] . -proc zodiac year . . +proc zodiac year . get year el$ an$ yy$ anch$ stch$ print year cycle = (year - 1983) mod1 60 diff --git a/Task/Chowla-numbers/ALGOL-68/chowla-numbers.alg b/Task/Chowla-numbers/ALGOL-68/chowla-numbers.alg index 641726dfd2..879053ae5c 100644 --- a/Task/Chowla-numbers/ALGOL-68/chowla-numbers.alg +++ b/Task/Chowla-numbers/ALGOL-68/chowla-numbers.alg @@ -1,4 +1,4 @@ -BEGIN # find some Chowla numbers ( Chowla n = sum of divisors of n exclusing n and 1 ) # +BEGIN # find some Chowla numbers ( Chowla n = sum of divisors of n excluding n and 1 ) # # returs the Chowla number of n # PROC chowla = ( INT n )INT: BEGIN diff --git a/Task/Chowla-numbers/Ada/chowla-numbers.ada b/Task/Chowla-numbers/Ada/chowla-numbers.ada index 8b9451b145..4f48ba270c 100644 --- a/Task/Chowla-numbers/Ada/chowla-numbers.ada +++ b/Task/Chowla-numbers/Ada/chowla-numbers.ada @@ -35,7 +35,7 @@ procedure Chowla_Numbers is Count := Count + 1; end if; if N mod Power = 0 then - Put_Line ("There is " & Count'Image & " primes < " & Power'Image); + Put_Line ("There are " & Count'Image & " primes < " & Power'Image); Power := Power * 10; end if; end loop; diff --git a/Task/Chowla-numbers/EasyLang/chowla-numbers.easy b/Task/Chowla-numbers/EasyLang/chowla-numbers.easy index 612642b535..3cecf7520f 100644 --- a/Task/Chowla-numbers/EasyLang/chowla-numbers.easy +++ b/Task/Chowla-numbers/EasyLang/chowla-numbers.easy @@ -1,5 +1,4 @@ fastfunc chowla n . - sum = 0 i = 2 while i * i <= n if n mod i = 0 @@ -14,7 +13,7 @@ fastfunc chowla n . . return sum . -proc sieve . c[] . +proc sieve &c[] . i = 3 while i * 3 <= len c[] if c[i] = 0 @@ -29,23 +28,22 @@ proc sieve . c[] . i += 2 . . -proc commatize n . s$ . +func$ comma n . s$[] = strchars n s$ = "" l = len s$[] for i = 1 to len s$[] - if i > 1 and l mod 3 = 0 - s$ &= "," - . + if i > 1 and l mod 3 = 0 : s$ &= "," l -= 1 s$ &= s$[i] . + return s$ . print "chowla number from 1 to 37" for i = 1 to 37 print " " & i & ": " & chowla i . -proc main . . +proc main . print "" len c[] 10000000 count = 1 @@ -53,13 +51,9 @@ proc main . . power = 100 i = 3 while i <= len c[] - if c[i] = 0 - count += 1 - . + if c[i] = 0 : count += 1 if i = power - 1 - commatize power p$ - commatize count c$ - print "There are " & c$ & " primes up to " & p$ + print "There are " & comma count & " primes up to " & comma power power *= 10 . i += 2 @@ -74,15 +68,13 @@ proc main . . p = k * kk until p > limit if chowla p = p - 1 - commatize p s$ - print s$ & " is a perfect number" + print comma p & " is a perfect number" count += 1 . k = kk + 1 kk += k i += 1 . - commatize limit s$ - print "There are " & count & " perfect mumbers up to " & s$ + print "There are " & count & " perfect mumbers up to " & comma limit . main diff --git a/Task/Chowla-numbers/REXX/chowla-numbers-1.rexx b/Task/Chowla-numbers/REXX/chowla-numbers-1.rexx deleted file mode 100644 index 54447064f1..0000000000 --- a/Task/Chowla-numbers/REXX/chowla-numbers-1.rexx +++ /dev/null @@ -1,29 +0,0 @@ -/*REXX program computes/displays chowla numbers (and may count primes & perfect numbers.*/ -parse arg LO HI . /*obtain optional arguments from the CL*/ -if LO=='' | LO=="," then LO= 1 /*Not specified? Then use the default.*/ -perf= LO<0; LO= abs(LO) /*Negative? Then determine if perfect.*/ -if HI=='' | HI=="," then HI= LO /*Not specified? Then use the default.*/ -prim= HI<0; HI= abs(HI) /*Negative? Then determine if a prime.*/ -numeric digits max(9, length(HI) + 1 ) /*use enough decimal digits for // */ -w= length( commas(HI) ) /*W: used in aligning output numbers.*/ -tell= \(prim | perf) /*set boolean value for showing chowlas*/ -p= 0 /*the number of primes found (so far).*/ - do j=LO to HI; #= chowla(j) /*compute the cholwa number for J. */ - if tell then say right('chowla('commas(j)")", w+9) ' = ' right( commas(#), w) - else if #==0 then if j>1 then p= p+1 - if perf then if j-1==# & j>1 then say right(commas(j), w) ' is a perfect number.' - end /*j*/ - -if prim & \perf then say 'number of primes found for the range ' commas(LO) " to " , - commas(HI) " (inclusive) is: " commas(p) -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -chowla: procedure; parse arg x; if x<2 then return 0; odd= x // 2 - s=0 /* [↓] use EVEN or ODD integers. ___*/ - do k=2+odd by 1+odd while k*k 2 - return 0 - . + if n mod 2 = 0 and n > 2 : return 0 i = 3 - sq = sqrt n - while i <= sq - if n mod i = 0 - return 0 - . + while i <= sqrt n + if n mod i = 0 : return 0 i += 2 . return 1 @@ -22,14 +17,10 @@ func cycle n . return m + n mod p * 10 . func circprime p . - if prime p = 0 - return 0 - . + if prime p = 0 : return 0 p2 = cycle p while p2 <> p - if p2 < p or prime p2 = 0 - return 0 - . + if p2 < p or prime p2 = 0 : return 0 p2 = cycle p2 . return 1 @@ -37,7 +28,7 @@ func circprime p . p = 2 while count < 19 if circprime p = 1 - print p + write p & " " count += 1 . p += 1 diff --git a/Task/Circular-primes/REXX/circular-primes-1.rexx b/Task/Circular-primes/REXX/circular-primes-1.rexx deleted file mode 100644 index 129443ee9a..0000000000 --- a/Task/Circular-primes/REXX/circular-primes-1.rexx +++ /dev/null @@ -1,37 +0,0 @@ -/*REXX program finds & displays circular primes (with a title & in a horizontal format).*/ -parse arg N hp . /*obtain optional arguments from the CL*/ -if N=='' | N=="," then N= 19 /* " " " " " " */ -if hp=='' | hp=="," then hip= 1000000 /* " " " " " " */ -call genP /*gen primes up to hp (200,000). */ -q= 024568 /*digs that most circular P can't have.*/ -found= 0; $= /*found: circular P count; $: a list.*/ - do j=1 until found==N; p= @.j /* [↓] traipse through all the primes.*/ - if p>9 & verify(p, q, 'M')>0 then iterate /*Does J contain forbidden digs? Skip.*/ - if \circP(p) then iterate /*Not circular? Then skip this number.*/ - found= found + 1 /*bump the count of circular primes. */ - $= $ p /*add this prime number ──► $ list. */ - end /*j*/ /*at this point, $ has a leading blank.*/ - -say center(' first ' found " circular primes ", 79, '─') -say strip($) -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -circP: procedure expose @. !.; parse arg x 1 ox /*obtain a prime number to be examined.*/ - do length(x)-1; parse var x f 2 y /*parse X number, rotating the digits*/ - x= y || f /*construct a new possible circular P. */ - if x 0 then iterate i b = a; l = Length(b) @@ -21,7 +24,7 @@ do i = 1 to p b = Right(b,l-1)||Left(b,1) if b < a then iterate i - if \ prime(b) then + if \ Prime(b) then iterate i end call Charout ,a' ' @@ -38,8 +41,8 @@ numeric digits 320 say 'Next 3 circular primes:' do i = 7 to 320 r = Repunit(i) - if prime(r) then - call charout ,'R('i') ' + if Prime(r) then + call Charout ,'R('i') ' end say say Format(Time('e'),,3) 'seconds' @@ -51,7 +54,7 @@ procedure expose glob. call Time('r') numeric digits 1040 say 'Primality of R(1031):' -if prime(Repunit(1031)) then +if Prime(Repunit(1031)) then say 'R(1031) is probable prime' else say 'R(1031) is composite' @@ -59,14 +62,8 @@ say Format(Time('e'),,3) 'seconds' say return -Repunit: -/* Repeat 1's function */ -procedure expose glob. -arg x -/* Formula */ -return Copies('1',x) - include Functions +include Special include Numbers include Sequences include Abend diff --git a/Task/Circular-primes/Scheme/circular-primes.scm b/Task/Circular-primes/Scheme/circular-primes.scm new file mode 100644 index 0000000000..a5cfdebbd1 --- /dev/null +++ b/Task/Circular-primes/Scheme/circular-primes.scm @@ -0,0 +1,82 @@ +(import srfi-1) + +; rotate list by n +(define (rotate lst n) + (if (> n 0) + (append (drop lst n) (take lst n)) + (append (take-right lst (abs n)) (drop-right lst (abs n))))) + + +; prime check +(define (prime? n) + (if (< n 4) (> n 1) + (and (odd? n) + (let loop ((k 3)) + (or (> (* k k) n) + (and (positive? (remainder n k)) + (loop (+ k 2)))))))) + +; returns number rotated in lists +(define (circ_lists lst) + (let + ( + (len (length lst)) + ) + (do ( + (remaining 1 (+ 1 remaining)) + (circs '() (cons (rotate lst remaining) circs )) + ) + ((< len remaining) circs) + ) + + ) +) + +; helper function to make number a list to rotate it +(define (number->list x) + (string->list (number->string x)) +) + +; returns list to number +(define (list->number x) + (string->number (list->string x)) +) + +; checks if number is prime when the number is turned into lists +(define (check x) + (not (member #f (map prime? (map list->number (circ_lists (number->list x)))))) + ) + +; all permutations of a number +(define (perms x) + (map list->number (circ_lists (number->list x))) +) + +(define limit 19) + +; checks if all permutations of x are not in lst +(define (not_perm x lst) + (equal? '() (filter-map (lambda (x) (not (equal? #f x))) + (map (lambda (x) (member x lst)) (perms x)))) + ) + + +(define (circular_primes x lst) + (cond + ( + (< (length lst) limit) + ; if is true if all permutations are prime and if all permutations are not already in the lst, which is returned + (if (and (equal? #t (check x)) (equal? #t (not_perm x lst))) + (circular_primes (+ x 1) (cons x lst)) + (circular_primes (+ x 1) lst) + ) + ) + ( + lst + ) + ) + ) + +(display (reverse (circular_primes 2 '()))) + +(newline) diff --git a/Task/Cistercian-numerals/Ada/cistercian-numerals-1.ada b/Task/Cistercian-numerals/Ada/cistercian-numerals-1.ada new file mode 100644 index 0000000000..87889f9cd1 --- /dev/null +++ b/Task/Cistercian-numerals/Ada/cistercian-numerals-1.ada @@ -0,0 +1,92 @@ +-- cistercian_numerals.adb +-- +-- test program for the Cistercian Representation Library +-- possibly overengineered in order to demonstrate use of types, +-- conditions, etc. +-- threw in some exception handling + +-- modern Ada +pragma Ada_2022; + +pragma Assertion_Policy (Check); + +-- imports + +with Ada.Text_IO; + +with Cistercian; +with Cistercian.Ascii; +with Cistercian.Ascii_Requirements; + +procedure Cistercian_Numerals is + + package IO renames Ada.Text_IO; + + Test_Values : constant array (1 .. 8) of Cistercian.Representable_Range := + [0, 1, 20, 300, 4_000, 5_555, 6_789, 1_983]; + -- test values required by task + User_Value : Integer; + -- value user requests + + Temp : Integer; + Dimension : Cistercian.Ascii_Requirements.Valid_Dimension; + +begin + + loop + begin + IO.Put_Line ("How large would you like your Cistercian numerals?"); + IO.Put_Line ("(You must supply an odd number greater than 5)"); + IO.Put ("> "); + Dimension := + Cistercian.Ascii_Requirements.Valid_Dimension'Value (IO.Get_Line); + -- kind of perplexed why I have to assert this + -- when the dynamic predicate should do so + pragma + Assert (Dimension in Cistercian.Ascii_Requirements.Valid_Dimension); + exit; + exception + when others => + IO.Put_Line ("You must supply an odd number greater than 5"); + end; + end loop; + + declare + package Cist_Ascii is new Cistercian.Ascii (Dimension); + begin + + -- first print test values + for Value of Test_Values loop + begin + IO.Put_Line + ("The Cistercian representation of" & Value'Image & " is:"); + Cist_Ascii.Put (Cistercian.From (Value)); + IO.New_Line; + exception + when others => + IO.Put_Line ("Hit an unrecoverable error. Terminating"); + return; + end; + end loop; + + -- now let user choose own values + loop + begin + IO.Put ("What other value would you like to see? "); + IO.Put_Line ("(enter a negative number to stop) "); + IO.Put ("? "); + User_Value := Integer'Value (IO.Get_Line); + Cist_Ascii.Put (Cistercian.From (User_Value)); + IO.New_Line; + exception + when others => + if User_Value < 0 then + exit; + end if; + IO.Put_Line ("Please enter a valid number from 0 to 9999."); + IO.Put ("? "); + end; + end loop; + end; + +end Cistercian_Numerals; diff --git a/Task/Cistercian-numerals/Ada/cistercian-numerals-2.ada b/Task/Cistercian-numerals/Ada/cistercian-numerals-2.ada new file mode 100644 index 0000000000..d2f8f44da9 --- /dev/null +++ b/Task/Cistercian-numerals/Ada/cistercian-numerals-2.ada @@ -0,0 +1,36 @@ +-- cistercian.ads +-- representations of Cistercian numbers + +package Cistercian is + + type Representation is private; + -- this type holds the Cistercian representation of a number + + subtype Representable_Range is Natural range 0 .. 9999; + -- the system only works with values in this range + + function From (Value : Representable_Range) return Representation; + -- converts `Value` to a `Representation` + + type Quadrant is (Ones, Tens, Hundreds, Thousands); + -- corresponds to the quadrants used by the system + + type Strokes_Enum is (Diag_From_Far, Diag_From_Near, Far, Near, Side); + -- corresponds to the line segments: + -- * Diag_From_Far corresponds to what you'll see in 3, 30, 300, 3000 + -- * Diag_From_Near corresponds to what you'll see in 4, 40, 400, 4000 + -- * Far corresponds to what you'll see in 1, 10, 100, 1000 + -- * Near corresponds to what you'll see in 2, 20, 200, 2000 + -- * Side corresponds to what you'll see in 6, 60, 600, 6000 + -- + -- the others are combinations of these + +private + + type Stroke_Used_Array is array (Strokes_Enum) of Boolean; + -- whether a stroke should be set + + type Representation is array (Quadrant) of Stroke_Used_Array; + -- indicates which quadrants' strokes are set + +end Cistercian; diff --git a/Task/Cistercian-numerals/Ada/cistercian-numerals-3.ada b/Task/Cistercian-numerals/Ada/cistercian-numerals-3.ada new file mode 100644 index 0000000000..1757bd50b3 --- /dev/null +++ b/Task/Cistercian-numerals/Ada/cistercian-numerals-3.ada @@ -0,0 +1,49 @@ +-- cistercian.adb + +pragma Ada_2022; + +package body Cistercian is + + subtype Digit_Range is Natural range 0 .. 9; + + Digit_Strokes : constant array (Digit_Range) of Stroke_Used_Array := + [0 => [others => False], + 1 => [Far => True, others => False], + 2 => [Near => True, others => False], + 3 => [Diag_From_Far => True, others => False], + 4 => [Diag_From_Near => True, others => False], + 5 => [Diag_From_Near => True, Far => True, others => False], + 6 => [Side => True, others => False], + 7 => [Far => True, Side => True, others => False], + 8 => [Near => True, Side => True, others => False], + 9 => [Far => True, Near => True, Side => True, others => False]]; + -- maps each digit to the corresponding strokes + -- this makes it easy for us to assign strokes later + + function From (Value : Representable_Range) return Representation is + -- converts Value to a Representation + Result : Representation; + + -- obtain digits, then... + + Ones_Digit : constant Digit_Range := Value rem 10; + Tens_Digit : constant Digit_Range := ((Value - Ones_Digit) / 10) rem 10; + Hund_Digit : constant Digit_Range := + ((Value - (Tens_Digit * 10 + Ones_Digit)) / 100) rem 10; + Thou_Digit : constant Digit_Range := + (Value - (Hund_Digit * 100 + Tens_Digit * 10 + Ones_Digit)) / 1000; + + begin + + -- assign strokes to corresponding quadrants + + Result (Ones) := Digit_Strokes (Ones_Digit); + Result (Tens) := Digit_Strokes (Tens_Digit); + Result (Hundreds) := Digit_Strokes (Hund_Digit); + Result (Thousands) := Digit_Strokes (Thou_Digit); + + return Result; + + end From; + +end Cistercian; diff --git a/Task/Cistercian-numerals/Ada/cistercian-numerals-4.ada b/Task/Cistercian-numerals/Ada/cistercian-numerals-4.ada new file mode 100644 index 0000000000..907571096b --- /dev/null +++ b/Task/Cistercian-numerals/Ada/cistercian-numerals-4.ada @@ -0,0 +1,54 @@ +-- cistercian-motion.ads +-- +-- details information on how to draw each Cistercian stroke +-- +-- this is fairly general, so it should be adaptable to any medium, +-- though we have adapted it only to ASCII + +pragma Ada_2022; + +with Cistercian; use Cistercian; + +package Cistercian.Motion is + type Start_Enum is (Near, Far); + -- whether the stroke starts near to or far from the center + + subtype Motion_Delta is Integer range -1 .. 1; + -- how the pen should step across the image in a given dimension + + type Motion_Record is record + -- record of a stroke's motion: + -- the location to start, as well as which direction to move + Col_Start, Row_Start : Start_Enum; + Col_Delta, Row_Delta : Motion_Delta; + end record; + + Stroke_Arrangement : + constant array (Quadrant, Cistercian.Strokes_Enum) of Motion_Record := + [Ones => + [Diag_From_Far => (Near, Far, 1, 1), + Diag_From_Near => (Near, Near, 1, -1), + Far => (Near, Far, 1, 0), + Near => (Near, Near, 1, 0), + Side => (Far, Far, 0, 1)], + Tens => + [Diag_From_Far => (Near, Far, -1, 1), + Diag_From_Near => (Far, Far, 1, 1), + Far => (Far, Far, 1, 0), + Near => (Far, Near, 1, 0), + Side => (Far, Far, 0, 1)], + Hundreds => + [Diag_From_Far => (Near, Far, 1, -1), + Diag_From_Near => (Near, Near, 1, 1), + Far => (Near, Far, 1, 0), + Near => (Near, Near, 1, 0), + Side => (Far, Near, 0, 1)], + Thousands => + [Diag_From_Far => (Far, Near, 1, 1), + Diag_From_Near => (Near, Near, -1, 1), + Far => (Far, Far, 1, 0), + Near => (Far, Near, 1, 0), + Side => (Far, Near, 0, 1)]]; + -- maps a quadrant-stoke pair to a motion + +end Cistercian.Motion; diff --git a/Task/Cistercian-numerals/Ada/cistercian-numerals-5.ada b/Task/Cistercian-numerals/Ada/cistercian-numerals-5.ada new file mode 100644 index 0000000000..6a0a804035 --- /dev/null +++ b/Task/Cistercian-numerals/Ada/cistercian-numerals-5.ada @@ -0,0 +1,9 @@ +-- cistercian-ascii_requirements.ads +-- +-- have to separate this because gnat requires only one compilation unit +-- per file + +package Cistercian.Ascii_Requirements is + subtype Valid_Dimension is Positive + with Static_Predicate => Valid_Dimension > 5; +end Cistercian.Ascii_Requirements; diff --git a/Task/Cistercian-numerals/Ada/cistercian-numerals-6.ada b/Task/Cistercian-numerals/Ada/cistercian-numerals-6.ada new file mode 100644 index 0000000000..75e07a62dc --- /dev/null +++ b/Task/Cistercian-numerals/Ada/cistercian-numerals-6.ada @@ -0,0 +1,54 @@ +-- cistercian-ascii.ads +-- ASCII printout of Cistercian representations +-- this is generic, so that you can make it as large as you like +-- (within reason) + +pragma Ada_2022; + +with Cistercian.Ascii_Requirements; + +generic + Dimension : Cistercian.Ascii_Requirements.Valid_Dimension := 7; +package Cistercian.Ascii is + + type Block (<>) is private; + -- as i understand it, this particular use of the discriminant + -- prevents the client from instantiating a `Block` without + -- going through one of our generator functions, + -- and the only one of those is `Zero` + + function Zero return Block; + -- returns a `Block` corresponding to 0; + -- i.e., a vertical line through the center + + function From (Value : Cistercian.Representation) return Block; + -- converts a Cistercian representation to an ASCII block + + procedure Put (Value : Cistercian.Representation); + -- print the value to standard output + +private + + Max : constant Integer := (Dimension - 1) / 2; + -- the maximum coordinate we can access in any one dimension + Mid : constant Integer := Max / 2 + 1; + -- midway to `Max`, natch + + subtype Cistercian_Ascii_Range is Integer range -(Max + 1) .. (Max + 1); + -- we leave some room for aesthetic reasons + -- (i had another reason originally, but i don't think it applies anymore) + + type Block is + array (Cistercian_Ascii_Range, Cistercian_Ascii_Range) of Boolean; + -- an entry should be True iff it should be painted in a stroke + + function Zero return Block + is + -- just a vertical line in the middle + ([for Row in Block'Range (1) + => [for Col in Block'Range (2) + => (if Col = 0 and then abs (Row) < Max + 1 + then True + else False)]]); + +end Cistercian.Ascii; diff --git a/Task/Cistercian-numerals/Ada/cistercian-numerals-7.ada b/Task/Cistercian-numerals/Ada/cistercian-numerals-7.ada new file mode 100644 index 0000000000..2bdc100450 --- /dev/null +++ b/Task/Cistercian-numerals/Ada/cistercian-numerals-7.ada @@ -0,0 +1,76 @@ +-- cistercian-ascii.adb + +pragma Ada_2022; + +with Ada.Text_IO; + +with Cistercian.Motion; + +package body Cistercian.Ascii is + + package IO renames Ada.Text_IO; + package CM renames Cistercian.Motion; + + function From (Value : Cistercian.Representation) return Block is + -- converts the representation to an ASCII block + + Result : Block := Zero; + + -- the extreme values for rows and columns, + -- as determine by where you want to start and which quadrant you're in + + Row_Extremes : + constant array (CM.Start_Enum, Quadrant) of Cistercian_Ascii_Range := + [CM.Far => [Ones | Tens => -Max, Hundreds | Thousands => Max], + CM.Near => [Ones | Tens => -1, Hundreds | Thousands => 1]]; + Col_Extremes : + constant array (CM.Start_Enum, Quadrant) of Cistercian_Ascii_Range := + [CM.Far => [Ones | Hundreds => Max, Tens | Thousands => -Max], + CM.Near => [Ones | Hundreds => 1, Tens | Thousands => -1]]; + + Row_Pos, Col_Pos : Cistercian_Ascii_Range; + Row_Delta, Col_Delta : CM.Motion_Delta; + + begin + + for Place in Quadrant loop + for Stroke in Cistercian.Strokes_Enum when Value (Place) (Stroke) loop + + -- obtain position and motion information + Row_Pos := + Row_Extremes + (CM.Stroke_Arrangement (Place, Stroke).Row_Start, Place); + Col_Pos := + Col_Extremes + (CM.Stroke_Arrangement (Place, Stroke).Col_Start, Place); + Row_Delta := CM.Stroke_Arrangement (Place, Stroke).Row_Delta; + Col_Delta := CM.Stroke_Arrangement (Place, Stroke).Col_Delta; + + -- make the stroke + for Ith in 1 .. Max loop + Result (Row_Pos, Col_Pos) := True; + Row_Pos := @ + Row_Delta; + Col_Pos := @ + Col_Delta; + end loop; + + end loop; + end loop; + + return Result; + + end From; + + procedure Put (Value : Cistercian.Representation) is + -- writes Value to standard output + X_At : constant Block := From (Value); + begin + + for Row in X_At'Range (1) loop + for Col in X_At'Range (2) loop + IO.Put ((if X_At (Row, Col) then 'X' else ' ')); + end loop; + IO.New_Line; + end loop; + end Put; + +end Cistercian.Ascii; diff --git a/Task/Cistercian-numerals/Applesoft-BASIC/cistercian-numerals.basic b/Task/Cistercian-numerals/Applesoft-BASIC/cistercian-numerals.basic new file mode 100644 index 0000000000..7d97acef9e --- /dev/null +++ b/Task/Cistercian-numerals/Applesoft-BASIC/cistercian-numerals.basic @@ -0,0 +1,6 @@ + 0 HGR : HCOLOR= 3: HOME : VTAB 21 : FOR I = 1 TO 8 : READ N$: N = VAL (N$): GOSUB 100: PRINT S$MID$ (" " + STR$ (N) + " ", VAL ( MID$ ("1223", LEN ( STR$ (N)),1)),4);: S$=" ":NEXT I : END: END : DATA0,1,20,300,4000,5555,6789,9080 + 100 N$ = RIGHT$ ("000" + STR$ (N),4):S = S + (S = 0) * 9:X = X + (X = 0) * (S + 4):Y = Y + (Y = 0) * (160 - S * 2):T = Y - S * 1.5:B = Y + S * 1.5: HPLOT X,T TO X,B TO X + 1,B TO X + 1,T + 110 FOR D = 1 TO 4:O = SGN (D - 2.5):A = VAL ( MID$ ("1331",D,1)) - 2:Y(0) = Y + S * 1.5 * A:Y(1) = Y + S * .5 * A:E$ = MID$ ("...1..2..3..4..14.6..16.26.126", VAL ( MID$ (N$,D,1)) * 3 + 1,3) + 120 FOR J = 1 TO 3:E = VAL ( MID$ (E$,J,1)): IF E THEN X1 = X + (S * O) * (E = 6):X2 = X + S * O:Y1 = Y( VAL ( MID$ ("0101.1",E,1))):Y2 = Y( VAL ( MID$ ("0110.0",E,1))): HPLOT X1,Y1 TO X2,Y2 TO X2 + 1,Y2 TO X1 + 1,Y1: NEXT J + 130 NEXT D:X = X + S * 4 - 1: IF X + S > 278 THEN X = S + 4:Y = Y + S * 4 + 140 RETURN diff --git a/Task/Cistercian-numerals/Crystal/cistercian-numerals.cr b/Task/Cistercian-numerals/Crystal/cistercian-numerals.cr new file mode 100644 index 0000000000..2ac7aadc41 --- /dev/null +++ b/Task/Cistercian-numerals/Crystal/cistercian-numerals.cr @@ -0,0 +1,96 @@ +def draw_cistercian_numerals (rows, *, size=20, decimals_size=0) + # characters are 2 units height, later scaled + hwidth = 0.888 # half width + line_width = 0.2 + hlw = line_width/2 + margin = line_width + scale = size/2 + interline = 0.2 + # top right quadrant is hwidth x -1. here are some distances from 0 + top = -1 + toph = top + hlw # center of top horizontal line + midv = -0.555 + bot = -0.111 + both = bot - hlw # center of bottom horizontal line + + # horizontal shift left for c3 & c4 + shift = hlw/Math.sin(Math.atan((top-bot).abs/(hwidth-hlw))) + + left = 0 # center of stem + leftx = hlw # right border of stem + midh = hwidth / 2 + right = hwidth + rightv = hwidth - hlw # center of right vertical line + + width = rows.max_of(&.size) * (2*hwidth + 2*margin) * scale + height = (rows.size * (2 + 2*margin) + (rows.size-1)*interline) * scale + + rows.size * decimals_size + + svg = String.build do |s| + s << <<-SVG << "\n" + + + + +SVG + # the digits' drawing instructions + digits = [[0,toph, 'H', right], # 1 + [0,midv, 'H', right], # 2 + [leftx-shift,top, 'L', right-shift,bot, 's'], # 3 + [leftx-shift,bot, 'L', right-shift,top, 's'], # 4 + [midh,midv, 'V', bot], # 5 + [midh,top, 'V', bot], # 6 + [0,toph, 'L', rightv,toph, rightv,bot], # 7 + [0,both, 'L', rightv,both, rightv,top], # 8 + [0,both, 'L', rightv,both, rightv,toph, 0,toph]] #9 + digits.map_with_index do |d, i| + s << %Q( \n) + end + s << "\n" + s << %Q(\n) + y = (2 + margin) * scale + rows.each do |row| + x = 0 + row.each do |number| + s << %Q( \n) + s << %Q( \n) + s << %Q( \n) + n = number + [nil, "scale(-1,1)", "rotate(180) scale(-1,1)", "rotate(180)"].each do |transform| + if n % 10 > 0 + s << %Q( \n" + end + n //= 10 + end + s << " \n \n" + if decimals_size > 0 + s << %Q( ) + s << %Q(#{number}\n) + end + x += (2*margin + 2*hwidth) * scale + end + y += (interline + 2*margin + 2) * scale + decimals_size + end + s << "\n" + end + puts svg +end + +draw_cistercian_numerals [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [20, 300, 4000, 5555, 6789, 1234, 6502, 2025, 8634, 5954], + (0..9).map { rand(10000) }], + size: 70, decimals_size: 18 diff --git a/Task/Cistercian-numerals/EasyLang/cistercian-numerals.easy b/Task/Cistercian-numerals/EasyLang/cistercian-numerals.easy index 766d24cc01..19b118bc31 100644 --- a/Task/Cistercian-numerals/EasyLang/cistercian-numerals.easy +++ b/Task/Cistercian-numerals/EasyLang/cistercian-numerals.easy @@ -1,5 +1,5 @@ -proc cist x y n . . - linewidth 0.5 +proc cist x y n . + glinewidth 0.5 dx[] = [ 4 -4 4 -4 ] dy[] = [ 4 4 -4 -4 ] for i to 4 @@ -8,43 +8,32 @@ proc cist x y n . . dy2 = 2 * dy d = n mod 10 n = n div 10 - move x y # - line x y + 8 - move x y - 8 - line x y + gline x y x y + 8 + gline x y - 8 x y if d = 1 - move x y + dy2 - line x + dx y + dy2 + gline x y + dy2 x + dx y + dy2 elif d = 2 - move x y + dy - line x + dx y + dy + gline x y + dy x + dx y + dy elif d = 3 - move x y + dy2 - line x + dx y + dy + gline x y + dy2 x + dx y + dy elif d = 4 - move x y + dy - line x + dx y + dy2 + gline x y + dy x + dx y + dy2 elif d = 5 - move x y + dy - line x + dx y + dy2 - line x y + dy2 + gline x y + dy x + dx y + dy2 + gline x + dx y + dy2 x y + dy2 elif d = 6 - move x + dx y + dy - line x + dx y + dy2 + gline x + dx y + dy x + dx y + dy2 elif d = 7 - move x y + dy2 - line x + dx y + dy2 - line x + dx y + dy + gline x y + dy2 x + dx y + dy2 + gline x + dx y + dy2 x + dx y + dy elif d = 8 - move x y + dy - line x + dx y + dy - line x + dx y + dy2 + gline x y + dy x + dx y + dy + gline x + dx y + dy x + dx y + dy2 elif d = 9 - move x y + dy - line x + dx y + dy - line x + dx y + dy2 - line x y + dy2 + gline x y + dy x + dx y + dy + gline x + dx y + dy x + dx y + dy2 + gline x + dx y + dy2 x y + dy2 . . x += 12 diff --git a/Task/Cistercian-numerals/FreeBASIC/cistercian-numerals.basic b/Task/Cistercian-numerals/FreeBASIC/cistercian-numerals.basic new file mode 100644 index 0000000000..d4fa35941d --- /dev/null +++ b/Task/Cistercian-numerals/FreeBASIC/cistercian-numerals.basic @@ -0,0 +1,95 @@ +Dim Shared As Byte dgs(0 To 9, 1 To 9, 0 To 2) +Dim As String c +Dim As Integer i, d + +Restore SegmentData +For d = 0 To 9 + For i = 1 To 9 + Read dgs(d, i, 0), dgs(d, i, 1), c + If c <> "" Then dgs(d, i, 2) = Asc(c) + Next +Next + +SegmentData: +Data 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 0 +Data 0,0,"+", 0,1,"-", 0,2,"-", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 1 +Data 2,0,"+", 2,1,"-", 2,2,"-", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 2 +Data 0,0,"+", 1,1,"\", 2,2,"\", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 3 +Data 2,0,"+", 1,1,"/", 0,2,"/", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 4 +Data 2,0,"+", 1,1,"/", 0,2,"+", 0,0,"+", 0,1,"-", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 5 +Data 0,2,"|", 1,2,"|", 2,2,"|", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 6 +Data 0,0,"+", 0,1,"-", 0,2,"+", 1,2,"|", 2,2,"|", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 7 +Data 2,0,"+", 2,1,"-", 2,2,"+", 1,2,"|", 0,2,"|", 0,0,"", 0,0,"", 0,0,"", 0,0,"" ' 8 +Data 2,0,"+", 2,1,"-", 2,2,"+", 1,2,"|", 0,2,"+", 0,1,"-", 0,0,"+", 0,0,"", 0,0,"" ' 9 + +Sub DrawDigit(canvas() As String, digit As Integer, position As Integer) + If digit < 0 Or digit > 9 Then Exit Sub + + Dim As Integer ud, lr, l, i + Select Case position + Case 1: ud = 1 : lr = 1 : l = 1 + Case 2: ud = 1 : lr = -1 : l = 1 + Case 3: ud = -1 : lr = 1 : l = 7 + Case 4: ud = -1 : lr = -1 : l = 7 + Case Else: Exit Sub + End Select + + For i = 1 To 9 + If dgs(digit, i, 0) = 0 And dgs(digit, i, 1) = 0 And dgs(digit, i, 2) = 0 Then Exit For + + Dim As Integer row = l + ud * dgs(digit, i, 0) + Dim As Integer col = 3 + lr * dgs(digit, i, 1) + Dim As String ch = Chr(dgs(digit, i, 2)) + + If Instr("/\", ch) Then + If ud <> lr Then + If ch = "/" Then + ch = "\" + Elseif ch = "\" Then + ch = "/" + End If + End If + End If + + If row >= 1 And row <= 7 And col >= 1 And col <= 5 Then Mid(canvas(row-1), col, 1) = Left(ch, 1) + Next +End Sub + +Sub ShowCistercianNumber(n As Integer) + Dim As Byte i + + Dim As String recanvas(0 To 7) + recanvas(0) = Right(" " & Str(n), 5) & ":" + Dim As String canvas(0 To 6) + For i = 0 To 6 + canvas(i) = " " + Mid(canvas(i), 3, 1) = "|" + Next + + Dim As Integer position = 1 + Dim As Integer tmp = n + + While tmp > 0 And position <= 4 + DrawDigit(canvas(), tmp Mod 10, position) + position += 1 + tmp \= 10 + Wend + + For i = 0 To 6 + recanvas(i+1) = canvas(i) + Next + + For i = 0 To 7 + Print recanvas(i) + Next +End Sub + +' Show example numbers +Dim As Integer nums(0 To 17) = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 300, 4000, 5555, 6789, 9394, 7922, 9999} + +For i = 0 To Ubound(nums) + ShowCistercianNumber(nums(i)) + Print +Next + +Sleep diff --git a/Task/Classes/Ballerina/classes.ballerina b/Task/Classes/Ballerina/classes.ballerina new file mode 100644 index 0000000000..5f7f119223 --- /dev/null +++ b/Task/Classes/Ballerina/classes.ballerina @@ -0,0 +1,28 @@ +import ballerina/io; + +class Dog { + string name; // field + + // Initializes a Dog instance passing it a name + // which is stored in the 'name' field. + function init(string name) { + self.name = name; + } + + // Function to make a noise. + function makeNoise() { + io:println("Woof!"); + } +} + +public function main() { + // Create a new Dog instance and assign a reference to it + // to the variable b. + Dog d = new Dog("Rover"); + + // Print the dog's name. + io:println("The dog is called ", d.name); + + // Make a noise. + d.makeNoise(); +} diff --git a/Task/Classes/Scheme/classes.scm b/Task/Classes/Scheme/classes.scm index ece399d954..dc5763eeef 100644 --- a/Task/Classes/Scheme/classes.scm +++ b/Task/Classes/Scheme/classes.scm @@ -1,3 +1,4 @@ +(define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) @@ -12,3 +13,13 @@ (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch) + +(define acc (make-account 100)) +((acc 'withdraw) 50) +50 +((acc 'withdraw) 60) +"Insufficient funds" +((acc 'deposit) 40) +90 +((acc 'withdraw) 60) +30 diff --git a/Task/Closest-pair-problem/EasyLang/closest-pair-problem.easy b/Task/Closest-pair-problem/EasyLang/closest-pair-problem.easy index d9ded104e7..013b09d2f5 100644 --- a/Task/Closest-pair-problem/EasyLang/closest-pair-problem.easy +++ b/Task/Closest-pair-problem/EasyLang/closest-pair-problem.easy @@ -1,5 +1,5 @@ # bruteforce -numfmt 4 0 +numfmt 0 4 x[] = [ 0.654682 0.409382 0.891663 0.716629 0.477721 0.925092 0.624291 0.211332 0.293786 0.839186 ] y[] = [ 0.925557 0.619391 0.888594 0.996200 0.946355 0.818220 0.142924 0.221507 0.691701 0.728260 ] n = len x[] diff --git a/Task/Closures-Value-capture/Crystal/closures-value-capture.cr b/Task/Closures-Value-capture/Crystal/closures-value-capture.cr new file mode 100644 index 0000000000..408a62a902 --- /dev/null +++ b/Task/Closures-Value-capture/Crystal/closures-value-capture.cr @@ -0,0 +1,6 @@ +closures = Array(-> Int32).new +(1..10).each do |i| + closures << ->{ i * i } +end + +puts closures[..-2].map(&.call).join(" ") diff --git a/Task/Color-of-a-screen-pixel/UNIX-Shell/color-of-a-screen-pixel.sh b/Task/Color-of-a-screen-pixel/UNIX-Shell/color-of-a-screen-pixel.sh new file mode 100644 index 0000000000..6fff9f2032 --- /dev/null +++ b/Task/Color-of-a-screen-pixel/UNIX-Shell/color-of-a-screen-pixel.sh @@ -0,0 +1 @@ +spectacle -nbo /dev/stdout 2>/dev/null | magick - txt:- | grep "^0,0" | awk '{ print $2 }' diff --git a/Task/Color-quantization/UNIX-Shell/color-quantization.sh b/Task/Color-quantization/UNIX-Shell/color-quantization.sh new file mode 100644 index 0000000000..0e9f4b1ef5 --- /dev/null +++ b/Task/Color-quantization/UNIX-Shell/color-quantization.sh @@ -0,0 +1 @@ +magick input.png -colors 16 out.png diff --git a/Task/Color-wheel/C/color-wheel.c b/Task/Color-wheel/C/color-wheel.c new file mode 100644 index 0000000000..8dee2a5a3a --- /dev/null +++ b/Task/Color-wheel/C/color-wheel.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +#define PI 3.14159265358979323846f + +typedef struct Vector2 { + float x, y; +} Vector2; + +// https://github.com/raysan5/raylib/blob/5aa3f0ccc374c1fbfc880402b37871b9c3bb7d8e/src/raymath.h#L316 +float vecdist(Vector2 v1, Vector2 v2) { return sqrtf((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y)); } + +// Packed because othervise compiler padd it with a zero. +// This breaks ppm format as it expects 3 bytes per pixel. +// Alternatively, if your compiler doesn't support __attribute__ you can remove it but +// then you will have to write every byte separately +typedef struct __attribute__((__packed__)) Color { + unsigned char r, g, b; +} Color; + +// Copied from +// https://github.com/raysan5/raylib/blob/5aa3f0ccc374c1fbfc880402b37871b9c3bb7d8e/src/rtextures.c#L4936 +// Hue is provided in degrees: [0..360] +// Saturation/Value are provided normalized: [0.0f..1.0f] +Color from_hsv(float hue, float saturation, float value) { + Color color = {0, 0, 0}; + + // Red channel + float k = fmodf((5.0f + hue / 60.0f), 6); + float t = 4.0f - k; + k = (t < k) ? t : k; + k = (k < 1) ? k : 1; + k = (k > 0) ? k : 0; + color.r = (unsigned char)((value - value * saturation * k) * 255.0f); + + // Green channel + k = fmodf((3.0f + hue / 60.0f), 6); + t = 4.0f - k; + k = (t < k) ? t : k; + k = (k < 1) ? k : 1; + k = (k > 0) ? k : 0; + color.g = (unsigned char)((value - value * saturation * k) * 255.0f); + + // Blue channel + k = fmodf((1.0f + hue / 60.0f), 6); + t = 4.0f - k; + k = (t < k) ? t : k; + k = (k < 1) ? k : 1; + k = (k > 0) ? k : 0; + color.b = (unsigned char)((value - value * saturation * k) * 255.0f); + + return color; +} + +int main(void) { + size_t img_size = 1000; + FILE *f = fopen("HSVWheel.ppm", "wb"); + if (!f) exit(69); + + // ppm header: + // "P6" - magic number that identifies format as binary with color, line break, space separated tuple with width and height of + // image in ASCII, line break, max value per color channel in ASCII, line break. + fprintf(f, "P6\n%lld %lld\n255\n", img_size, img_size); + + const size_t radius = img_size / 2; + const Vector2 center = {radius, radius}; + + // iterate over every pixel of image + for (size_t y = 0; y < img_size; ++y) { + for (size_t x = 0; x < img_size; ++x) { + // if distance from pixel to center of image - we inside of the colorwheel + float dist = vecdist(center, (Vector2){x, y}); + if (dist <= radius) { + // angle between x-axis and line from center to pixel in radians + // add PI/2 to rotate the hue by 90 degrees and have red on top + float angle = atan2f(y - center.y, x - center.x) + (PI / 2); + // normalize angle to be in range [0..2π] + if (angle < 0) angle += 2 * PI; + // convert from radian to degree + float hue = angle * (180 / PI); + // normalize distance to [0..1] range and use as saturation + float sat = dist / radius; + Color color = from_hsv(hue, sat, 1); + fwrite(&color, sizeof(Color), 1, f); + } else { + // Fill rest with background color + Color color = {0x1e, 0x1e, 0x1e}; + fwrite(&color, sizeof(Color), 1, f); + } + } + } + + // cleanup + fflush(f); + fclose(f); + return 0; +} diff --git a/Task/Color-wheel/EasyLang/color-wheel.easy b/Task/Color-wheel/EasyLang/color-wheel.easy index e540c2388c..f1ee8bbaa1 100644 --- a/Task/Color-wheel/EasyLang/color-wheel.easy +++ b/Task/Color-wheel/EasyLang/color-wheel.easy @@ -1,4 +1,4 @@ -proc hsb2rgb hue sat bri . r g b . +proc hsb2rgb hue sat bri &r &g &b . h = (hue - floor hue) * 6 f = h - floor h p = bri * (1 - sat) @@ -19,7 +19,7 @@ proc hsb2rgb hue sat bri . r g b . r = bri ; g = p ; b = q . . -proc cwheel . . +proc cwheel . for y = 0 to 499 dy = y - 250 for x = 0 to 499 @@ -29,9 +29,8 @@ proc cwheel . . theta = atan2 dy dx hue = (theta + 180) / 360 hsb2rgb hue (dist / 250) 1 r g b - color3 r g b - move x / 5 y / 5 - rect 0.3 0.3 + gcolor3 r g b + grect x / 5 y / 5 0.3 0.3 . . . diff --git a/Task/Color-wheel/Emacs-Lisp/color-wheel.l b/Task/Color-wheel/Emacs-Lisp/color-wheel.l new file mode 100644 index 0000000000..47aa9860bf --- /dev/null +++ b/Task/Color-wheel/Emacs-Lisp/color-wheel.l @@ -0,0 +1,75 @@ +(defun make-colors () + "Make a list of colors in RGB format." + (let ((red #xff) + (green #x0) + (blue #x0) + (colors)) + (while (<= green #xff) + (push (format "#%02x%02x%02x" red green blue) colors) + (setq green (+ green #x11))) + (setq green #xff) + (while (>= red #x0) + (push (format "#%02x%02x%02x" red green blue) colors) + (setq red (- red #x11))) + (setq red #x0) + (while (<= blue #xff) + (push (format "#%02x%02x%02x" red green blue) colors) + (setq blue (+ blue #x11))) + (setq blue #xff) + (while (>= green #x0) + (push (format "#%02x%02x%02x" red green blue) colors) + (setq green (- green #x11))) + (setq green #x0) + (while (<= red #xff) + (push (format "#%02x%02x%02x" red green blue) colors) + (setq red (+ red #x11))) + (reverse colors))) + +(defun sample-colors (sample-size colors) + "Get SAMPLE-SIZE number from COLORS" + (let* ((total-colors (length colors)) + (interval (/ (float (- total-colors 1)) (float (- sample-size 1)))) + (color-position-in-list 0) + (samples)) + (while (< color-position-in-list total-colors) + (push (nth (round color-position-in-list) colors) samples) + (setq color-position-in-list (+ interval color-position-in-list))) + samples)) + +(defun correct-y (reversed-y) + "Correct REVERSED-Y to work with Cartesian coordinates. +This function assumes that the y-axis size of the svg-create command +is 400. If it has another value, then the 400 below would need to be +changed. This function is necessary because svg has y axis values +increasing in a downward direction, the opposite of Cartesian +coordinates." + (- 400 reversed-y)) + +(defun plot-triangle (svg h k r angle1 angle2 fill-color) + "Create svg code for triangle inscribed in circle. +Circle center and one point of the triangle is located at point H and +K. Other two points of the triangle are on the circle +circumference. Radius of circle is R. ANGLE is angle in radians of point +on circle relative to the circle center." + (let ((x1) + (y1) + (x2) + (y2)) + (setq x1 (+ (* r (cos angle1)) h)) + (setq y1 (+ (* r (sin angle1)) k)) + (setq y1 (correct-y y1)) + (setq x2 (+ (* r (cos angle2)) h)) + (setq y2 (+ (* r (sin angle2)) k)) + (setq y2 (correct-y y2)) + (svg-polygon svg (list (cons x1 y1) (cons x2 y2) (cons h k)) :fill-color fill-color))) + +(defun color-wheel (number-of-colors) + "Create a color-wheel with NUMBER-OF-COLORS." + (let ((angle 0) + (portion-of-circle (/ (* 2 float-pi) number-of-colors)) + (colors (sample-colors number-of-colors (make-colors))) + (svg (svg-create 400 400 :stroke-width 0 :stroke-color "red"))) + (dolist (color colors) + (plot-triangle svg 200 200 200 angle (+ angle portion-of-circle) color) + (setq angle (+ angle portion-of-circle))) + (insert-image (svg-image svg)))) diff --git a/Task/Colorful-numbers/EasyLang/colorful-numbers.easy b/Task/Colorful-numbers/EasyLang/colorful-numbers.easy index 955b9009e6..a8af5cd6e4 100644 --- a/Task/Colorful-numbers/EasyLang/colorful-numbers.easy +++ b/Task/Colorful-numbers/EasyLang/colorful-numbers.easy @@ -5,13 +5,9 @@ func colorful n . m = n while m > 0 d = m mod 10 - if n > 9 and d <= 1 - return 0 - . + if n > 9 and d <= 1 : return 0 digcnt[d] += 1 - if digcnt[d] > 1 - return 0 - . + if digcnt[d] > 1 : return 0 ndigs += 1 digits[ndigs] = d m = m div 10 @@ -22,9 +18,7 @@ func colorful n . for j = i to ndigs p *= digits[j] for k to prodcnt - if products[k] = p - return 0 - . + if products[k] = p : return 0 . prodcnt += 1 products[prodcnt] = p @@ -36,14 +30,12 @@ len cnt[] 8 len used[] 10 arrbase used[] 0 largest = 0 -proc cnt_colorful taken n digits . . +proc cnt_colorful taken n digits . if taken = 0 for d = 0 to 9 used[d] = 1 h = 1 - if d < 2 - h = 9 - . + if d < 2 : h = 9 cnt_colorful h d 1 used[d] = 0 . diff --git a/Task/Colorful-numbers/JavaScript/colorful-numbers.js b/Task/Colorful-numbers/JavaScript/colorful-numbers.js new file mode 100644 index 0000000000..cab316dd25 --- /dev/null +++ b/Task/Colorful-numbers/JavaScript/colorful-numbers.js @@ -0,0 +1,85 @@ +function chunk_array(arr, n) { + const chunks = []; + + for (let i = 0; i < arr.length; i++) { + const sliced = arr.slice(i, i + n); + if (sliced.length == n) { + chunks.push(sliced); + } + } + + return chunks; +} + +function isColorful(num) { + const numArr = num.toString().split('').map(item => parseInt(item)); + + if (numArr.length == 1) { + return true; + } + + const count = {}; + + for (const num of numArr) { + const c = (count[num] || 0) + 1; + + if (c == 2) { + return false; + } + + count[num] = c; + } + + const prods = []; + + for(let i = 2; i < numArr.length+1; i++) { + const chunked = chunk_array(numArr, i); + for (const chunk of chunked) { + const prod = chunk.reduce((prev, val) => prev * val, 1); + + if (numArr.includes(prod) || prods.includes(prod)) { + return false; + } + prods.push(prod); + } + } + + return true; +} + + +const colorful = []; + +for(let i = 0; i < 100; i++) { + if (isColorful(i)) { + colorful.push(i); + } +} + +console.log(`Amount of colorful numbers lesser than 100 is ${colorful.length}`); +console.log(colorful); + +let isStart = true; +let maxColorful = 0; +let totalCount = 0; + +for (let i = 10; i < 1000000000; i *= 10) { + const colorful = []; + + for(let j = isStart ? 0 : (i / 10); j < i; j++) { + if (isColorful(j)) { + colorful.push(j); + maxColorful = Math.max(maxColorful, j); + } + } + + totalCount += colorful.length; + console.log(`The count of colorful numbers between ${isStart ? 0 : (i / 10)} and ${i-1} is ${colorful.length}`); + + if (isStart) { + isStart = false; + } +} + +console.log(`The largest possible colorful number is ${maxColorful}.`); +console.log(`The total number of colorful numbers is ${totalCount}.`); diff --git a/Task/Colour-bars-Display/EasyLang/colour-bars-display.easy b/Task/Colour-bars-Display/EasyLang/colour-bars-display.easy index 96cf380e59..dc02f8c6f6 100644 --- a/Task/Colour-bars-Display/EasyLang/colour-bars-display.easy +++ b/Task/Colour-bars-Display/EasyLang/colour-bars-display.easy @@ -1,7 +1,6 @@ col[] = [ 000 900 090 009 909 099 990 999 ] w = 100 / len col[] for i = 1 to len col[] - color col[i] - move w * (i - 1) 0 - rect w 100 + gcolor col[i] + grect w * (i - 1) 0 w 100 . diff --git a/Task/Colour-bars-Display/Python/colour-bars-display.py b/Task/Colour-bars-Display/Python/colour-bars-display-1.py similarity index 100% rename from Task/Colour-bars-Display/Python/colour-bars-display.py rename to Task/Colour-bars-Display/Python/colour-bars-display-1.py diff --git a/Task/Colour-bars-Display/Python/colour-bars-display-2.py b/Task/Colour-bars-Display/Python/colour-bars-display-2.py new file mode 100644 index 0000000000..2603946990 --- /dev/null +++ b/Task/Colour-bars-Display/Python/colour-bars-display-2.py @@ -0,0 +1,40 @@ +import pygame +import sys + +GLOBAL_WINDOW_SIZE = (640, 480) +COLOURS = ( + (0, 0, 0), + (255, 0, 0), + (0, 255, 0), + (0, 0, 255), + (255, 0, 255), + (0, 255, 255), + (255, 255, 0), + (255, 255, 255) +) + +def drawColouredStripes(surface): + stripeWidth = surface.get_width() // 8 + for i, col in enumerate(COLOURS): + pygame.draw.rect(surface, col, pygame.Rect(i*stripeWidth, 0, stripeWidth, surface.get_height())) + +pygame.init() + +if len(sys.argv) == 3: + newWindowSize = (int(sys.argv[1]), int(sys.argv[2])) + screen = pygame.display.set_mode(newWindowSize) +else: + screen = pygame.display.set_mode(GLOBAL_WINDOW_SIZE) + +running = True + +while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + drawColouredStripes(screen) + + pygame.display.flip() + +pygame.quit() diff --git a/Task/Colour-bars-Display/Uxntal/colour-bars-display.uxnatl b/Task/Colour-bars-Display/Uxntal/colour-bars-display.uxnatl index ae82d8a7db..18f094b457 100644 --- a/Task/Colour-bars-Display/Uxntal/colour-bars-display.uxnatl +++ b/Task/Colour-bars-Display/Uxntal/colour-bars-display.uxnatl @@ -1,29 +1,19 @@ -( uxnasm color-bars.tal color-bars.rom && uxnemu color-bars.rom ) +|00 @System [ &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 + &b $2 &debug $1 &state $1 ] -|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1 -|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 +|20 @Screen [ &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 + &addr $2 &pixel $1 &sprite $1 ] -|0100 - ( set 4 color theme - rgb - color0: 000 - black - color1: f00 - red - color2: 0f0 - green - color3: 00f - blue ) +|100 @Screen/on-reset ( -> ) #0f00 .System/r DEO2 #00f0 .System/g DEO2 #000f .System/b DEO2 - ( store bars width ) - .Screen/width DEI2 #0004 DIV2 ,&quarter STR2 - ( set starting position ) - #0000 .Screen/y DEO2 - ( draw bars ) - #00 + #8480 &loop - #00 OVR [ LIT2 &quarter $2 ] MUL2 - .Screen/x DEO2 - DUP #80 ORA .Screen/pixel DEO - INC DUP #04 NEQ ?&loop -BRK + DUP ./pixel DEO + ./x DEI2k ./width DEI2 #02 SFT2 ADD2 ROT DEO2 + INC GTHk ?/loop + + BRK diff --git a/Task/Colour-pinstripe-Display/EasyLang/colour-pinstripe-display.easy b/Task/Colour-pinstripe-Display/EasyLang/colour-pinstripe-display.easy index ed11ac98e6..562377a32c 100644 --- a/Task/Colour-pinstripe-Display/EasyLang/colour-pinstripe-display.easy +++ b/Task/Colour-pinstripe-Display/EasyLang/colour-pinstripe-display.easy @@ -3,9 +3,8 @@ for i = 1 to 4 col = 1 y = 100 - i * 25 for x = 0 step i to 100 - i - color k[col] - move x y - rect i 25 + gcolor k[col] + grect x y i 25 col = (col + 1) mod1 8 . . diff --git a/Task/Colour-pinstripe-Display/Uxntal/colour-pinstripe-display.uxnatl b/Task/Colour-pinstripe-Display/Uxntal/colour-pinstripe-display.uxnatl index 8f499e336d..6ec0726773 100644 --- a/Task/Colour-pinstripe-Display/Uxntal/colour-pinstripe-display.uxnatl +++ b/Task/Colour-pinstripe-Display/Uxntal/colour-pinstripe-display.uxnatl @@ -1,38 +1,42 @@ -( uxnasm color-pinstripe.tal color-pinstripe.rom && uxnemu color-pinstripe.rom ) +|00 @System [ &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 + &b $2 &debug $1 &state $1 ] -|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1 -|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 +|20 @Screen [ &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 + &addr $2 &pixel $1 &sprite $1 ] -|0100 - ( set theme ) - #0f00 .System/r DEO2 - #00f0 .System/g DEO2 - #000f .System/b DEO2 +|100 - ( store screen width ) - .Screen/width DEI2 ,draw-layer/width STR2 - ( store a quarter of the screen height ) - .Screen/height DEI2 #02 SFT2 ,&quarter-height STR2 +( set theme ) +#0f00 .System/r DEO2 +#00f0 .System/g DEO2 +#000f .System/b DEO2 - ( draw the four stripe layers ) - #00 - &loop ( -- ) - ( update y coordinate ) - #00 OVR [ LIT2 &quarter-height $2 ] MUL2 .Screen/y DEO2 - ( draw a layer ) - INCk draw-layer - ( do it four times ) - INC DUP #04 LTH ?&loop - POP BRK +( store screen width ) +.Screen/width DEI2 ,draw-layer/width STR2 +( store a quarter of the screen height ) +.Screen/height DEI2 #02 SFT2 ,/quarter-height STR2 + +( draw the four stripe layers ) +#00 +&loop + ( update y coordinate ) + #00 OVR [ LIT2 &quarter-height $2 ] MUL2 .Screen/y DEO2 + ( draw a layer ) + INCk draw-layer + ( do it four times ) + INC DUP #04 LTH ?/loop + POP + +BRK @draw-layer ( step -: ) ( extend step to short, create counter ) #00 SWP #0000 - &loop ( -- ) + &loop ( update x coordinate ) MUL2k .Screen/x DEO2 ( fill a region ) DUP #03 AND #80 ORA .Screen/pixel DEO ( loop until the end of the screen ) - INC2 MUL2k [ LIT2 &width $2 ] LTH2 ?&loop + INC2 MUL2k [ LIT2 &width $2 ] LTH2 ?/loop POP2 POP2 JMP2r diff --git a/Task/Combinations-with-repetitions/EasyLang/combinations-with-repetitions.easy b/Task/Combinations-with-repetitions/EasyLang/combinations-with-repetitions.easy index 0e2be62a85..12a4b06003 100644 --- a/Task/Combinations-with-repetitions/EasyLang/combinations-with-repetitions.easy +++ b/Task/Combinations-with-repetitions/EasyLang/combinations-with-repetitions.easy @@ -4,7 +4,7 @@ k = 2 len result[] k n_results = 0 # -proc output . . +proc output . n_results += 1 if len items$[] > 0 s$ = "" @@ -14,7 +14,7 @@ proc output . . print s$ . . -proc combine pos val . . +proc combine pos val . if pos > k output else diff --git a/Task/Combinations/EasyLang/combinations.easy b/Task/Combinations/EasyLang/combinations.easy index 3ac717f830..34c4b35b4d 100644 --- a/Task/Combinations/EasyLang/combinations.easy +++ b/Task/Combinations/EasyLang/combinations.easy @@ -2,7 +2,7 @@ n = 5 m = 3 len result[] m # -proc combinations pos val . . +proc combinations pos val . if pos > m print result[] return diff --git a/Task/Comma-quibbling/Crystal/comma-quibbling.cr b/Task/Comma-quibbling/Crystal/comma-quibbling.cr new file mode 100644 index 0000000000..c9464e6016 --- /dev/null +++ b/Task/Comma-quibbling/Crystal/comma-quibbling.cr @@ -0,0 +1,19 @@ +def comma_quibble (arr) + "{" + + case arr.size + when 0 + "" + when 1 + arr[0] + else + arr[..-2].join(", ") + " and #{arr[-1]}" + end + "}" +end + +[[] of String, # (No input words). + ["ABC"], + ["ABC", "DEF"], + ["ABC", "DEF", "G", "H"], +].each do |input| + puts comma_quibble(input) +end diff --git a/Task/Comma-quibbling/Elena/comma-quibbling-1.elena b/Task/Comma-quibbling/Elena/comma-quibbling-1.elena new file mode 100644 index 0000000000..3b7623d585 --- /dev/null +++ b/Task/Comma-quibbling/Elena/comma-quibbling-1.elena @@ -0,0 +1,23 @@ +import system'routines; +import extensions; +import extensions'text; + +public extension QuibbleOp : Array +{ + string quibble() + { + ^ self.zipBy( + self.Length.coundDown().selectBy::(n => n == self.Length ? EmptyString : (n == 1 ? " and " : ", ") ), + (word, prefix => prefix + word) + ) + .summarize(StringWriter.load("{")) + "}" + } +} + +public program() +{ + Console.printLine(new string[] { }.quibble()); + Console.printLine(new string[] { "ABC" }.quibble()); + Console.printLine(new string[] { "ABC", "ADF" }.quibble()); + Console.printLine(new string[] { "ABC", "DEF", "G", "H" }.quibble()) +} diff --git a/Task/Comma-quibbling/Elena/comma-quibbling-2.elena b/Task/Comma-quibbling/Elena/comma-quibbling-2.elena new file mode 100644 index 0000000000..af737461ae --- /dev/null +++ b/Task/Comma-quibbling/Elena/comma-quibbling-2.elena @@ -0,0 +1,31 @@ +import extensions; +import textgen; + +const string Script = "<={{=>for (var i := 0; i < self.Length; i := i + 1) { + if (i > 0) { + if (i == self.Length - 1) { + <= and => + } + else { + <=, => + } + }; + + <={self[i]}=> + }; <=}}=>"; + +public extension QuibbleOp : Array +{ + string quibble() + { + ^ self.generateFrom(Script); + } +} + +public program() +{ + Console.printLine(new string[] { }.quibble()); + Console.printLine(new string[] { "ABC" }.quibble()); + Console.printLine(new string[] { "ABC", "ADF" }.quibble()); + Console.printLine(new string[] { "ABC", "DEF", "G", "H" }.quibble()) +} diff --git a/Task/Command-line-arguments/AArch64-Assembly/command-line-arguments.aarch64 b/Task/Command-line-arguments/AArch64-Assembly/command-line-arguments-1.aarch64 similarity index 100% rename from Task/Command-line-arguments/AArch64-Assembly/command-line-arguments.aarch64 rename to Task/Command-line-arguments/AArch64-Assembly/command-line-arguments-1.aarch64 diff --git a/Task/Command-line-arguments/AArch64-Assembly/command-line-arguments-2.aarch64 b/Task/Command-line-arguments/AArch64-Assembly/command-line-arguments-2.aarch64 new file mode 100644 index 0000000000..134551fb07 --- /dev/null +++ b/Task/Command-line-arguments/AArch64-Assembly/command-line-arguments-2.aarch64 @@ -0,0 +1,26 @@ +.global _start +.text +_start: + mov x9, sp // move stack pointer to x9 + 0: ldr x0, [x9, #8]! // add 8 to x9, load long int value at x9 into x0 + cbz x0, 9f // if x0 is zero (null pointer) jump forward to 9: + bl writez // call our function that prints a null terminated string + adr x0, lfz // load address of lfz (line feed, zero) into x0 + bl writez // print it + b 0b // jump backward to label 0: + 9: mov x8, #93 // 93 is exit + mov x0, xzr // return (0); + svc #0 // syscall + // If using as a function in C declare it as +writez: // extern long writez(char *str); + mov x1, x0 // address of str needs to be in x1 for syscall + sub x0, x0, #1 // decrement x0, because the next statement increments it first. + 0: ldrb w2, [x0, #1]! // increment x0, load byte value at x0 in w2 + cbnz w2, 0b // if w2 is not zero jump back to 0: label + sub x2, x0, x1 // subtract x1 from x0, load into x2. length of str + mov x0, #1 // mov into x0 1. stdout + mov x8, #64 // mov into x8 64. write + svc #0 // syscall + ret // return from function. + // return value is number of characters written. +lfz: .byte 10, 0 // line feed (0x0a), zero (null character) diff --git a/Task/Commatizing-numbers/JavaScript/commatizing-numbers.js b/Task/Commatizing-numbers/JavaScript/commatizing-numbers.js new file mode 100644 index 0000000000..ab6c8185ab --- /dev/null +++ b/Task/Commatizing-numbers/JavaScript/commatizing-numbers.js @@ -0,0 +1,42 @@ +function contains(haystack, needle) { + return haystack.indexOf(needle) !== -1; +} + +function commatize(text, start_index = 0, step = 3, separator = ",") { + console.log("Before: " + text); + const size = text.length; + + for (let i = start_index; i < size; ++i) { + if (contains("123456789", text[i])) { + for (let j = i + 1; j <= size; ++j) { + if (j > size || !contains("0123456789", text[j])) { + for (let k = j - 1 - step; k >= i; k -= step) { + text = text.slice(0, k + 1) + separator + text.slice(k + 1); + } + break; + } + } + break; + } + } + + console.log(" After: " + text + "\n"); +} + +function main() { + commatize("pi=3.14159265358979323846264338327950288419716939937510582097494459231", 6, 5, " "); + commatize("The author has two Z$100000000000000 Zimbabwe notes (100 trillion)."); + commatize("\"-in Aus$+1411.8millions\""); + commatize("===US$0017440 millions=== (in 2000 dollars)"); + commatize("123.e8000 is pretty big."); + commatize("The land area of the earth is 57268900(29% of the surface) square miles."); + commatize("Ain't no numbers in this here words, nohow, no way, Jose."); + commatize("James was never known as 0000000007"); + commatize("Arthur Eddington wrote: I believe there are " + + "15747724136275002577605653961181555468044717914527116709366231425076185631031296" + + " protons in the universe."); + commatize(" $-140000±100 millions."); + commatize("6/9/1946 was a good year for some."); +} + +main(); diff --git a/Task/Comments/OPL/comments.opl b/Task/Comments/OPL/comments.opl new file mode 100644 index 0000000000..901aa3e30b --- /dev/null +++ b/Task/Comments/OPL/comments.opl @@ -0,0 +1,2 @@ +REM This is a comment. +PAUSE 20 REM Can be placed behind statements, too. diff --git a/Task/Comments/Uxntal/comments.uxnatl b/Task/Comments/Uxntal/comments.uxnatl new file mode 100644 index 0000000000..74169c1755 --- /dev/null +++ b/Task/Comments/Uxntal/comments.uxnatl @@ -0,0 +1,31 @@ +( + Print a hex byte to decimal. +) + +( macros ) +%\n { 0a } +%newline { [ LIT2 \n -Console/write ] DEO } + +( devices ) +|10 @Console/vector $2 &read $1 ( &pad is unused ) &pad $5 &write $1 &error $1 + +( main program ) +|100 + +@on-reset ( -> ) + #42 print/dec newline + BRK + +( library ) +@print/dec ( dec -- ) + DUP #64 DIV /dec/try + DUP #0a DIV /dec/try + ( >> ) + + &dec/num ( num -- ) + #0a DIVk MUL SUB [ LIT "0 ] ADD .Console/write DEO + JMP2r + + &dec/try ( num -- ) + DUP ?/dec/num + POP JMP2r diff --git a/Task/Compare-a-list-of-strings/EasyLang/compare-a-list-of-strings.easy b/Task/Compare-a-list-of-strings/EasyLang/compare-a-list-of-strings.easy index 86039c73d8..a451eb048b 100644 --- a/Task/Compare-a-list-of-strings/EasyLang/compare-a-list-of-strings.easy +++ b/Task/Compare-a-list-of-strings/EasyLang/compare-a-list-of-strings.easy @@ -1,22 +1,14 @@ -proc test s$[] . . +proc test s$[] . ident = 1 ascend = 1 for i = 2 to len s$[] h = strcmp s$[i] s$[i - 1] - if h <> 0 - ident = 0 - . - if h <= 0 - ascend = 0 - . + if h <> 0 : ident = 0 + if h <= 0 : ascend = 0 . print s$[] - if ident = 1 - print "all equal" - . - if ascend = 1 - print "ascending" - . + if ident = 1 : print "all equal" + if ascend = 1 : print "ascending" print "" . test [ "AA" "BB" "CC" ] diff --git a/Task/Compare-a-list-of-strings/M2000-Interpreter/compare-a-list-of-strings.m2000 b/Task/Compare-a-list-of-strings/M2000-Interpreter/compare-a-list-of-strings.m2000 index 14627c3e47..b02abbc166 100644 --- a/Task/Compare-a-list-of-strings/M2000-Interpreter/compare-a-list-of-strings.m2000 +++ b/Task/Compare-a-list-of-strings/M2000-Interpreter/compare-a-list-of-strings.m2000 @@ -37,3 +37,38 @@ Module CheckIt { Print LessThan(A$())=False } Checkit +MODULE UsingLambdaFunctionAndFold { + equ=LAMBDA ->{ + =LAMBDA p$, c=0 -> { + IF c=0 THEN + p$=LETTER$: PUSH 1=1 : c++ + ELSE + READ q$ + IF STACKITEM() THEN + DROP + PUSH p$=q$ + p$=q$ + END IF + END IF + } + } + LessThan=LAMBDA ->{ + =LAMBDA p$, c=0 -> { + IF c=0 THEN + p$=LETTER$: PUSH 1=1 : c++ + ELSE + READ q$ + IF STACKITEM() THEN + DROP + PUSH p$(#y)} +a:"aaa" +b:"ab" +comp[a;b] +length:{ (" the string " ,x, " has size ", ($#x), " the string " ,y, " has size " , ($#y))} +// if prints a first if a is longer +{$[comp[x;y];length[a;b];length[b;a]]}[a;b] +// extra credit +// just take each length and sort an array as usual +c:("abcd"; "123456789"; "abcdef"; "1234567") +c[<#'c] diff --git a/Task/Compare-length-of-two-strings/M2000-Interpreter/compare-length-of-two-strings-1.m2000 b/Task/Compare-length-of-two-strings/M2000-Interpreter/compare-length-of-two-strings-1.m2000 new file mode 100644 index 0000000000..263ccadf2a --- /dev/null +++ b/Task/Compare-length-of-two-strings/M2000-Interpreter/compare-length-of-two-strings-1.m2000 @@ -0,0 +1,47 @@ +MODULE COMPARE_STRING_LENGTH { + A = "I am string" + B = {I am string too} + PRINT A WORKS FOR EXPRESSIONS (-1,0,1) + PRINT A <=> B = -1 ' A { + PUSH STRING$("*",LEN(a$))+CHR$(9)+a$ +} +map2=lambda-> { + PUSH RIGHTPART$(LETTER$, CHR$(9)) +} +CLIPBOARD a#MAP(map1)#SORT(-1)#MAP(map2)#STR$() +PRINT CLIPBOARD$ +' like Python's advance solution +b=a#MAP(map1)#SORT(-1)#MAP(map2) +c=LEN(b)-1 +d=EACH(b) +WHILE d + PRINT QUOTE$(ARRAY$(d));" has length ";LEN(ARRAY$(d)); + IF d^=0 THEN + PRINT " and is the longest string" + ELSE.IF d^STRING$("S", STACK.SIZE) THEN ERROR "NO LIST OF STRINGS" + LOCAL a(1 TO STACK.SIZE, 2) + LOCAL c=1, i + WHILE NOT EMPTY + OVER ' double the top of stack of items + a(c, 0):=LEN(LETTER$), LETTER$ ' pass a row of values + c++ + END WHILE + c-- + LOCAL column=0, descending_type=1 + SORT a(), 1, c, column, descending_type + FOR i=1 to c + PRINT QUOTE$(a(i, 1));" has length ";a(i,0); + IF i=1 THEN + PRINT " and is the longest string" + ELSE.IF i=c THEN + PRINT " and is neither the longest nor the shortest string" + ELSE + PRINT " and is the shortest string" + END IF + NEXT + END SUB +} +Using2dArrayForSortStringsByLength diff --git a/Task/Compare-length-of-two-strings/OPL/compare-length-of-two-strings-1.opl b/Task/Compare-length-of-two-strings/OPL/compare-length-of-two-strings-1.opl new file mode 100644 index 0000000000..9a8062d239 --- /dev/null +++ b/Task/Compare-length-of-two-strings/OPL/compare-length-of-two-strings-1.opl @@ -0,0 +1,15 @@ +PROC main: + LOCAL string1$(7),string2$(4),length1%,length2% + string1$="Rosetta" + string2$="Code" + length1%=LEN(string1$) + length2%=LEN(string2$) + IF length1%>length2% + PRINT string1$,"(";length1%;")" + PRINT string2$,"(";length2%;")" + ELSE + PRINT string2$,"(";length2%;")" + PRINT string1$,"(";length1%;")" + ENDIF + GET +ENDP diff --git a/Task/Compare-length-of-two-strings/OPL/compare-length-of-two-strings-2.opl b/Task/Compare-length-of-two-strings/OPL/compare-length-of-two-strings-2.opl new file mode 100644 index 0000000000..c6d0e19da8 --- /dev/null +++ b/Task/Compare-length-of-two-strings/OPL/compare-length-of-two-strings-2.opl @@ -0,0 +1,47 @@ +PROC main: + LOCAL move%,id%,input$(20),store$(23),list$(5,23) + id%=1 + PRINT "Please enter five strings." + WHILE id%<6 + PRINT "String",id%;":", + INPUT input$ + IF LEN(GEN$(LEN(input$),2))=1 + list$(id%)="0"+GEN$(LEN(list$(id%)),1)+" "+list$(id%) + ELSE + list$(id%)=GEN$(LEN(list$(id%)),2)+" "+list$(id%) + ENDIF + id%=id%+1 + ENDWH + PRINT + id%=1 + move%=1 + DO + move%=0 + WHILE id%<6 + IF id%<>1 + IF list$(id%-1)5 + IF list$(id%+1)>list$(id%) + store$=list$(id%+1) + list$(id%+1)=list$(id%) + list$(id%)=store$ + move%=1 + ENDIF + ENDIF + id%=id%+1 + ENDWH + id%=1 + UNTIL move%=0 + id%=1 + WHILE id%<6 + PRINT list$(id%) + id%=id%+1 + ENDWH + GET +ENDP diff --git a/Task/Compare-length-of-two-strings/Scheme/compare-length-of-two-strings.scm b/Task/Compare-length-of-two-strings/Scheme/compare-length-of-two-strings.scm new file mode 100644 index 0000000000..0f28cd8822 --- /dev/null +++ b/Task/Compare-length-of-two-strings/Scheme/compare-length-of-two-strings.scm @@ -0,0 +1,47 @@ +; sorting for chicken +(import (chicken sort)) +; may need it in your scheme, when not included +(import srfi-1) +(define a "i am string") +(define b "i am string too") + +(string(arr: &mut [T]) { + let mut n = arr.len(); + let mut swapped = true; + + while swapped { + swapped = false; + + for i in 1..n { + if arr[i - 1] > arr[i] { + arr.swap(i - 1, i); + swapped = true; + } + } + + n -= 1; + } +} + +fn insertion_sort(arr: &mut [T]) { + for i in 1..arr.len() { + let mut j = i; + while j > 0 && arr[j] < arr[j - 1] { + arr.swap(j, j - 1); + j -= 1; + } + } +} + +fn quick_sort(arr: &mut [T]) { + if arr.len() >= 2 { + let pivot = partition(arr); + quick_sort(&mut arr[..pivot]); + quick_sort(&mut arr[pivot..]); + } +} + +/// In order to sort 100,000 integers without overflowing the stack, we use Hoare's partition scheme +/// which moves iterators from both ends of the slice towards the center until they cross. +/// This is especially effective for slicing sequences that are nearly/fully sorted. +fn partition(arr: &mut [T]) -> usize { + let pivot = arr[arr.len() / 2]; + + let mut i = 0; + let mut j = arr.len() - 1; + + loop { + while arr[i] < pivot { + i += 1; + } + while arr[j] > pivot { + j -= 1; + } + + if i >= j { + return i; + } + + arr.swap(i, j); + i += 1; + j -= 1; + } +} + +/// We are hard-coding the type for this example, since radix sorting on signed integers is a _bit_ +/// more complicated than needed here. +fn radix_sort(arr: &mut [u32]) { + let mut buf = vec![0; arr.len()]; + // Reduce the amount of iterations by finding the max value bit + let max_bits = u32::BITS - arr.iter().max().unwrap().leading_zeros(); + + for bit in 0..max_bits { + // Manual implementation of partition with only one buffer array + let mut a = 0; + let mut b = 0; + + for i in 0..arr.len() { + if arr[i] >> bit & 1 == 0 { + arr[a] = arr[i]; + a += 1; + } else { + buf[b] = arr[i]; + b += 1; + } + } + + arr[a..].copy_from_slice(&buf[..b]); + } +} + +fn shell_sort(arr: &mut [T]) { + // Marcin Ciura's gap sequence + for gap in [701, 301, 132, 57, 23, 10, 4, 1] { + for i in gap..arr.len() { + let temp = arr[i]; + let mut j = i; + while j >= gap && arr[j - gap] > temp { + arr[j] = arr[j - gap]; + j -= gap; + } + arr[j] = temp; + } + } +} + +fn rust_stable_sort(arr: &mut [T]) { + arr.sort(); +} + +fn rust_unstable_sort(arr: &mut [T]) { + arr.sort_unstable(); +} + +const ALGOS: [(&'static str, fn(&mut [u32])); 7] = [ + ("Bubble", bubble_sort), + ("Insert", insertion_sort), + ("Quick", quick_sort), + ("Radix", radix_sort), + ("Shell", shell_sort), + ("Drift", rust_stable_sort), + ("IPN", rust_unstable_sort), +]; diff --git a/Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-2.rs b/Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-2.rs new file mode 100644 index 0000000000..f09167cbea --- /dev/null +++ b/Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-2.rs @@ -0,0 +1,16 @@ +fn ones(len: u32) -> Vec { + vec![1; len as usize] +} + +fn sequence(len: u32) -> Vec { + (1..=len).collect() +} + +fn random(mut rng: &mut rand::rngs::ThreadRng, len: u32) -> Vec { + use rand::seq::SliceRandom; + + let mut seq = sequence(len); + seq.shuffle(&mut rng); + + seq +} diff --git a/Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-3.rs b/Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-3.rs new file mode 100644 index 0000000000..e2448e7713 --- /dev/null +++ b/Task/Compare-sorting-algorithms-performance/Rust/compare-sorting-algorithms-performance-3.rs @@ -0,0 +1,121 @@ +use core::error::Error; +use core::time::Duration; +use std::collections::BTreeMap; +use std::io::{Write, stdout}; +use std::time::Instant; + +fn run_time(f: fn(&mut [u32]), arr: &mut [u32]) -> Duration { + let start_time = Instant::now(); + f(arr); + start_time.elapsed() +} + +const LENGTHS: [u32; 30] = [ + 1, 2, 3, 4, 6, 10, 14, 21, 31, 46, 68, 100, 146, 215, 316, 464, 681, 1000, 1467, 2154, 3162, + 4641, 6812, 10000, 14677, 21544, 31622, 46415, 68129, 100000, +]; + +const IDC: [usize; 6] = [0, 5, 11, 17, 23, 29]; + +fn main() { + let mut rng = rand::rng(); + let mut metrics: [_; 3] = + core::array::from_fn(|_| BTreeMap::<&'static str, [Duration; 30]>::new()); + + for (i, len) in LENGTHS.iter().enumerate() { + print!("{len} "); + stdout().flush().unwrap(); + + let one = ones(*len); + let seq = sequence(*len); + let ran = random(&mut rng, *len); + + for (algo_name, algo) in ALGOS { + let (mut a, mut b, mut c) = (one.clone(), seq.clone(), ran.clone()); + + metrics[0].entry(algo_name).or_default()[i] = run_time(algo, &mut a); + metrics[1].entry(algo_name).or_default()[i] = run_time(algo, &mut b); + metrics[2].entry(algo_name).or_default()[i] = run_time(algo, &mut c); + + debug_assert!(a.is_sorted()); + debug_assert!(b.is_sorted()); + debug_assert!(c.is_sorted()); + } + } + println!("...Done"); + + println!( + "\n{:^20} {:>12?}", + "Data sizes", + [1, 10, 100, 1_000, 10_000, 100_000] + ); + println!("\n{:-^20}", "All Ones"); + for (algo_name, run_times) in &mut metrics[0] { + let powers_of_ten = run_times.get_disjoint_mut(IDC).unwrap(); + println!("{algo_name:^20} {powers_of_ten:>12?}"); + } + println!("\n{:-^20}", "Ascending"); + for (algo_name, run_times) in &mut metrics[1] { + let powers_of_ten = run_times.get_disjoint_mut(IDC).unwrap(); + println!("{algo_name:^20} {powers_of_ten:>12?}"); + } + println!("\n{:-^20}", "Random"); + for (algo_name, run_times) in &mut metrics[2] { + let powers_of_ten = run_times.get_disjoint_mut(IDC).unwrap(); + println!("{algo_name:^20} {powers_of_ten:>12?}"); + } + + let _ = plot("one", &metrics[0]); + let _ = plot("sequenced", &metrics[1]); + let _ = plot("random", &metrics[2]); +} + +fn plot(data_type: &str, map: &BTreeMap<&str, [Duration; 30]>) -> Result<(), Box> { + use plotters::prelude::*; + + let file_name = format!("{data_type}.png"); + let caption = format!("Sorting algorithms on {data_type} data"); + + let image = BitMapBackend::new(&file_name, (800, 600)).into_drawing_area(); + image.fill(&WHITE)?; + + let root = image.margin(10, 10, 10, 10); + let mut chart = ChartBuilder::on(&root) + .caption(caption, ("sans-serif", 24).into_font()) + .x_label_area_size(20) + .y_label_area_size(60) + .build_cartesian_2d((0..100_000).log_scale(), (0..10_000_000_000).log_scale())?; + + chart + .configure_mesh() + .x_desc("Data sizes") + .y_desc("Sort time") + .x_labels(10) + .y_labels(10) + .y_label_formatter(&|x| format!("{x:e} ns")) + .draw()?; + + for ((&algo_name, durations), color) in map + .iter() + .zip([MAGENTA, RED, GREEN, BLUE, YELLOW, CYAN, BLACK]) + { + let coordinates = durations + .iter() + .enumerate() + .map(|(i, duration)| (LENGTHS[i], duration.as_nanos() as i128)); + chart + .draw_series(LineSeries::new(coordinates, color))? + .label(algo_name) + .legend(move |(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], color)); + } + + chart + .configure_series_labels() + .background_style(WHITE.mix(0.8)) + .border_style(BLACK) + .draw()?; + + image.present()?; + + Ok(()) +} diff --git a/Task/Compiler-AST-interpreter/Rust/compiler-ast-interpreter.rs b/Task/Compiler-AST-interpreter/Rust/compiler-ast-interpreter.rs new file mode 100644 index 0000000000..f6d118b4c7 --- /dev/null +++ b/Task/Compiler-AST-interpreter/Rust/compiler-ast-interpreter.rs @@ -0,0 +1,400 @@ +use std::collections::HashMap; +use std::env; +use std::fs::File; +use std::io::{self, BufRead, BufReader, Lines}; +use std::process; + +// --- Data Structures --- + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum NodeType { + Ident, + String, + Integer, + Sequence, + If, + Prtc, + Prts, + Prti, + While, + Assign, + Negate, + Not, + Mul, + Div, + Mod, + Add, + Sub, + Lss, + Leq, + Gtr, + Geq, + Eql, + Neq, + And, + Or, +} + +#[derive(Debug, Clone)] +struct Tree { + node_type: NodeType, + // Use Option> for optional, heap-allocated children + left: Option>, + right: Option>, + // Store index for Ident/String or value for Integer + value: i32, +} + +// --- Global State Holder --- + +#[derive(Debug, Default)] +struct InterpreterContext { + string_pool: Vec, + global_names: Vec, + global_values: Vec, + // Cache for faster NodeType lookup + node_type_map: HashMap, +} + +impl InterpreterContext { + fn new() -> Self { + let mut map = HashMap::new(); + // Initialize the map from the static array + for &(text, node_type) in NODE_TYPE_MAPPING { + map.insert(text.to_string(), node_type); + } + InterpreterContext { + node_type_map: map, + ..Default::default() + } + } + + // Helper to get NodeType from string using the map + fn get_node_type(&self, name: &str) -> Option { + self.node_type_map.get(name).cloned() + } + + // Look up or add a string to the pool, return its index + fn fetch_string_offset(&mut self, st_literal: &str) -> Result { + if !st_literal.starts_with('"') || !st_literal.ends_with('"') { + return Err(format!("Invalid string literal format: {}", st_literal)); + } + // Trim quotes + let inner = &st_literal[1..st_literal.len() - 1]; + + // Basic escape sequence handling (\n, \\) + let mut processed = String::with_capacity(inner.len()); + let mut chars = inner.chars(); + while let Some(c) = chars.next() { + if c == '\\' { + match chars.next() { + Some('n') => processed.push('\n'), + Some('\\') => processed.push('\\'), + Some(other) => { + // Keep literal backslash and the following char if not recognized escape + processed.push('\\'); + processed.push(other); + } + None => return Err("String literal ends with dangling '\\'".to_string()), + } + } else { + processed.push(c); + } + } + + if let Some(pos) = self.string_pool.iter().position(|s| s == &processed) { + Ok(pos) + } else { + self.string_pool.push(processed); + Ok(self.string_pool.len() - 1) + } + } + + // Look up or add a variable name, return its index + fn fetch_var_offset(&mut self, name: &str) -> usize { + if let Some(pos) = self.global_names.iter().position(|n| n == name) { + pos + } else { + self.global_names.push(name.to_string()); + self.global_values.push(0); // Initialize new global variables to 0 + self.global_names.len() - 1 + } + } +} + +// --- Node Creation --- + +fn make_node(node_type: NodeType, left: Option>, right: Option>) -> Box { + Box::new(Tree { + node_type, + left, + right, + value: 0, // Default value, not used for non-leaf nodes + }) +} + +fn make_leaf(node_type: NodeType, value: i32) -> Box { + Box::new(Tree { + node_type, + left: None, + right: None, + value, + }) +} + +// --- Interpreter --- + +// Takes context mutably because assignment modifies global_values +fn interp(node: Option<&Box>, context: &mut InterpreterContext) -> i32 { + if node.is_none() { + return 0; // Interpret null node as 0 or do nothing + } + let node = node.unwrap(); // We know it's Some + + match node.node_type { + NodeType::Integer => node.value, + NodeType::Ident => { + // Access global_values using the index stored in node.value + // Provide a default value (e.g., 0) if index is somehow out of bounds, though fetch_var_offset should prevent this. + context.global_values.get(node.value as usize).cloned().unwrap_or_else(|| { + eprintln!("warning: Undefined variable accessed (index {})", node.value); + 0 + }) + } + NodeType::String => node.value, // Index into string_pool + + NodeType::Assign => { + // Left child must be an identifier leaf + let var_index = match node.left { + Some(ref left_node) if left_node.node_type == NodeType::Ident => left_node.value as usize, + _ => panic!("Assignment target must be an identifier"), + }; + let val_to_assign = interp(node.right.as_ref(), context); + if var_index < context.global_values.len() { + context.global_values[var_index] = val_to_assign; + } else { + // This should ideally not happen if fetch_var_offset works correctly + panic!("Assignment to invalid variable index {}", var_index); + } + val_to_assign // Assignment expression evaluates to the assigned value + } + + // Binary Operators + NodeType::Add => interp(node.left.as_ref(), context) + interp(node.right.as_ref(), context), + NodeType::Sub => interp(node.left.as_ref(), context) - interp(node.right.as_ref(), context), + NodeType::Mul => interp(node.left.as_ref(), context) * interp(node.right.as_ref(), context), + NodeType::Div => { + let right_val = interp(node.right.as_ref(), context); + if right_val == 0 { + eprintln!("error: Division by zero"); + process::exit(1); + } + interp(node.left.as_ref(), context) / right_val + } + NodeType::Mod => { + let right_val = interp(node.right.as_ref(), context); + if right_val == 0 { + eprintln!("error: Modulo by zero"); + process::exit(1); + } + interp(node.left.as_ref(), context) % right_val + } + NodeType::Lss => (interp(node.left.as_ref(), context) < interp(node.right.as_ref(), context)) as i32, + NodeType::Gtr => (interp(node.left.as_ref(), context) > interp(node.right.as_ref(), context)) as i32, + NodeType::Leq => (interp(node.left.as_ref(), context) <= interp(node.right.as_ref(), context)) as i32, + NodeType::Geq => (interp(node.left.as_ref(), context) >= interp(node.right.as_ref(), context)) as i32, + NodeType::Eql => (interp(node.left.as_ref(), context) == interp(node.right.as_ref(), context)) as i32, + NodeType::Neq => (interp(node.left.as_ref(), context) != interp(node.right.as_ref(), context)) as i32, + NodeType::And => (interp(node.left.as_ref(), context) != 0 && interp(node.right.as_ref(), context) != 0) as i32, + NodeType::Or => (interp(node.left.as_ref(), context) != 0 || interp(node.right.as_ref(), context) != 0) as i32, + + // Unary Operators + NodeType::Negate => -interp(node.left.as_ref(), context), + NodeType::Not => (interp(node.left.as_ref(), context) == 0) as i32, + + // Control Flow + NodeType::If => { + let condition = interp(node.left.as_ref(), context); + if condition != 0 { + // If branch is in right->left + interp(node.right.as_ref().and_then(|n| n.left.as_ref()), context); + } else { + // Else branch is in right->right + interp(node.right.as_ref().and_then(|n| n.right.as_ref()), context); + } + 0 // If statement doesn't return a value + } + NodeType::While => { + while interp(node.left.as_ref(), context) != 0 { + interp(node.right.as_ref(), context); + } + 0 // While loop doesn't return a value + } + + // Print Statements + NodeType::Prtc => { + let val = interp(node.left.as_ref(), context); + // Attempt to print as char, handle potential errors + if let Some(c) = std::char::from_u32(val as u32) { + print!("{}", c); + } else { + eprintln!("warning: Prtc value {} cannot be represented as char", val); + } + io::Write::flush(&mut io::stdout()).expect("Could not flush stdout"); + 0 + } + NodeType::Prti => { + print!("{}", interp(node.left.as_ref(), context)); + io::Write::flush(&mut io::stdout()).expect("Could not flush stdout"); + 0 + } + NodeType::Prts => { + let string_index = interp(node.left.as_ref(), context) as usize; + if let Some(s) = context.string_pool.get(string_index) { + print!("{}", s); + io::Write::flush(&mut io::stdout()).expect("Could not flush stdout"); + } else { + eprintln!("warning: Prts invalid string index {}", string_index); + } + 0 + } + + // Sequencing + NodeType::Sequence => { + interp(node.left.as_ref(), context); // Evaluate left side effect + interp(node.right.as_ref(), context); // Evaluate right side effect + 0 // Sequence doesn't return a value + } + } +} + +// --- Parser --- + +// Map C enum names to Rust NodeType enum +// Stored statically for efficiency +static NODE_TYPE_MAPPING: &[(&str, NodeType)] = &[ + ("Identifier", NodeType::Ident), + ("String", NodeType::String), + ("Integer", NodeType::Integer), + ("Sequence", NodeType::Sequence), + ("If", NodeType::If), + ("Prtc", NodeType::Prtc), + ("Prts", NodeType::Prts), + ("Prti", NodeType::Prti), + ("While", NodeType::While), + ("Assign", NodeType::Assign), + ("Negate", NodeType::Negate), + ("Not", NodeType::Not), + ("Multiply", NodeType::Mul), // Changed from C + ("Divide", NodeType::Div), // Changed from C + ("Mod", NodeType::Mod), + ("Add", NodeType::Add), + ("Subtract", NodeType::Sub), // Changed from C + ("Less", NodeType::Lss), // Changed from C + ("LessEqual", NodeType::Leq), + ("Greater", NodeType::Gtr), // Changed from C + ("GreaterEqual", NodeType::Geq), + ("Equal", NodeType::Eql), // Changed from C + ("NotEqual", NodeType::Neq), + ("And", NodeType::And), + ("Or", NodeType::Or), +]; + +// Helper function to report errors and exit +fn report_error(message: &str) -> Result { + Err(message.to_string()) +} + + +// Recursive function to load the AST from the input lines +fn load_ast( + lines: &mut Lines, + context: &mut InterpreterContext, +) -> Result>, String> { + match lines.next() { + None => Ok(None), // End of input + Some(line_result) => { + let line = line_result.map_err(|e| format!("IO Error reading line: {}", e))?; + let trimmed_line = line.trim(); + + // Skip comments and empty lines + if trimmed_line.is_empty() || trimmed_line.starts_with(';') { + return load_ast(lines, context); // Read next line + } + + // Split into tokens (NodeType and optional data) + let mut parts = trimmed_line.splitn(2, ' '); + let node_type_str = parts.next().ok_or("Line is unexpectedly empty after trim")?; + let data_part = parts.next().map(|s| s.trim()).filter(|s| !s.is_empty()); + + // Get the NodeType enum variant + let node_type = context + .get_node_type(node_type_str) + .ok_or_else(|| format!("Unknown node type token: {}", node_type_str))?; + + // If there's data, it's a leaf node + if let Some(data) = data_part { + let value = match node_type { + NodeType::Ident => context.fetch_var_offset(data) as i32, + NodeType::Integer => data.parse::() + .map_err(|_| format!("Invalid integer literal: {}", data))?, + NodeType::String => context.fetch_string_offset(data)? as i32, + _ => return report_error(&format!("Node type '{}' should not have data '{}'", node_type_str, data)), + }; + Ok(Some(make_leaf(node_type, value))) + } else { + // No data part, so it's an internal node. Recursively load children. + // Check arity based on node type + match node_type { + // Unary operators or control structures needing one child/subtree + NodeType::Negate | NodeType::Not | NodeType::Prtc | NodeType::Prti | NodeType::Prts => { + let left = load_ast(lines, context)?; + Ok(Some(make_node(node_type, left, None))) + } + // Binary operators or control structures needing two children/subtrees + NodeType::Sequence | NodeType::If | NodeType::While | NodeType::Assign | + NodeType::Mul | NodeType::Div | NodeType::Mod | NodeType::Add | NodeType::Sub | + NodeType::Lss | NodeType::Leq | NodeType::Gtr | NodeType::Geq | + NodeType::Eql | NodeType::Neq | NodeType::And | NodeType::Or => { + let left = load_ast(lines, context)?; + let right = load_ast(lines, context)?; + Ok(Some(make_node(node_type, left, right))) + } + // Leaf node types that were handled above. Error if encountered here. + NodeType::Ident | NodeType::String | NodeType::Integer => { + report_error(&format!("Leaf node type '{}' found without data", node_type_str)) + } + } + } + } + } +} + +// --- Main Function --- + +fn main() -> Result<(), String> { + let args: Vec = env::args().collect(); + + // Determine input source: file or stdin + let input: Box = if args.len() > 1 && !args[1].is_empty() { + let filename = &args[1]; + let file = File::open(filename) + .map_err(|e| format!("Cannot open file '{}': {}", filename, e))?; + Box::new(BufReader::new(file)) + } else { + Box::new(BufReader::new(io::stdin())) + }; + + let mut lines = input.lines(); + let mut context = InterpreterContext::new(); + + // Load the entire AST structure + let ast_root = load_ast(&mut lines, &mut context)?; + + // Interpret the loaded AST + interp(ast_root.as_ref(), &mut context); + + println!(); // Add a newline like the C version might implicitly do after last print + + Ok(()) +} diff --git a/Task/Compiler-code-generator/JavaScript/compiler-code-generator.js b/Task/Compiler-code-generator/JavaScript/compiler-code-generator.js new file mode 100644 index 0000000000..4a26bae23c --- /dev/null +++ b/Task/Compiler-code-generator/JavaScript/compiler-code-generator.js @@ -0,0 +1,502 @@ +// Required Node.js modules +const fs = require('fs'); +const path = require('path'); // Useful for joining paths if needed + +// --- Constants --- +const WORD_SIZE = 4; // In bytes + +// --- Enums (JavaScript Object Equivalents) --- + +const Mnemonic = { + NONE: { ordinal: 0, name: 'NONE' }, + FETCH: { ordinal: 1, name: 'FETCH' }, + STORE: { ordinal: 2, name: 'STORE' }, + PUSH: { ordinal: 3, name: 'PUSH' }, + ADD: { ordinal: 4, name: 'ADD' }, + SUB: { ordinal: 5, name: 'SUB' }, + MUL: { ordinal: 6, name: 'MUL' }, + DIV: { ordinal: 7, name: 'DIV' }, + MOD: { ordinal: 8, name: 'MOD' }, + LT: { ordinal: 9, name: 'LT' }, + GT: { ordinal: 10, name: 'GT' }, + LE: { ordinal: 11, name: 'LE' }, + GE: { ordinal: 12, name: 'GE' }, + EQ: { ordinal: 13, name: 'EQ' }, + NE: { ordinal: 14, name: 'NE' }, + AND: { ordinal: 15, name: 'AND' }, + OR: { ordinal: 16, name: 'OR' }, + NEG: { ordinal: 17, name: 'NEG' }, + NOT: { ordinal: 18, name: 'NOT' }, + JMP: { ordinal: 19, name: 'JMP' }, + JZ: { ordinal: 20, name: 'JZ' }, + PRTC: { ordinal: 21, name: 'PRTC' }, + PRTS: { ordinal: 22, name: 'PRTS' }, + PRTI: { ordinal: 23, name: 'PRTI' }, + HALT: { ordinal: 24, name: 'HALT' }, +}; + +// Helper array to map ordinal back to Mnemonic object (for listCode) +const MnemonicByOrdinal = Object.values(Mnemonic).sort((a, b) => a.ordinal - b.ordinal); + + +const NodeType = { + nd_None: { name: 'None', mnemonic: Mnemonic.NONE }, + nd_Ident: { name: 'Identifier', mnemonic: Mnemonic.NONE }, + nd_String: { name: 'String', mnemonic: Mnemonic.NONE }, + nd_Integer: { name: 'Integer', mnemonic: Mnemonic.NONE }, + nd_Sequence: { name: 'Sequence', mnemonic: Mnemonic.NONE }, + nd_If: { name: 'If', mnemonic: Mnemonic.NONE }, + nd_Prtc: { name: 'Prtc', mnemonic: Mnemonic.PRTC }, + nd_Prts: { name: 'Prts', mnemonic: Mnemonic.PRTS }, + nd_Prti: { name: 'Prti', mnemonic: Mnemonic.PRTI }, + nd_While: { name: 'While', mnemonic: Mnemonic.NONE }, + nd_Assign: { name: 'Assign', mnemonic: Mnemonic.NONE }, + nd_Negate: { name: 'Negate', mnemonic: Mnemonic.NEG }, + nd_Not: { name: 'Not', mnemonic: Mnemonic.NOT }, + nd_Mul: { name: 'Multiply', mnemonic: Mnemonic.MUL }, + nd_Div: { name: 'Divide', mnemonic: Mnemonic.DIV }, + nd_Mod: { name: 'Mod', mnemonic: Mnemonic.MOD }, + nd_Add: { name: 'Add', mnemonic: Mnemonic.ADD }, + nd_Sub: { name: 'Subtract', mnemonic: Mnemonic.SUB }, + nd_Lss: { name: 'Less', mnemonic: Mnemonic.LT }, + nd_Leq: { name: 'LessEqual', mnemonic: Mnemonic.LE }, + nd_Gtr: { name: 'Greater', mnemonic: Mnemonic.GT }, + nd_Geq: { name: 'GreaterEqual', mnemonic: Mnemonic.GE }, + nd_Eql: { name: 'Equal', mnemonic: Mnemonic.EQ }, + nd_Neq: { name: 'NotEqual', mnemonic: Mnemonic.NE }, + nd_And: { name: 'And', mnemonic: Mnemonic.AND }, + nd_Or: { name: 'Or', mnemonic: Mnemonic.OR }, +}; + + +// --- AST Node Class --- +class Node { + constructor(nt = null, left = null, right = null, value = null) { + this.nt = nt; + this.left = left; + this.right = right; + this.value = value; + } + + static makeNode(nodetype, left, right) { + return new Node(nodetype, left, right, null); + } + + static makeNode1(nodetype, left) { + return new Node(nodetype, left, null, null); + } + + static makeLeaf(nodetype, value) { + return new Node(nodetype, null, null, value); + } +} + + +// --- Code Generator State and Methods --- + +let code = new Uint8Array(0); // Use Uint8Array for byte code +const strToNodes = new Map(); +const stringPool = []; +const variables = []; +let stringCount = 0; +let varCount = 0; + +const unaryOps = [ + NodeType.nd_Negate, NodeType.nd_Not +]; +const operators = [ + NodeType.nd_Mul, NodeType.nd_Div, NodeType.nd_Mod, NodeType.nd_Add, NodeType.nd_Sub, + NodeType.nd_Lss, NodeType.nd_Leq, NodeType.nd_Gtr, NodeType.nd_Geq, + NodeType.nd_Eql, NodeType.nd_Neq, NodeType.nd_And, NodeType.nd_Or +]; + +// State for reading AST from lines +let inputLines = []; +let currentLineIndex = 0; + + +function appendToCode(b) { + const newCode = new Uint8Array(code.length + 1); + newCode.set(code); // Copy existing bytes + newCode[code.length] = b & 0xff; // Add new byte (ensure it's 0-255) + code = newCode; +} + +function emitByte(m) { + appendToCode(m.ordinal); +} + +function emitWord(n) { + // Ensure n is treated as a 32-bit integer (signed or unsigned depends on context) + // Emit bytes in big-endian order + appendToCode((n >> 24) & 0xff); + appendToCode((n >> 16) & 0xff); + appendToCode((n >> 8) & 0xff); + appendToCode(n & 0xff); +} + +function emitWordAt(pos, n) { + if (pos + WORD_SIZE > code.length) { + throw new Error(`Emit word out of bounds at position ${pos}`); + } + // Ensure n is treated as a 32-bit integer + code[pos] = (n >> 24) & 0xff; + code[pos + 1] = (n >> 16) & 0xff; + code[pos + 2] = (n >> 8) & 0xff; + code[pos + 3] = n & 0xff; +} + +function getWord(pos) { + if (pos + WORD_SIZE > code.length) { + throw new Error(`Get word out of bounds at position ${pos}`); + } + // Read bytes in big-endian order and combine into a 32-bit integer + // Need to treat bytes as unsigned (0-255) using & 0xff + let result = 0; + result |= (code[pos] & 0xff) << 24; + result |= (code[pos + 1] & 0xff) << 16; + result |= (code[pos + 2] & 0xff) << 8; + result |= (code[pos + 3] & 0xff); + + // Handle sign bit if the result is expected to be signed + // In JS, bitwise ops treat numbers as signed 32-bit. + // The above combination *might* result in a negative number + // if the most significant bit is set (for values >= 2^31). + // If the VM expects unsigned, this is fine. If signed, + // JS handles this conversion reasonably well after the bitwise ops. + // Let's return the potentially signed result from the bitwise ops. + return result; +} + + +function fetchVarOffset(name) { + let n = variables.indexOf(name); + if (n === -1) { + variables.push(name); + n = varCount++; + } + return n; +} + +function fetchStringOffset(str) { + let n = stringPool.indexOf(str); + if (n === -1) { + stringPool.push(str); + n = stringCount++; + } + return n; +} + +function hole() { + const t = code.length; + emitWord(0); // Emit a placeholder word (0) + return t; // Return the position of the hole +} + +function arrayContains(arr, item) { + return arr.includes(item); // JavaScript Array.prototype.includes is equivalent +} + +function codeGen(x) { + let n, p1, p2; + if (x === null) return; + + switch (x.nt) { + case NodeType.nd_None: + return; + case NodeType.nd_Ident: + emitByte(Mnemonic.FETCH); + n = fetchVarOffset(x.value); + emitWord(n); + break; + case NodeType.nd_Integer: + emitByte(Mnemonic.PUSH); + emitWord(parseInt(x.value, 10)); // Use radix 10 + break; + case NodeType.nd_String: + emitByte(Mnemonic.PUSH); + n = fetchStringOffset(x.value); + emitWord(n); + break; + case NodeType.nd_Assign: + n = fetchVarOffset(x.left.value); + codeGen(x.right); + emitByte(Mnemonic.STORE); + emitWord(n); + break; + case NodeType.nd_If: + // p2 needs scope beyond the if block, initialize before switch case + codeGen(x.left); // Condition + emitByte(Mnemonic.JZ); // Jump if condition is zero (false) + p1 = hole(); // Placeholder for jump address (to 'else' or end of 'then') + + codeGen(x.right.left); // 'then' block + + if (x.right.right !== null) { // Check if 'else' block exists + emitByte(Mnemonic.JMP); // Jump over 'else' block after 'then' + p2 = hole(); // Placeholder for jump address (to end of 'else') + } + + // Patch the JZ instruction: jump relative from instruction *after* the word + emitWordAt(p1, code.length - (p1 + WORD_SIZE)); + + if (x.right.right !== null) { + codeGen(x.right.right); // 'else' block + // Patch the JMP instruction: jump relative from instruction *after* the word + emitWordAt(p2, code.length - (p2 + WORD_SIZE)); + } + break; + case NodeType.nd_While: + p1 = code.length; // Start of the loop condition + codeGen(x.left); // Condition + emitByte(Mnemonic.JZ); // Jump if condition is zero (false) + p2 = hole(); // Placeholder for jump address (to end of loop) + + codeGen(x.right); // Loop body + + emitByte(Mnemonic.JMP); // Jump back to the start of the loop condition + // Jump relative from instruction *after* the word + emitWord(p1 - (code.length + WORD_SIZE)); + + // Patch the JZ instruction: jump relative from instruction *after* the word + emitWordAt(p2, code.length - (p2 + WORD_SIZE)); + break; + case NodeType.nd_Sequence: + codeGen(x.left); + codeGen(x.right); + break; + case NodeType.nd_Prtc: + codeGen(x.left); + emitByte(Mnemonic.PRTC); + break; + case NodeType.nd_Prti: + codeGen(x.left); + emitByte(Mnemonic.PRTI); + break; + case NodeType.nd_Prts: + codeGen(x.left); + emitByte(Mnemonic.PRTS); + break; + default: + if (arrayContains(operators, x.nt)) { + codeGen(x.left); + codeGen(x.right); + emitByte(x.nt.mnemonic); // Use the mnemonic property + } else if (arrayContains(unaryOps, x.nt)) { + codeGen(x.left); + emitByte(x.nt.mnemonic); // Use the mnemonic property + } else { + throw new Error(`Error in code generator! Found ${x.nt.name}, expecting operator.`); + } + } +} + +function listCode() { + let pc = 0; + console.log(`Datasize: ${varCount} Strings: ${stringCount}`); + for (const s of stringPool) { + console.log(`"${s}"`); // Print strings, maybe quoted + } + + console.log("\n--- Code ---"); + + while (pc < code.length) { + process.stdout.write(`${pc.toString().padStart(4, ' ')} `); // Format like printf %4d + const opcodeValue = code[pc++]; + if (opcodeValue >= MnemonicByOrdinal.length) { + throw new Error(`Unknown opcode value ${opcodeValue} @ ${pc - 1}`); + } + const op = MnemonicByOrdinal[opcodeValue]; + + let x; + switch (op) { + case Mnemonic.FETCH: + x = getWord(pc); + process.stdout.write(`fetch [${x}]`); + pc += WORD_SIZE; + break; + case Mnemonic.STORE: + x = getWord(pc); + process.stdout.write(`store [${x}]`); + pc += WORD_SIZE; + break; + case Mnemonic.PUSH: + x = getWord(pc); + process.stdout.write(`push ${x}`); + pc += WORD_SIZE; + break; + case Mnemonic.ADD: case Mnemonic.SUB: case Mnemonic.MUL: case Mnemonic.DIV: case Mnemonic.MOD: + case Mnemonic.LT: case Mnemonic.GT: case Mnemonic.LE: case Mnemonic.GE: case Mnemonic.EQ: case Mnemonic.NE: + case Mnemonic.AND: case Mnemonic.OR: case Mnemonic.NEG: case Mnemonic.NOT: + case Mnemonic.PRTC: case Mnemonic.PRTI: case Mnemonic.PRTS: case Mnemonic.HALT: + process.stdout.write(op.name.toLowerCase()); + break; + case Mnemonic.JMP: + x = getWord(pc); // Read relative offset + // Relative offset is calculated from the *instruction following the word* in the VM + // pc points to the byte *after* the word now. + process.stdout.write(`jmp (${x}) ${pc + x}`); + pc += WORD_SIZE; + break; + case Mnemonic.JZ: + x = getWord(pc); // Read relative offset + // Relative offset is calculated from the *instruction following the word* in the VM + // pc points to the byte *after* the word now. + process.stdout.write(`jz (${x}) ${pc + x}`); + pc += WORD_SIZE; + break; + default: + // Should not happen if MnemonicByOrdinal is correctly built + throw new Error(`Unknown opcode ${op.name} (${opcodeValue}) @ ${pc - 1}`); + } + console.log(); // Newline after each instruction + } +} + + +// Helper function to get the next line from the pre-loaded array +function getNextLine() { + if (currentLineIndex >= inputLines.length) { + return null; // End of input + } + return inputLines[currentLineIndex++]; +} + +function loadAst() { + let command, value; + let line = getNextLine(); + + while (line !== null) { + value = null; + // Check line length before substring to avoid errors + if (line.length > 15) { + command = line.substring(0, 15).trim(); + value = line.substring(15).trim(); + } else { + command = line.trim(); + } + + if (command === ";") { + return null; // End of a sequence or node definition + } + + const nodeType = strToNodes.get(command); + if (!nodeType) { + throw new Error(`Command not found: '${command}' on line ${currentLineIndex}`); + } + + if (value !== null && value !== "") { // Check value is not just empty string + // Note: The Java code checks value != null. If the AST format + // allows "Identifier ", value will be "" after trim. + // Let's stick closer to Java's null check, assuming non-leaf + // nodes won't have anything after column 15 except whitespace. + // Re-evaluating Java: `value != null` is set based on `line.length > 16`. + // Let's emulate that logic closely. + + // Java logic: value = line.substring(15).trim(); IF line.length > 16 + // Then `if (value != null)` returns leaf. + // If line.length <= 16, command = line.trim(), value = null. + // So leaf nodes MUST have something after col 15. + // Let's adjust: if line.length > 15, value = line.substring(15).trim(). + // Then check if value is non-empty. This handles "Identifier " as non-leaf. + + // Corrected logic: + if (line.length > 15 && line.substring(15).trim() !== "") { + value = line.substring(15).trim(); + return Node.makeLeaf(nodeType, value); + } + // If line.length <= 15 OR substring(15).trim() is empty, + // it's not a leaf with a value in that part of the line. + // Fall through to non-leaf handling. + } + + + // If it's not a leaf (or the leaf value part was empty/absent based on col 15) + // Recursively load children + const left = loadAst(); + const right = loadAst(); // Might be null for unary/sequence end + + // Some nodes like Prtc, Prti, Prts, Negate, Not only have a left child + // Based on the Java code_gen, these are treated as makeNode1 implicitly + // but load_ast always tries to read two children. + // The AST format must represent unary nodes with a ";" after the single child. + // Example: Prtc\n Integer 10\n ;\n ; + // This recursive loadAst handles that structure. + return Node.makeNode(nodeType, left, right); + } + + // Should ideally not reach here if input is well-formed and ends with AST + // But needed for compiler in Java, let's return null in JS too for safety. + return null; +} + + +// --- Initialization --- +function initialize() { + strToNodes.set(";", NodeType.nd_None); // Special case for AST parsing termination + strToNodes.set("Sequence", NodeType.nd_Sequence); + strToNodes.set("Identifier", NodeType.nd_Ident); + strToNodes.set("String", NodeType.nd_String); + strToNodes.set("Integer", NodeType.nd_Integer); + strToNodes.set("If", NodeType.nd_If); + strToNodes.set("While", NodeType.nd_While); + strToNodes.set("Prtc", NodeType.nd_Prtc); + strToNodes.set("Prts", NodeType.nd_Prts); + strToNodes.set("Prti", NodeType.nd_Prti); + strToNodes.set("Assign", NodeType.nd_Assign); + strToNodes.set("Negate", NodeType.nd_Negate); + strToNodes.set("Not", NodeType.nd_Not); + strToNodes.set("Multiply", NodeType.nd_Mul); + strToNodes.set("Divide", NodeType.nd_Div); + strToNodes.set("Mod", NodeType.nd_Mod); + strToNodes.set("Add", NodeType.nd_Add); + strToNodes.set("Subtract", NodeType.nd_Sub); + strToNodes.set("Less", NodeType.nd_Lss); + strToNodes.set("LessEqual", NodeType.nd_Leq); + strToNodes.set("Greater", NodeType.nd_Gtr); + strToNodes.set("GreaterEqual", NodeType.nd_Geq); + strToNodes.set("Equal", NodeType.nd_Eql); + strToNodes.set("NotEqual", NodeType.nd_Neq); + strToNodes.set("And", NodeType.nd_And); + strToNodes.set("Or", NodeType.nd_Or); +} + + +// --- Main Execution --- +function main() { + initialize(); + + const args = process.argv.slice(2); // Get command line arguments excluding 'node' and script name + + if (args.length > 0) { + const filename = args[0]; + try { + // Read the entire file synchronously for simpler line-by-line processing + const fileContent = fs.readFileSync(filename, 'utf8'); + inputLines = fileContent.split(/\r?\n/); // Split into lines, handling common line endings + currentLineIndex = 0; // Reset line index for loadAst + + const ast = loadAst(); + + if (ast) { + codeGen(ast); + emitByte(Mnemonic.HALT); // Emit HALT after generating code for the main AST + listCode(); + } else { + console.log("No valid AST loaded."); + } + + + } catch (e) { + console.error(`Error: ${e.message}`); + // console.error(e.stack); // Uncomment for detailed stack trace + } + } else { + console.log("Usage: node code_generator.js "); + } +} + +// Execute the main function +if (require.main === module) { + main(); +} diff --git a/Task/Compiler-code-generator/Rust/compiler-code-generator.rs b/Task/Compiler-code-generator/Rust/compiler-code-generator.rs new file mode 100644 index 0000000000..795d5617f4 --- /dev/null +++ b/Task/Compiler-code-generator/Rust/compiler-code-generator.rs @@ -0,0 +1,644 @@ +// src/main.rs + +use std::collections::HashMap; +use std::fs::File; +use std::io::{self, BufRead, BufReader, BufWriter, Write}; +use std::path::Path; +use std::process; +use std::error::Error; +use std::fmt; + +// --- Custom Error Type --- +#[derive(Debug)] +enum CompileError { + Io(io::Error), + Parse(String), + CodeGen(String), + Runtime(String), // For potential runtime errors if extended later +} + +impl fmt::Display for CompileError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + CompileError::Io(e) => write!(f, "IO Error: {}", e), + CompileError::Parse(msg) => write!(f, "Parse Error: {}", msg), + CompileError::CodeGen(msg) => write!(f, "Code Generation Error: {}", msg), + CompileError::Runtime(msg) => write!(f, "Runtime Error: {}", msg), + } + } +} + +impl Error for CompileError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + CompileError::Io(e) => Some(e), + _ => None, + } + } +} + +// Allow converting io::Error into CompileError +impl From for CompileError { + fn from(err: io::Error) -> CompileError { + CompileError::Io(err) + } +} + +// Convenience type alias for Results +type Result = std::result::Result; + +// --- Enums --- +// Using u8 for Code as in the C code (uchar) +type CodeByte = u8; + +// Added derive attributes for convenience +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[repr(u8)] // Explicit representation matching C's implicit enum values +enum NodeType { + Ident, String, Integer, Sequence, If, Prtc, Prts, Prti, While, + Assign, Negate, Not, Mul, Div, Mod, Add, Sub, Lss, Leq, + Gtr, Geq, Eql, Neq, And, Or, + // Added for parsing unknown types + Unknown, +} + +// Mapping string names to NodeType - replacing get_enum_value C function +fn node_type_from_str(s: &str) -> NodeType { + match s { + "Identifier" => NodeType::Ident, + "String" => NodeType::String, + "Integer" => NodeType::Integer, + "Sequence" => NodeType::Sequence, + "If" => NodeType::If, + "Prtc" => NodeType::Prtc, + "Prts" => NodeType::Prts, + "Prti" => NodeType::Prti, + "While" => NodeType::While, + "Assign" => NodeType::Assign, + "Negate" => NodeType::Negate, + "Not" => NodeType::Not, + "Multiply" => NodeType::Mul, + "Divide" => NodeType::Div, + "Mod" => NodeType::Mod, + "Add" => NodeType::Add, + "Subtract" => NodeType::Sub, + "Less" => NodeType::Lss, + "LessEqual" => NodeType::Leq, + "Greater" => NodeType::Gtr, + "GreaterEqual" => NodeType::Geq, + "Equal" => NodeType::Eql, + "NotEqual" => NodeType::Neq, + "And" => NodeType::And, + "Or" => NodeType::Or, + _ => NodeType::Unknown, // Handle unknown tokens gracefully + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +enum OpCode { + Fetch, Store, Push, Add, Sub, Mul, Div, Mod, Lt, Gt, Le, Ge, Eq, Ne, And, + Or, Neg, Not, Jmp, Jz, Prtc, Prts, Prti, Halt, +} + +// --- Structs --- +#[derive(Debug, Clone)] // Added Clone for easier handling if needed +struct Tree { + node_type: NodeType, + // Use Option> for optional children + left: Option>, + right: Option>, + // Use String for owned string values + value: Option, +} + +impl Tree { + // Constructor for nodes with children + fn new_node(node_type: NodeType, left: Tree, right: Tree) -> Box { + Box::new(Tree { + node_type, + left: Some(Box::new(left)), + right: Some(Box::new(right)), + value: None, + }) + } + + // Constructor for nodes with children (accepting Option>) + fn new_node_option(node_type: NodeType, left: Option>, right: Option>) -> Box { + Box::new(Tree { + node_type, + left, + right, + value: None, + }) + } + + + // Constructor for leaf nodes with a value + fn new_leaf(node_type: NodeType, value: &str) -> Box { + Box::new(Tree { + node_type, + left: None, + right: None, + value: Some(value.to_string()), + }) + } +} + +// --- Code Generation State --- +struct CodeGenState { + object: Vec, // Replaces da_dim(object, code) + globals: Vec, // Replaces da_dim(globals, const char *) + string_pool: Vec, // Replaces da_dim(string_pool, const char *) + // `here` is implicitly `object.len()` +} + +impl CodeGenState { + fn new() -> Self { + CodeGenState { + object: Vec::new(), + globals: Vec::new(), + string_pool: Vec::new(), + } + } + + // Get current code position + fn here(&self) -> usize { + self.object.len() + } + + // Replaces emit_byte + fn emit_byte(&mut self, byte: CodeByte) { + self.object.push(byte); + } + + // Emit an opcode + fn emit_opcode(&mut self, opcode: OpCode) { + self.object.push(opcode as CodeByte); + } + + // Replaces emit_int - uses little-endian encoding + fn emit_int(&mut self, value: i32) { + self.object.extend_from_slice(&value.to_le_bytes()); + } + + // Replaces hole() + fn emit_hole(&mut self) -> usize { + let pos = self.here(); + self.emit_int(0); // Placeholder value + pos + } + + // Replaces fix() - patches a previous hole + // Uses little-endian encoding + fn fix_jump(&mut self, hole_pos: usize, jump_target: usize) -> Result<()> { + if hole_pos + 4 > self.object.len() { + return Err(CompileError::CodeGen("Invalid hole position for jump fix".to_string())); + } + // Calculate relative offset + let offset = jump_target as isize - (hole_pos as isize + 4); // offset is from *after* the int + let offset_bytes = (offset as i32).to_le_bytes(); + self.object[hole_pos..hole_pos + 4].copy_from_slice(&offset_bytes); + Ok(()) + } + + // Like C's fix, but uses absolute target address for patching data later + // Use for patching arbitrary data, not jumps + fn fix_data(&mut self, pos: usize, value: i32) -> Result<()> { + if pos + 4 > self.object.len() { + return Err(CompileError::CodeGen("Invalid position for data fix".to_string())); + } + let value_bytes = value.to_le_bytes(); + self.object[pos..pos + 4].copy_from_slice(&value_bytes); + Ok(()) + } + + + // Replaces fetch_var_offset + fn fetch_var_offset(&mut self, id: &str) -> usize { + if let Some(pos) = self.globals.iter().position(|g| g == id) { + pos + } else { + self.globals.push(id.to_string()); + self.globals.len() - 1 + } + } + + // Replaces fetch_string_offset + fn fetch_string_offset(&mut self, st: &str) -> usize { + if let Some(pos) = self.string_pool.iter().position(|s| s == st) { + pos + } else { + self.string_pool.push(st.to_string()); + self.string_pool.len() - 1 + } + } + + // Replaces type_to_op + fn type_to_op(node_type: NodeType) -> Option { + match node_type { + NodeType::Negate => Some(OpCode::Neg), + NodeType::Not => Some(OpCode::Not), + NodeType::Mul => Some(OpCode::Mul), + NodeType::Div => Some(OpCode::Div), + NodeType::Mod => Some(OpCode::Mod), + NodeType::Add => Some(OpCode::Add), + NodeType::Sub => Some(OpCode::Sub), + NodeType::Lss => Some(OpCode::Lt), + NodeType::Leq => Some(OpCode::Le), + NodeType::Gtr => Some(OpCode::Gt), + NodeType::Geq => Some(OpCode::Ge), + NodeType::Eql => Some(OpCode::Eq), + NodeType::Neq => Some(OpCode::Ne), + NodeType::And => Some(OpCode::And), + NodeType::Or => Some(OpCode::Or), + _ => None, // Other node types don't map directly to a single opcode + } + } + + // --- Code Generator Logic --- + // Takes Option<&Tree> because some nodes might have absent children + fn code_gen(&mut self, node: Option<&Tree>) -> Result<()> { + let node = match node { + Some(n) => n, + None => return Ok(()), // Nothing to generate for a None node + }; + + match node.node_type { + NodeType::Ident => { + let ident = node.value.as_ref().ok_or_else(|| { + CompileError::CodeGen("Identifier node is missing value".to_string()) + })?; + self.emit_opcode(OpCode::Fetch); + let offset = self.fetch_var_offset(ident); + self.emit_int(offset as i32); + } + NodeType::Integer => { + let val_str = node.value.as_ref().ok_or_else(|| { + CompileError::CodeGen("Integer node is missing value".to_string()) + })?; + let value = val_str.parse::().map_err(|e| { + CompileError::Parse(format!("Invalid integer literal '{}': {}", val_str, e)) + })?; + self.emit_opcode(OpCode::Push); + self.emit_int(value); + } + NodeType::String => { + let val_str = node.value.as_ref().ok_or_else(|| { + CompileError::CodeGen("String node is missing value".to_string()) + })?; + self.emit_opcode(OpCode::Push); + let offset = self.fetch_string_offset(val_str); + self.emit_int(offset as i32); + } + NodeType::Assign => { + let ident_node = node.left.as_ref().ok_or_else(|| { + CompileError::CodeGen("Assignment missing identifier (left side)".to_string()) + })?; + let ident = ident_node.value.as_ref().ok_or_else(|| { + CompileError::CodeGen("Assignment identifier node missing value".to_string()) + })?; + if ident_node.node_type != NodeType::Ident { + return Err(CompileError::CodeGen("Left side of assignment must be an identifier".to_string())); + } + + let var_offset = self.fetch_var_offset(ident); + self.code_gen(node.right.as_deref())?; // Generate value first + self.emit_opcode(OpCode::Store); + self.emit_int(var_offset as i32); + } + NodeType::If => { + // If condition + self.code_gen(node.left.as_deref())?; + self.emit_opcode(OpCode::Jz); // Jump if zero (false) + let jump_over_true_branch_hole = self.emit_hole(); + + // True branch (must be present, wrapped in Sequence or single node) + let if_body = node.right.as_ref().ok_or_else(|| CompileError::CodeGen("If node missing body (right side)".to_string()))?; + + self.code_gen(if_body.left.as_deref())?; // Execute 'then' part + + // Handle optional 'else' part + let mut jump_over_else_branch_hole: Option = None; + if if_body.right.is_some() { + self.emit_opcode(OpCode::Jmp); // Jump over the 'else' part + jump_over_else_branch_hole = Some(self.emit_hole()); + } + + // Patch the first jump (jz) to point after the 'then' block (or after the 'jmp' if there's an else) + let after_true_branch = self.here(); + self.fix_jump(jump_over_true_branch_hole, after_true_branch)?; + + // Generate 'else' block if it exists + if let Some(else_node) = &if_body.right { + self.code_gen(Some(else_node))?; + // Patch the jump over the else branch + let after_else_branch = self.here(); + if let Some(hole) = jump_over_else_branch_hole { + self.fix_jump(hole, after_else_branch)?; + } else { + // Should not happen if if_body.right was Some + return Err(CompileError::CodeGen("Internal error: Missing else jump hole".to_string())); + } + } + } + NodeType::While => { + let condition_start = self.here(); + self.code_gen(node.left.as_deref())?; // While expr + self.emit_opcode(OpCode::Jz); // If false, jump to end + let exit_jump_hole = self.emit_hole(); + + self.code_gen(node.right.as_deref())?; // Loop body + self.emit_opcode(OpCode::Jmp); // Jump back to condition + // Use emit_hole + fix_jump for the backward jump + let back_jump_hole = self.emit_hole(); + self.fix_jump(back_jump_hole, condition_start)?; + + let after_loop = self.here(); + self.fix_jump(exit_jump_hole, after_loop)?; // Patch the exit jump + } + NodeType::Sequence => { + self.code_gen(node.left.as_deref())?; + self.code_gen(node.right.as_deref())?; + } + NodeType::Prtc => { + self.code_gen(node.left.as_deref())?; + self.emit_opcode(OpCode::Prtc); + } + NodeType::Prti => { + self.code_gen(node.left.as_deref())?; + self.emit_opcode(OpCode::Prti); + } + NodeType::Prts => { + self.code_gen(node.left.as_deref())?; + self.emit_opcode(OpCode::Prts); + } + // Binary Operators + NodeType::Lss | NodeType::Gtr | NodeType::Leq | NodeType::Geq | + NodeType::Eql | NodeType::Neq | NodeType::And | NodeType::Or | + NodeType::Sub | NodeType::Add | NodeType::Div | NodeType::Mul | + NodeType::Mod => { + self.code_gen(node.left.as_deref())?; + self.code_gen(node.right.as_deref())?; + if let Some(op) = CodeGenState::type_to_op(node.node_type) { + self.emit_opcode(op); + } else { + return Err(CompileError::CodeGen(format!( + "Cannot map node type {:?} to binary opcode", node.node_type + ))); + } + } + // Unary Operators + NodeType::Negate | NodeType::Not => { + self.code_gen(node.left.as_deref())?; + if let Some(op) = CodeGenState::type_to_op(node.node_type) { + self.emit_opcode(op); + } else { + return Err(CompileError::CodeGen(format!( + "Cannot map node type {:?} to unary opcode", node.node_type + ))); + } + } + NodeType::Unknown => { + return Err(CompileError::CodeGen("Encountered Unknown node type during code generation".to_string())); + } + } + Ok(()) + } + + // Replaces code_finish + fn code_finish(&mut self) { + self.emit_opcode(OpCode::Halt); + } +} + + +// --- Disassembler --- +// Replaces list_code +// Takes BufWriter for potentially better performance with many writes +fn list_code(state: &CodeGenState, writer: &mut BufWriter) -> Result<()> { + writeln!(writer, "Datasize: {} Strings: {}", state.globals.len(), state.string_pool.len())?; + for s in &state.string_pool { + writeln!(writer, "{}", s)?; + } + writeln!(writer, "--- Code ---")?; + + let code = &state.object; + let mut pc = 0; + + while pc < code.len() { + let start_pc = pc; + write!(writer, "{:5} ", start_pc)?; + + // Function to safely read an i32 operand + let read_operand = |current_pc: usize| -> Result<(i32, usize)> { + let end_operand = current_pc + 4; + if end_operand > code.len() { + Err(CompileError::Runtime("Unexpected end of code while reading operand".to_string())) + } else { + // Read bytes assuming little-endian + let mut bytes = [0u8; 4]; + bytes.copy_from_slice(&code[current_pc..end_operand]); + Ok((i32::from_le_bytes(bytes), end_operand)) + } + }; + + // Function to safely read an opcode byte + let read_opcode_byte = |current_pc: usize| -> Result<(u8, usize)> { + if current_pc >= code.len() { + Err(CompileError::Runtime("Unexpected end of code while reading opcode".to_string())) + } else { + Ok((code[current_pc], current_pc + 1)) + } + }; + + let (opcode_byte, next_pc) = read_opcode_byte(pc)?; + pc = next_pc; // Move pc past the opcode byte + + // Try to convert byte to OpCode enum + let opcode: OpCode = unsafe { + // This is safe IF OpCode is repr(u8) and opcode_byte is a valid variant value. + // A safer way would be a match statement or a function. + if opcode_byte <= OpCode::Halt as u8 { + std::mem::transmute(opcode_byte) + } else { + writeln!(writer, "ERROR: Unknown opcode byte {}", opcode_byte)?; + return Err(CompileError::Runtime(format!("Unknown opcode byte: {}", opcode_byte))); + } + }; + + + match opcode { + OpCode::Fetch => { + let (operand, next_pc) = read_operand(pc)?; pc = next_pc; + writeln!(writer, "fetch [{}]", operand)?; + } + OpCode::Store => { + let (operand, next_pc) = read_operand(pc)?; pc = next_pc; + writeln!(writer, "store [{}]", operand)?; + } + OpCode::Push => { + let (operand, next_pc) = read_operand(pc)?; pc = next_pc; + writeln!(writer, "push {}", operand)?; + } + OpCode::Add => writeln!(writer, "add")?, + OpCode::Sub => writeln!(writer, "sub")?, + OpCode::Mul => writeln!(writer, "mul")?, + OpCode::Div => writeln!(writer, "div")?, + OpCode::Mod => writeln!(writer, "mod")?, + OpCode::Lt => writeln!(writer, "lt")?, + OpCode::Gt => writeln!(writer, "gt")?, + OpCode::Le => writeln!(writer, "le")?, + OpCode::Ge => writeln!(writer, "ge")?, + OpCode::Eq => writeln!(writer, "eq")?, + OpCode::Ne => writeln!(writer, "ne")?, + OpCode::And => writeln!(writer, "and")?, + OpCode::Or => writeln!(writer, "or")?, + OpCode::Neg => writeln!(writer, "neg")?, + OpCode::Not => writeln!(writer, "not")?, + OpCode::Jmp | OpCode::Jz => { + let (offset, next_pc) = read_operand(pc)?; pc = next_pc; + // Calculate absolute target address + // offset is relative to the instruction *after* the operand + let target_pc = (pc as isize + offset as isize) as usize; + let op_str = if opcode == OpCode::Jmp { "jmp" } else { "jz " }; + writeln!(writer, "{} ({}) {}", op_str, offset, target_pc)?; + + } + OpCode::Prtc => writeln!(writer, "prtc")?, + OpCode::Prti => writeln!(writer, "prti")?, + OpCode::Prts => writeln!(writer, "prts")?, + OpCode::Halt => { + writeln!(writer, "halt")?; + break; // Stop disassembly after HALT + } + // The transmute above should prevent reaching here if OpCode is exhaustive + // _ => { + // writeln!(writer, "ERROR: Unknown opcode {}", opcode_byte)?; + // return Err(CompileError::Runtime(format!("Unknown opcode byte: {}", opcode_byte))); + // } + } + } + writer.flush()?; // Ensure buffer is written + Ok(()) +} + + +// --- AST Loader --- +struct AstLoader { + reader: R, + line_buffer: String, +} + +impl AstLoader { + fn new(reader: R) -> Self { + AstLoader { + reader, + line_buffer: String::new(), + } + } + + // Replaces read_line and rtrim + fn read_next_line(&mut self) -> Result> { + self.line_buffer.clear(); + match self.reader.read_line(&mut self.line_buffer)? { + 0 => Ok(None), // EOF + _ => Ok(Some(self.line_buffer.trim_end())), // Return trimmed line + } + } + + // Replaces load_ast (recursive part) + fn load_ast_recursive(&mut self) -> Result>> { + let line = match self.read_next_line()? { + Some(l) if !l.is_empty() && !l.starts_with(';') => l, + Some(_) => return self.load_ast_recursive(), // Skip empty lines or comments + None => return Ok(None), // End of input + }; + + let mut parts = line.splitn(2, ' '); // Split into token and the rest + let token = parts.next().ok_or_else(|| CompileError::Parse("Empty line encountered unexpectedly".to_string()))?; + let maybe_value = parts.next(); + + let node_type = node_type_from_str(token); + if node_type == NodeType::Unknown { + return Err(CompileError::Parse(format!("Unknown token '{}'", token))); + } + + // Check if it's a leaf node (has extra data on the same line) + if let Some(value_part) = maybe_value { + let trimmed_value = value_part.trim_start(); + if !trimmed_value.is_empty() { + // It's a leaf node (Identifier, String, Integer) + match node_type { + NodeType::Ident | NodeType::String | NodeType::Integer => { + Ok(Some(Tree::new_leaf(node_type, trimmed_value))) + } + _ => Err(CompileError::Parse(format!( + "Node type {:?} unexpectedly found with value '{}' on the same line", + node_type, trimmed_value + ))), + } + } else { + // It's an internal node, load children recursively + let left = self.load_ast_recursive()?; + let right = self.load_ast_recursive()?; + Ok(Some(Tree::new_node_option(node_type, left, right))) + } + } else { + // No extra data, must be an internal node with children on subsequent lines + let left = self.load_ast_recursive()?; + let right = self.load_ast_recursive()?; + Ok(Some(Tree::new_node_option(node_type, left, right))) + } + } +} + + +// --- Main Function --- +fn main() { + if let Err(e) = run() { + eprintln!("Error: {}", e); + process::exit(1); + } +} + +fn run() -> Result<()> { + let args: Vec = std::env::args().collect(); + let source_filename = args.get(1).map(String::as_str).unwrap_or(""); + let dest_filename = args.get(2).map(String::as_str).unwrap_or(""); + + // --- Setup I/O --- + // Use Box to handle both Stdin and Files + let source_reader: Box = if source_filename.is_empty() { + Box::new(BufReader::new(io::stdin())) + } else { + let file = File::open(Path::new(source_filename)) + .map_err(|e| CompileError::Io(e))?; // Convert IO error + Box::new(BufReader::new(file)) + }; + + // Use Box and BufWriter for output + let dest_writer: Box = if dest_filename.is_empty() { + Box::new(io::stdout()) + } else { + let file = File::create(Path::new(dest_filename)) + .map_err(|e| CompileError::Io(e))?; + Box::new(file) + }; + let mut buffered_writer = BufWriter::new(dest_writer); + + + // --- Load AST --- + let mut loader = AstLoader::new(source_reader); + let ast_root = loader.load_ast_recursive()?; + + // --- Code Generation --- + let mut state = CodeGenState::new(); + state.code_gen(ast_root.as_deref())?; // Pass reference + state.code_finish(); + + // --- List Code --- + list_code(&state, &mut buffered_writer)?; + + Ok(()) +} diff --git a/Task/Compiler-lexical-analyzer/Rust/compiler-lexical-analyzer.rs b/Task/Compiler-lexical-analyzer/Rust/compiler-lexical-analyzer.rs new file mode 100644 index 0000000000..5170027cd8 --- /dev/null +++ b/Task/Compiler-lexical-analyzer/Rust/compiler-lexical-analyzer.rs @@ -0,0 +1,682 @@ +use once_cell::sync::Lazy; +use std::collections::HashMap; +use std::env; +use std::fmt; +use std::fs; +use std::io::{self, Read, Write}; +use std::process; +use std::str; + +// ===================================================================================================================== +// Errors +// ===================================================================================================================== + +// Define a custom error type for cleaner error handling +#[derive(Debug)] +enum LexerError { + Io(io::Error), + Generic(String), +} + +impl fmt::Display for LexerError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + LexerError::Io(e) => write!(f, "I/O Error: {}", e), + LexerError::Generic(s) => write!(f, "Lexer Error: {}", s), + } + } +} + +impl std::error::Error for LexerError {} + +// Allow easy conversion from io::Error +impl From for LexerError { + fn from(err: io::Error) -> Self { + LexerError::Io(err) + } +} + +// Allow easy conversion from String/&str +impl From for LexerError { + fn from(err: String) -> Self { + LexerError::Generic(err) + } +} +impl From<&str> for LexerError { + fn from(err: &str) -> Self { + LexerError::Generic(err.to_string()) + } +} + +type Result = std::result::Result; + +// ===================================================================================================================== +// Machinery +// ===================================================================================================================== + +fn file_to_string(path: &str) -> Result { + fs::read_to_string(path).map_err(LexerError::Io) +} + +fn string_to_file(path: &str, contents: &str) -> Result<()> { + fs::write(path, contents).map_err(LexerError::Io) +} + +// Rust version of with_IO, using closures and Result for error handling +fn with_io(source: &str, destination: &str, f: F) -> Result<()> +where + F: FnOnce(String) -> Result, +{ + let input = if source == "stdin" { + let mut buffer = String::new(); + io::stdin().read_to_string(&mut buffer)?; + buffer + } else { + file_to_string(source)? + }; + + let output = f(input)?; // Execute the processing function + + if destination == "stdout" { + print!("{}", output); // Use print! for stdout + io::stdout().flush()?; // Ensure output is flushed + } else { + string_to_file(destination, &output)?; + } + + Ok(()) +} + +// Add escaped newlines and backslashes back in for printing +fn sanitize(s: &str) -> String { + let mut result = String::with_capacity(s.len()); // Pre-allocate + for c in s.chars() { + match c { + '\n' => result.push_str("\\n"), + '\\' => result.push_str("\\\\"), + _ => result.push(c), + } + } + result +} + +// ===================================================================================================================== +// Scanner - Operates on byte slice for closer C++ char* parity +// ===================================================================================================================== +#[derive(Debug, Clone, Copy)] // Clone + Copy needed for pre_state +struct Scanner<'a> { + bytes: &'a [u8], + pos: usize, // Current byte position + line: usize, + column: usize, +} + +impl<'a> Scanner<'a> { + fn new(source: &'a str) -> Self { + Scanner { + bytes: source.as_bytes(), + pos: 0, + line: 1, + column: 1, + } + } + + // Peek at the current byte without consuming + fn peek(&self) -> Option { + self.bytes.get(self.pos).copied() + } + + // Peek at the next byte + fn peek_next(&self) -> Option { + self.bytes.get(self.pos + 1).copied() + } + + // Advance the position by one byte, updating line/column + fn advance(&mut self) { + if let Some(byte) = self.peek() { + self.pos += 1; + if byte == b'\n' { + self.line += 1; + self.column = 1; + } else { + self.column += 1; + } + } + // Don't advance past the end + } + + // Advance and return the *new* current byte + // Equivalent to C++'s next() behavior: advance then peek + fn next(&mut self) -> Option { + self.advance(); + self.peek() + } + + // Skip ASCII whitespace characters + fn skip_whitespace(&mut self) { + while let Some(byte) = self.peek() { + if byte.is_ascii_whitespace() { + self.advance(); + } else { + break; + } + } + } + + // Get the current byte slice from start_pos to current pos + fn slice(&self, start_pos: usize) -> &'a [u8] { + &self.bytes[start_pos..self.pos] + } +} + +// ===================================================================================================================== +// Tokens +// ===================================================================================================================== +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum TokenName { + OpMultiply, OpDivide, OpMod, OpAdd, OpSubtract, OpNegate, + OpLess, OpLessEqual, OpGreater, OpGreaterEqual, OpEqual, OpNotEqual, + OpNot, OpAssign, OpAnd, OpOr, + LeftParen, RightParen, LeftBrace, RightBrace, Semicolon, Comma, + KeywordIf, KeywordElse, KeywordWhile, KeywordPrint, KeywordPutc, + Identifier, Integer, String, + EndOfInput, Error, +} + +// Use Display trait for string representation +impl fmt::Display for TokenName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use TokenName::*; + let s = match self { + OpMultiply => "Op_multiply", OpDivide => "Op_divide", OpMod => "Op_mod", + OpAdd => "Op_add", OpSubtract => "Op_subtract", OpNegate => "Op_negate", + OpLess => "Op_less", OpLessEqual => "Op_lessequal", OpGreater => "Op_greater", + OpGreaterEqual => "Op_greaterequal", OpEqual => "Op_equal", OpNotEqual => "Op_notequal", + OpNot => "Op_not", OpAssign => "Op_assign", OpAnd => "Op_and", OpOr => "Op_or", + LeftParen => "LeftParen", RightParen => "RightParen", LeftBrace => "LeftBrace", + RightBrace => "RightBrace", Semicolon => "Semicolon", Comma => "Comma", + KeywordIf => "Keyword_if", KeywordElse => "Keyword_else", KeywordWhile => "Keyword_while", + KeywordPrint => "Keyword_print", KeywordPutc => "Keyword_putc", + Identifier => "Identifier", Integer => "Integer", String => "String", + EndOfInput => "End_of_input", Error => "Error", + }; + write!(f, "{}", s) + } +} + +// Rust enum for token values (replaces std::variant) +#[derive(Debug, Clone, PartialEq)] +enum TokenVal { + Int(i32), + String(String), + None, // For tokens without a specific value +} + +#[derive(Debug, Clone)] +struct Token { + name: TokenName, + value: TokenVal, + line: usize, + column: usize, +} + +// Use Display trait for formatted token output +impl fmt::Display for Token { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:<2} {:<2} ", self.line, self.column)?; // Use Rust formatting for width + match self.name { + TokenName::Identifier => { + if let TokenVal::String(s) = &self.value { + write!(f, "{:<18}{}", self.name, s) // Left align with width + } else { + write!(f, "{:<18}", self.name) // Should not happen + } + } + TokenName::Integer => { + if let TokenVal::Int(i) = &self.value { + write!(f, "{:<18}{}", self.name, i) + } else { + write!(f, "{:<18}", self.name) + } + } + TokenName::String => { + if let TokenVal::String(s) = &self.value { + write!(f, "{:<18}\"{}\"", self.name, sanitize(s)) + } else { + write!(f, "{:<18}", self.name) + } + } + TokenName::Error => { + if let TokenVal::String(s) = &self.value { + // Error message might be multi-line, handle indentation carefully + let lines: Vec<&str> = s.lines().collect(); + if lines.is_empty() { + write!(f, "{}", self.name) + } else { + write!(f, "{:<18}{}", self.name, lines[0])?; + for line in lines.iter().skip(1) { + write!(f, "\n{:<28}{}", "", line)?; // Indent subsequent lines + } + Ok(()) // Return Ok(()) explicitly as write! doesn't cover all paths + } + } else { + write!(f, "{}", self.name) // Error without details + } + } + TokenName::EndOfInput => write!(f, "{}", self.name), + // Default for simple tokens + _ => write!(f, "{}", self.name), + } + } +} + + +// ===================================================================================================================== +// Lexer +// ===================================================================================================================== + +// Lazy static initialization for the keywords map +static KEYWORDS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + m.insert("else".to_string(), TokenName::KeywordElse); + m.insert("if".to_string(), TokenName::KeywordIf); + m.insert("print".to_string(), TokenName::KeywordPrint); + m.insert("putc".to_string(), TokenName::KeywordPutc); + m.insert("while".to_string(), TokenName::KeywordWhile); + m +}); + + +struct Lexer<'a> { + s: Scanner<'a>, + source: &'a str, // Keep original source for error slicing if needed + // pre_state is implicitly captured before each token attempt +} + +impl<'a> Lexer<'a> { + fn new(source: &'a str) -> Self { + Lexer { + s: Scanner::new(source), + source, // Store the source string slice + } + } + + // Helper to create a token with current pre-state line/column + fn make_token(&self, name: TokenName, value: TokenVal, line: usize, column: usize) -> Token { + Token { name, value, line, column } + } + + // Helper to create an error token + fn error_token(&mut self, msg: String, code_snippet: &str, line: usize, column: usize) -> Token { + let full_msg = format!("{}\n{:>28}({}, {}): {}", + msg, "", line, column, code_snippet); + + // Ensure we advance past the problematic character(s) if possible + // In many cases, advance() might have already happened within the failing logic. + // If peek is not None, we might advance once more to avoid infinite loops on bad chars. + if self.s.peek().is_some() { + // Be cautious here. C++ version advanced unconditionally. + // Let's only advance if the error didn't consume the char. + // self.s.advance(); // Maybe remove this, depends on exact error logic + } + + self.make_token(TokenName::Error, TokenVal::String(full_msg), line, column) + } + + // Helper for simple single-character tokens + fn simply(&mut self, name: TokenName, line: usize, column: usize) -> Token { + self.s.advance(); + self.make_token(name, TokenVal::None, line, column) + } + + // Helper for tokens like &&, || + fn expect(&mut self, expected: u8, name: TokenName, line: usize, column: usize, start_pos: usize) -> Token { + if self.s.next() == Some(expected) { + self.s.advance(); // Consume the second character + self.make_token(name, TokenVal::None, line, column) + } else { + // Get the single character that caused the error + let snippet = str::from_utf8(&self.s.bytes[start_pos..self.s.pos]) + .unwrap_or(""); // Use slice up to current pos + let current_char = self.s.peek().map_or('?', |b| b as char); // Use peek for error char + self.error_token( + format!("Unrecognized character '{}' after '{}'", current_char, self.s.bytes[start_pos] as char), + snippet, + line, // Error occurs at the original line/col + column, + ) + } + } + + // Helper for tokens like <=, >=, ==, != + fn follow(&mut self, expected: u8, ifyes: TokenName, ifno: TokenName, line: usize, column: usize) -> Token { + if self.s.peek_next() == Some(expected) { + self.s.advance(); // Consume the first char + self.s.advance(); // Consume the second char '=' + self.make_token(ifyes, TokenVal::None, line, column) + } else { + self.s.advance(); // Consume just the first char + self.make_token(ifno, TokenVal::None, line, column) + } + } + + // Handles / or /* ... */ comments + fn divide_or_comment(&mut self, line: usize, column: usize, start_pos: usize) -> Token { + if self.s.peek_next() == Some(b'*') { + // Start of a block comment + self.s.advance(); // Consume '/' + self.s.advance(); // Consume '*' + + loop { + match self.s.peek() { + Some(b'*') => { + if self.s.peek_next() == Some(b'/') { + self.s.advance(); // Consume '*' + self.s.advance(); // Consume '/' + return self.next_token(); // Return the *next* token after comment + } else { + self.s.advance(); // Consume '*' but it wasn't end of comment + } + } + Some(_) => { + self.s.advance(); // Consume character inside comment + } + None => { + // Reached EOF inside comment + let snippet = str::from_utf8(&self.s.bytes[start_pos..self.s.pos]).unwrap_or("/*..."); + return self.error_token( + "End-of-file in comment. Closing '*/' not found.".to_string(), + snippet, + line, // Error reported at comment start + column, + ); + } + } + } + } else { + // Just a division operator + self.s.advance(); // Consume '/' + self.make_token(TokenName::OpDivide, TokenVal::None, line, column) + } + } + + // Handles 'c' character literals -> stored as Integer token + fn char_lit(&mut self, line: usize, column: usize, start_pos: usize) -> Token { + self.s.advance(); // Consume opening ' + + let char_val = match self.s.peek() { + None => return self.error_token("End-of-file in char literal.".to_string(), "'", line, column), + Some(b'\'') => return self.error_token("Empty character constant.".to_string(), "''", line, column), + Some(b'\\') => { // Escape sequence + self.s.advance(); // Consume '\' + match self.s.peek() { + Some(b'n') => { self.s.advance(); b'\n' } + Some(b'\\') => { self.s.advance(); b'\\' } + Some(c) => { + let snippet = format!("'\\{}...", c as char); + // Advance past the unknown escape char before reporting error + self.s.advance(); + return self.error_token(format!("Unknown escape sequence \\{}", c as char), &snippet, line, column); + } + None => return self.error_token("End-of-file after escape in char literal.".to_string(), "'\\", line, column), + } + } + Some(byte) => { // Normal character + self.s.advance(); + byte + } + }; + + // Check for closing quote + if self.s.peek() == Some(b'\'') { + self.s.advance(); // Consume closing ' + self.make_token(TokenName::Integer, TokenVal::Int(char_val as i32), line, column) + } else { + // Find the extent of the invalid literal for the error message + let mut end_pos = self.s.pos; + while let Some(b) = self.s.bytes.get(end_pos) { + if *b == b'\'' || *b == b'\n' || end_pos > start_pos + 10 { // Limit snippet size + break; + } + end_pos += 1; + } + // Consume until the closing quote or newline to avoid cascading errors + while let Some(b) = self.s.peek() { + if b == b'\'' { self.s.advance(); break; } + if b == b'\n' { break; } // Stop at newline + self.s.advance(); + } + + let snippet = str::from_utf8(&self.s.bytes[start_pos..end_pos.min(self.s.bytes.len())]) + .unwrap_or(""); + self.error_token("Multi-character constant or missing closing quote.".to_string(), snippet, line, column) + } + } + + + // Handles "..." string literals + fn string_lit(&mut self, line: usize, column: usize, start_pos: usize) -> Token { + self.s.advance(); // Consume opening " + let mut content: Vec = Vec::new(); + + loop { + match self.s.peek() { + None => { + let snippet = str::from_utf8(&self.s.bytes[start_pos..self.s.pos]).unwrap_or("\"..."); + return self.error_token("End-of-file while scanning string literal. Closing '\"' not found.".to_string(), snippet, line, column); + } + Some(b'"') => { + self.s.advance(); // Consume closing " + // Attempt to convert collected bytes to UTF-8 String + match String::from_utf8(content) { + Ok(s) => return self.make_token(TokenName::String, TokenVal::String(s), line, column), + Err(e) => { + let snippet = str::from_utf8(&self.s.bytes[start_pos..self.s.pos]).unwrap_or(""); + return self.error_token(format!("Invalid UTF-8 sequence in string literal: {}", e), snippet, line, column); + } + } + } + Some(b'\n') => { + let snippet = str::from_utf8(&self.s.bytes[start_pos..self.s.pos]).unwrap_or("\"..."); + // Don't consume newline, error points before it + return self.error_token("End-of-line while scanning string literal. Closing '\"' not found.".to_string(), snippet, self.s.line, self.s.column); // Report error at current line/col + } + Some(b'\\') => { // Escape sequence + self.s.advance(); // Consume '\' + match self.s.peek() { + Some(b'n') => { self.s.advance(); content.push(b'\n'); } + Some(b'\\') => { self.s.advance(); content.push(b'\\'); } + Some(c) => { + let snippet = format!("...\\{}...", c as char); + // Consume the unknown escape char before reporting error + self.s.advance(); + return self.error_token(format!("Unknown escape sequence \\{}", c as char), &snippet, self.s.line, self.s.column); // Use current line/col + } + None => { + let snippet = str::from_utf8(&self.s.bytes[start_pos..self.s.pos]).unwrap_or("\"...\\"); + return self.error_token("End-of-file after escape in string literal.".to_string(), snippet, line, column); + } + } + } + Some(byte) => { // Normal character + content.push(byte); + self.s.advance(); + } + } + } + } + + // Helper predicate functions (using u8 methods) + #[inline] fn is_id_start(c: u8) -> bool { c.is_ascii_alphabetic() || c == b'_' } + #[inline] fn is_id_end(c: u8) -> bool { c.is_ascii_alphanumeric() || c == b'_' } + #[inline] fn is_digit(c: u8) -> bool { c.is_ascii_digit() } + + // Handles identifiers and keywords + fn identifier(&mut self, line: usize, column: usize, start_pos: usize) -> Token { + while let Some(byte) = self.s.peek() { + if Self::is_id_end(byte) { + self.s.advance(); + } else { + break; + } + } + let ident_bytes = self.s.slice(start_pos); + // Identifiers must be valid UTF-8 in Rust + match str::from_utf8(ident_bytes) { + Ok(ident_str) => { + // Check if it's a keyword + if let Some(keyword_token) = KEYWORDS.get(ident_str) { + self.make_token(*keyword_token, TokenVal::None, line, column) + } else { + self.make_token(TokenName::Identifier, TokenVal::String(ident_str.to_string()), line, column) + } + } + Err(_) => { + // This shouldn't happen if is_id_end checks ASCII, but handle defensively + self.error_token("Invalid UTF-8 sequence in identifier.".to_string(), "", line, column) + } + } + } + + + // Handles integer literals + fn integer_lit(&mut self, line: usize, column: usize, start_pos: usize) -> Token { + while let Some(byte) = self.s.peek() { + if Self::is_digit(byte) { + self.s.advance(); + } else { + break; + } + } + + // Check if it's followed by an identifier character (invalid number) + if let Some(byte) = self.s.peek() { + if Self::is_id_start(byte) { + // Consume the invalid part to show in error + while let Some(b) = self.s.peek() { + if Self::is_id_end(b) { self.s.advance(); } else { break; } + } + let snippet = str::from_utf8(self.s.slice(start_pos)).unwrap_or(""); + return self.error_token("Invalid number. Contains non-numeric characters.".to_string(), snippet, line, column); + } + } + + + let num_bytes = self.s.slice(start_pos); + match str::from_utf8(num_bytes) { + Ok(num_str) => { + match num_str.parse::() { + Ok(n) => self.make_token(TokenName::Integer, TokenVal::Int(n), line, column), + Err(e) => { + // Could be overflow or other parse error + let snippet = str::from_utf8(num_bytes).unwrap_or(""); + let msg = if e.kind() == &std::num::IntErrorKind::PosOverflow || e.kind() == &std::num::IntErrorKind::NegOverflow { + "Number exceeds maximum value.".to_string() + } else { + format!("Invalid integer literal: {}", e) + }; + self.error_token(msg, snippet, line, column) + } + } + } + Err(_) => { + // Should not happen for digits, but handle defensively + self.error_token("Invalid UTF-8 sequence in number.".to_string(), "", line, column) + } + } + } + + // Get the next token from the input stream + pub fn next_token(&mut self) -> Token { + self.s.skip_whitespace(); + + // Capture state *before* processing the token + let pre_line = self.s.line; + let pre_column = self.s.column; + let start_pos = self.s.pos; // Start byte position of the token + + // Use peek() to decide what kind of token comes next + match self.s.peek() { + Some(b'*') => self.simply(TokenName::OpMultiply, pre_line, pre_column), + Some(b'%') => self.simply(TokenName::OpMod, pre_line, pre_column), + Some(b'+') => self.simply(TokenName::OpAdd, pre_line, pre_column), + Some(b'-') => self.simply(TokenName::OpSubtract, pre_line, pre_column), + Some(b'{') => self.simply(TokenName::LeftBrace, pre_line, pre_column), + Some(b'}') => self.simply(TokenName::RightBrace, pre_line, pre_column), + Some(b'(') => self.simply(TokenName::LeftParen, pre_line, pre_column), + Some(b')') => self.simply(TokenName::RightParen, pre_line, pre_column), + Some(b';') => self.simply(TokenName::Semicolon, pre_line, pre_column), + Some(b',') => self.simply(TokenName::Comma, pre_line, pre_column), + + Some(b'&') => self.expect(b'&', TokenName::OpAnd, pre_line, pre_column, start_pos), + Some(b'|') => self.expect(b'|', TokenName::OpOr, pre_line, pre_column, start_pos), + + Some(b'<') => self.follow(b'=', TokenName::OpLessEqual, TokenName::OpLess, pre_line, pre_column), + Some(b'>') => self.follow(b'=', TokenName::OpGreaterEqual, TokenName::OpGreater, pre_line, pre_column), + Some(b'=') => self.follow(b'=', TokenName::OpEqual, TokenName::OpAssign, pre_line, pre_column), + Some(b'!') => self.follow(b'=', TokenName::OpNotEqual, TokenName::OpNot, pre_line, pre_column), + + Some(b'/') => self.divide_or_comment(pre_line, pre_column, start_pos), + Some(b'\'') => self.char_lit(pre_line, pre_column, start_pos), + Some(b'"') => self.string_lit(pre_line, pre_column, start_pos), + + Some(c) if Self::is_id_start(c) => self.identifier(pre_line, pre_column, start_pos), + Some(c) if Self::is_digit(c) => self.integer_lit(pre_line, pre_column, start_pos), + + Some(c) => { + // Unrecognized character + let snippet = str::from_utf8(&self.s.bytes[start_pos ..= start_pos]).unwrap_or("?"); // Just the char + self.s.advance(); // Consume the bad character + self.error_token(format!("Unrecognized character '{}'", c as char), snippet, pre_line, pre_column) + } + + None => self.make_token(TokenName::EndOfInput, TokenVal::None, pre_line, pre_column), + } + } + + // Check if there are more characters (excluding EOF) + pub fn has_more(&self) -> bool { + self.s.peek().is_some() + } +} + +// ===================================================================================================================== +// Main Function +// ===================================================================================================================== +fn run_lexer(input: String) -> Result { + let mut lexer = Lexer::new(&input); // Pass input by reference + let mut output = String::new(); + + output.push_str("Location Token name Value\n"); + output.push_str("--------------------------------------\n"); + + let mut token = lexer.next_token(); + loop { + output.push_str(&format!("{}\n", token)); // Use the Display impl for Token + + if token.name == TokenName::EndOfInput || token.name == TokenName::Error { + // If it's an error token, we might stop or continue depending on desired behavior. + // This version stops on the first error or EOF. + if token.name == TokenName::Error { + // Optionally, return an error instead of just stopping the output string + // return Err(LexerError::Generic(format!("Lexing failed at line {}, column {}", token.line, token.column))); + } + break; + } + + token = lexer.next_token(); + } + + Ok(output) +} + +fn main() { + let args: Vec = env::args().collect(); + let in_path = args.get(1).map_or("stdin", |s| s.as_str()); + let out_path = args.get(2).map_or("stdout", |s| s.as_str()); + + if let Err(e) = with_io(in_path, out_path, run_lexer) { + eprintln!("Error: {}", e); + process::exit(1); + } +} diff --git a/Task/Compiler-syntax-analyzer/FreeBASIC/compiler-syntax-analyzer.basic b/Task/Compiler-syntax-analyzer/FreeBASIC/compiler-syntax-analyzer.basic new file mode 100644 index 0000000000..9775c3616a --- /dev/null +++ b/Task/Compiler-syntax-analyzer/FreeBASIC/compiler-syntax-analyzer.basic @@ -0,0 +1,370 @@ +#define BUFFER_SIZE 4096 + +' Token constants +Enum TokensCtes + tk_EOI, tk_Mul, tk_Div, tk_Mod, tk_Add, tk_Sub, tk_Negate, tk_Not, tk_Lss, tk_Leq, tk_Gtr + tk_Geq, tk_Eql, tk_Neq, tk_Assign, tk_And, tk_Or, tk_If, tk_Else, tk_While, tk_Print + tk_Putc, tk_Lparen, tk_Rparen, tk_Lbrace, tk_Rbrace, tk_Semi, tk_Comma, tk_Ident + tk_Integer, tk_String +End Enum + +' Node types +Enum NodeTypes + nd_Ident, nd_String, nd_Integer, nd_Sequence, nd_If, nd_Prtc, nd_Prts, nd_Prti, nd_While + nd_Assign, nd_Negate, nd_Not, nd_Mul, nd_Div, nd_Mod, nd_Add, nd_Sub, nd_Lss, nd_Leq + nd_Gtr, nd_Geq, nd_Eql, nd_Neq, nd_And, nd_Or +End Enum + +' Token info structure +Type TokenInfo + nombre As String + rightAssoc As Boolean + isBinary As Boolean + isUnary As Boolean + precedence As Integer + nodeType As Integer + Declare Constructor() + Declare Constructor(n As String, ra As Boolean, ib As Boolean, iu As Boolean, p As Integer, nt As Integer) +End Type + +Constructor TokenInfo() + nombre = "" + rightAssoc = False + isBinary = False + isUnary = False + precedence = 0 + nodeType = 0 +End Constructor + +Constructor TokenInfo(n As String, ra As Boolean, ib As Boolean, iu As Boolean, p As Integer, nt As Integer) + nombre = n + rightAssoc = ra + isBinary = ib + isUnary = iu + precedence = p + nodeType = nt +End Constructor + +' Node structure +Type Node + nodeType As Integer + izda As Node Ptr + dcha As Node Ptr + value As String +End Type + +' Global variables +Dim Shared As Integer ff, errLine, errCol, tok +Dim Shared As String tokText, tokOther +Dim Shared As TokenInfo tokens(30) + +Declare Function ParseExpr(p As Integer) As Node Ptr + +' Initialize token info +Sub InitTokens() + tokens(tk_EOI) = TokenInfo("EOI", False, False, False, -1, -1) + tokens(tk_Mul) = TokenInfo("*", False, True, False, 13, nd_Mul) + tokens(tk_Div) = TokenInfo("/", False, True, False, 13, nd_Div) + tokens(tk_Mod) = TokenInfo("%", False, True, False, 13, nd_Mod) + tokens(tk_Add) = TokenInfo("+", False, True, False, 12, nd_Add) + tokens(tk_Sub) = TokenInfo("-", False, True, False, 12, nd_Sub) + tokens(tk_Negate) = TokenInfo("-", False, False, True, 14, nd_Negate) + tokens(tk_Not) = TokenInfo("!", False, False, True, 14, nd_Not) + tokens(tk_Lss) = TokenInfo("<", False, True, False, 10, nd_Lss) + tokens(tk_Leq) = TokenInfo("<=", False, True, False, 10, nd_Leq) + tokens(tk_Gtr) = TokenInfo(">", False, True, False, 10, nd_Gtr) + tokens(tk_Geq) = TokenInfo(">=", False, True, False, 10, nd_Geq) + tokens(tk_Eql) = TokenInfo("==", False, True, False, 9, nd_Eql) + tokens(tk_Neq) = TokenInfo("!=", False, True, False, 9, nd_Neq) + tokens(tk_Assign) = TokenInfo("=", False, False, False, -1, nd_Assign) + tokens(tk_And) = TokenInfo("&&", False, True, False, 5, nd_And) + tokens(tk_Or) = TokenInfo("||", False, True, False, 4, nd_Or) + tokens(tk_If) = TokenInfo("if", False, False, False, -1, nd_If) + tokens(tk_Else) = TokenInfo("else", False, False, False, -1, -1) + tokens(tk_While) = TokenInfo("while", False, False, False, -1, nd_While) + tokens(tk_Print) = TokenInfo("print", False, False, False, -1, -1) + tokens(tk_Putc) = TokenInfo("putc", False, False, False, -1, -1) + tokens(tk_Lparen) = TokenInfo("(", False, False, False, -1, -1) + tokens(tk_Rparen) = TokenInfo(")", False, False, False, -1, -1) + tokens(tk_Lbrace) = TokenInfo("{", False, False, False, -1, -1) + tokens(tk_Rbrace) = TokenInfo("}", False, False, False, -1, -1) + tokens(tk_Semi) = TokenInfo(";", False, False, False, -1, -1) + tokens(tk_Comma) = TokenInfo(",", False, False, False, -1, -1) + tokens(tk_Ident) = TokenInfo("Ident", False, False, False, -1, nd_Ident) + tokens(tk_Integer) = TokenInfo("Integer", False, False, False, -1, nd_Integer) + tokens(tk_String) = TokenInfo("String", False, False, False, -1, nd_String) +End Sub + +' show error and exit +Sub ShowError(msg As String) + Print "(" & errLine & ", " & errCol & ") " & msg + End 1 +End Sub + +' Get next token +Sub GetToken() + Static As String linea + If Eof(ff) Then + tok = tk_EOI + Exit Sub + End If + Line Input #ff, linea + If Len(linea) = 0 Then ShowError("empty line") + + Dim As Integer numParts = 0 + Dim As String parts(0 To 3) + Dim As String currentPart = "" + Dim As Boolean inQuotes = False + + For i As Integer = 1 To Len(linea) + Dim As String c = Mid(linea, i, 1) + If c = """" Then + inQuotes = Not inQuotes + currentPart &= c + Elseif (Cbool((c = " ") Or (c = Chr(9))) Andalso (inQuotes = False)) Then + If Len(currentPart) > 0 Then + parts(numParts) = currentPart + numParts += 1 + currentPart = "" + End If + Else + currentPart &= c + End If + Next + If Len(currentPart) > 0 Then + parts(numParts) = currentPart + numParts += 1 + End If + + errLine = Valint(parts(0)) + errCol = Valint(parts(1)) + tokText = parts(2) + tok = -1 + + Select Case tokText + Case "End_of_input": tok = tk_EOI + Case "Op_multiply": tok = tk_Mul + Case "Op_divide": tok = tk_Div + Case "Op_mod": tok = tk_Mod + Case "Op_add": tok = tk_Add + Case "Op_subtract": tok = tk_Sub + Case "Op_negate": tok = tk_Negate + Case "Op_not": tok = tk_Not + Case "Op_less": tok = tk_Lss + Case "Op_lessequal": tok = tk_Leq + Case "Op_greater": tok = tk_Gtr + Case "Op_greaterequal":tok = tk_Geq + Case "Op_equal": tok = tk_Eql + Case "Op_notequal": tok = tk_Neq + Case "Op_assign": tok = tk_Assign + Case "Op_and": tok = tk_And + Case "Op_or": tok = tk_Or + Case "Keyword_if": tok = tk_If + Case "Keyword_else": tok = tk_Else + Case "Keyword_while": tok = tk_While + Case "Keyword_print": tok = tk_Print + Case "Keyword_putc": tok = tk_Putc + Case "LeftParen": tok = tk_Lparen + Case "RightParen": tok = tk_Rparen + Case "LeftBrace": tok = tk_Lbrace + Case "RightBrace": tok = tk_Rbrace + Case "Semicolon": tok = tk_Semi + Case "Comma": tok = tk_Comma + Case "Identifier": tok = tk_Ident + Case "Integer": tok = tk_Integer + Case "String": tok = tk_String + End Select + + If tok = -1 Then ShowError("Unknown token " & tokText) + If tok = tk_Integer Or tok = tk_Ident Or tok = tk_String Then + tokOther = Iif(numParts >= 4, parts(3), "") + End If +End Sub + +' Create nodes +Function MakeNode(nodeType As Integer, izda As Node Ptr = 0, dcha As Node Ptr = 0) As Node Ptr + Dim As Node Ptr n = New Node + With *n + .nodeType = nodeType + .izda = izda + .dcha = dcha + .value = "" + End With + + Return n +End Function + +Function MakeLeaf(nodeType As Integer, value As String) As Node Ptr + Dim As Node Ptr n = New Node + n->nodeType = nodeType + n->izda = 0 + n->dcha = 0 + n->value = value + + Return n +End Function + +Sub Expect(msg As String, s As Integer) + If tok = s Then + GetToken() + Else + ShowError(msg & ": Expecting '" & tokens(s).nombre & "', found '" & tokens(tok).nombre & "'") + End If +End Sub + +' Main parsing functions +Function ParenExpr() As Node Ptr + Expect("paren_expr", tk_Lparen) + Dim As Node Ptr node = ParseExpr(0) + Expect("paren_expr", tk_Rparen) + + Return node +End Function + +Function ParseExpr(p As Integer) As Node Ptr + Dim As Node Ptr x = 0, node + Dim As Integer op, q + + Select Case tok + Case tk_Lparen + x = ParenExpr() + Case tk_Sub, tk_Add + op = Iif(tok = tk_Sub, tk_Negate, tk_Add) + GetToken() + node = ParseExpr(tokens(tk_Negate).precedence) + x = Iif(op = tk_Negate, MakeNode(nd_Negate, node), node) + Case tk_Not + GetToken() + x = MakeNode(nd_Not, ParseExpr(tokens(tk_Not).precedence)) + Case tk_Ident + x = MakeLeaf(nd_Ident, tokOther) + GetToken() + Case tk_Integer + x = MakeLeaf(nd_Integer, tokOther) + GetToken() + Case Else + ShowError("Expecting a primary, found: " & tokens(tok).nombre) + End Select + + While tokens(tok).isBinary Andalso tokens(tok).precedence >= p + op = tok + GetToken() + q = tokens(op).precedence + If Not tokens(op).rightAssoc Then q += 1 + node = ParseExpr(q) + x = MakeNode(tokens(op).nodeType, x, node) + Wend + + Return x +End Function + +Function ParseStmt() As Node Ptr + Dim As Node Ptr t = 0, e + + Select Case tok + Case tk_If + GetToken() + e = ParenExpr() + Dim As Node Ptr s = ParseStmt() + Dim As Node Ptr s2 = 0 + If tok = tk_Else Then + GetToken() + s2 = ParseStmt() + End If + t = MakeNode(nd_If, e, MakeNode(nd_If, s, s2)) + Case tk_Putc + GetToken() + e = ParenExpr() + t = MakeNode(nd_Prtc, e) + Expect("Putc", tk_Semi) + Case tk_Print + GetToken() + Expect("Print", tk_Lparen) + Do + If tok = tk_String Then + e = MakeNode(nd_Prts, MakeLeaf(nd_String, tokOther)) + GetToken() + Else + e = MakeNode(nd_Prti, ParseExpr(0)) + End If + t = MakeNode(nd_Sequence, t, e) + If tok <> tk_Comma Then Exit Do + GetToken() + Loop + Expect("Print", tk_Rparen) + Expect("Print", tk_Semi) + Case tk_Semi + GetToken() + Case tk_Ident + Dim As Node Ptr v = MakeLeaf(nd_Ident, tokOther) + GetToken() + Expect("assign", tk_Assign) + e = ParseExpr(0) + t = MakeNode(nd_Assign, v, e) + Expect("assign", tk_Semi) + Case tk_While + GetToken() + e = ParenExpr() + Dim As Node Ptr s = ParseStmt() + t = MakeNode(nd_While, e, s) + Case tk_Lbrace + GetToken() + While tok <> tk_Rbrace Andalso tok <> tk_EOI + t = MakeNode(nd_Sequence, t, ParseStmt()) + Wend + Expect("Lbrace", tk_Rbrace) + Case tk_EOI + ' Do nothing + Case Else + ShowError("Expecting start of statement, found: " & tokens(tok).nombre) + End Select + + Return t +End Function + +Function Parse() As Node Ptr + Dim As Node Ptr tree = 0 + + GetToken() + While tok <> tk_EOI + tree = MakeNode(nd_Sequence, tree, ParseStmt()) + Wend + + Return tree +End Function + +Sub PrintAST(t As Node Ptr) + Dim As String displayNodes(24) = { _ + "Identifier","String","Integer","Sequence","If","Prtc", _ + "Prts","Prti","While","Assign","Negate","Not","Multiply","Divide","Mod", _ + "Add","Subtract","Less","LessEqual","Greater","GreaterEqual","Equal", _ + "NotEqual","And","Or" } + + If t = 0 Then + Print ";" + Else + Print Left(displayNodes(t->nodeType) & Space(14), 14); + Select Case t->nodeType + Case nd_Ident, nd_Integer, nd_String + Print t->value + Case Else + Print + PrintAST(t->izda) + PrintAST(t->dcha) + End Select + End If +End Sub + +' Main program +InitTokens() +If Command(1) <> "" Then + ff = Freefile + Open Command(1) For Input Access Read As #ff Len = BUFFER_SIZE +Else + ff = 1 ' stdin +End If + +Dim As Node Ptr ast = Parse() +PrintAST(ast) + +Sleep diff --git a/Task/Compiler-syntax-analyzer/M2000-Interpreter/compiler-syntax-analyzer.m2000 b/Task/Compiler-syntax-analyzer/M2000-Interpreter/compiler-syntax-analyzer.m2000 index 388b820e8b..1b0a6c5166 100644 --- a/Task/Compiler-syntax-analyzer/M2000-Interpreter/compiler-syntax-analyzer.m2000 +++ b/Task/Compiler-syntax-analyzer/M2000-Interpreter/compiler-syntax-analyzer.m2000 @@ -97,7 +97,7 @@ Module syntax_analyzer(b$){ sub stmt(&op) local t=(,) if op=Identifier then - t=(line$) + t=(line$,) getone(&op) expected(Op_assign) getone(&op) diff --git a/Task/Compiler-syntax-analyzer/Rust/compiler-syntax-analyzer.rs b/Task/Compiler-syntax-analyzer/Rust/compiler-syntax-analyzer.rs new file mode 100644 index 0000000000..d50b2f14a7 --- /dev/null +++ b/Task/Compiler-syntax-analyzer/Rust/compiler-syntax-analyzer.rs @@ -0,0 +1,659 @@ +// src/main.rs + +use std::env; +use std::fs::File; +use std::io::{self, prelude::*, BufReader, BufWriter, Lines}; +use std::process::exit; +use std::collections::HashMap; // For potentially faster token lookup if needed + +// --- Enums --- + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] // Added Hash for HashMap key +pub enum TokenType { + Eoi, Mul, Div, Mod, Add, Sub, Negate, Not, Lss, Leq, Gtr, + Geq, Eql, Neq, Assign, And, Or, If, Else, While, Print, + Putc, Lparen, Rparen, Lbrace, Rbrace, Semi, Comma, Ident, + Integer, String, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum NodeType { + Ident, String, Integer, Sequence, If, Prtc, Prts, Prti, While, + Assign, Negate, Not, Mul, Div, Mod, Add, Sub, Lss, Leq, + Gtr, Geq, Eql, Neq, And, Or, +} + +// --- Structs --- + +#[derive(Debug, Clone)] +pub struct Token { + tok_type: TokenType, + err_ln: usize, + err_col: usize, + text: Option, // Use Option for optional text +} + +#[derive(Debug, Clone)] +pub struct AstNode { + node_type: NodeType, + // Use Option> for optional, heap-allocated children + left: Option>, + right: Option>, + // Use Option for optional value (ident, literal) + value: Option, +} + +#[derive(Debug)] +pub struct TokenAttributes { + text: &'static str, + enum_text: &'static str, + tok_type: TokenType, + right_associative: bool, + is_binary: bool, + is_unary: bool, + precedence: Option, // Use Option for precedence (-1 in C) + node_type: Option, // Use Option for node type (-1 in C) +} + +// --- Static Data --- + +// Use 'static lifetime for compile-time constants +// Order MUST match TokenType enum definition +const TOKEN_ATTRIBUTES: &[TokenAttributes] = &[ + TokenAttributes { text: "EOI", enum_text: "End_of_input", tok_type: TokenType::Eoi, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: "*", enum_text: "Op_multiply", tok_type: TokenType::Mul, right_associative: false, is_binary: true, is_unary: false, precedence: Some(13), node_type: Some(NodeType::Mul) }, + TokenAttributes { text: "/", enum_text: "Op_divide", tok_type: TokenType::Div, right_associative: false, is_binary: true, is_unary: false, precedence: Some(13), node_type: Some(NodeType::Div) }, + TokenAttributes { text: "%", enum_text: "Op_mod", tok_type: TokenType::Mod, right_associative: false, is_binary: true, is_unary: false, precedence: Some(13), node_type: Some(NodeType::Mod) }, + TokenAttributes { text: "+", enum_text: "Op_add", tok_type: TokenType::Add, right_associative: false, is_binary: true, is_unary: false, precedence: Some(12), node_type: Some(NodeType::Add) }, + TokenAttributes { text: "-", enum_text: "Op_subtract", tok_type: TokenType::Sub, right_associative: false, is_binary: true, is_unary: false, precedence: Some(12), node_type: Some(NodeType::Sub) }, + TokenAttributes { text: "-", enum_text: "Op_negate", tok_type: TokenType::Negate, right_associative: false, is_binary: false, is_unary: true, precedence: Some(14), node_type: Some(NodeType::Negate) }, // NOTE: C code listed Sub/Add precedence here, but Negate makes more sense + TokenAttributes { text: "!", enum_text: "Op_not", tok_type: TokenType::Not, right_associative: false, is_binary: false, is_unary: true, precedence: Some(14), node_type: Some(NodeType::Not) }, + TokenAttributes { text: "<", enum_text: "Op_less", tok_type: TokenType::Lss, right_associative: false, is_binary: true, is_unary: false, precedence: Some(10), node_type: Some(NodeType::Lss) }, + TokenAttributes { text: "<=", enum_text: "Op_lessequal", tok_type: TokenType::Leq, right_associative: false, is_binary: true, is_unary: false, precedence: Some(10), node_type: Some(NodeType::Leq) }, + TokenAttributes { text: ">", enum_text: "Op_greater", tok_type: TokenType::Gtr, right_associative: false, is_binary: true, is_unary: false, precedence: Some(10), node_type: Some(NodeType::Gtr) }, + TokenAttributes { text: ">=", enum_text: "Op_greaterequal", tok_type: TokenType::Geq, right_associative: false, is_binary: true, is_unary: false, precedence: Some(10), node_type: Some(NodeType::Geq) }, + TokenAttributes { text: "==", enum_text: "Op_equal", tok_type: TokenType::Eql, right_associative: false, is_binary: true, is_unary: false, precedence: Some(9), node_type: Some(NodeType::Eql) }, + TokenAttributes { text: "!=", enum_text: "Op_notequal", tok_type: TokenType::Neq, right_associative: false, is_binary: true, is_unary: false, precedence: Some(9), node_type: Some(NodeType::Neq) }, + TokenAttributes { text: "=", enum_text: "Op_assign", tok_type: TokenType::Assign, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: Some(NodeType::Assign) }, // Assignment is special, not a standard binary op in expr parsing + TokenAttributes { text: "&&", enum_text: "Op_and", tok_type: TokenType::And, right_associative: false, is_binary: true, is_unary: false, precedence: Some(5), node_type: Some(NodeType::And) }, + TokenAttributes { text: "||", enum_text: "Op_or", tok_type: TokenType::Or, right_associative: false, is_binary: true, is_unary: false, precedence: Some(4), node_type: Some(NodeType::Or) }, + TokenAttributes { text: "if", enum_text: "Keyword_if", tok_type: TokenType::If, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: Some(NodeType::If) }, + TokenAttributes { text: "else", enum_text: "Keyword_else", tok_type: TokenType::Else, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: "while", enum_text: "Keyword_while", tok_type: TokenType::While, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: Some(NodeType::While) }, + TokenAttributes { text: "print", enum_text: "Keyword_print", tok_type: TokenType::Print, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: "putc", enum_text: "Keyword_putc", tok_type: TokenType::Putc, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: "(", enum_text: "LeftParen", tok_type: TokenType::Lparen, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: ")", enum_text: "RightParen", tok_type: TokenType::Rparen, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: "{", enum_text: "LeftBrace", tok_type: TokenType::Lbrace, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: "}", enum_text: "RightBrace", tok_type: TokenType::Rbrace, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: ";", enum_text: "Semicolon", tok_type: TokenType::Semi, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: ",", enum_text: "Comma", tok_type: TokenType::Comma, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: None }, + TokenAttributes { text: "Ident", enum_text: "Identifier", tok_type: TokenType::Ident, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: Some(NodeType::Ident) }, + TokenAttributes { text: "Integer literal", enum_text: "Integer", tok_type: TokenType::Integer, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: Some(NodeType::Integer) }, + TokenAttributes { text: "String literal", enum_text: "String", tok_type: TokenType::String, right_associative: false, is_binary: false, is_unary: false, precedence: None, node_type: Some(NodeType::String) }, +]; + +// Create a lazy-initialized HashMap for faster lookup by enum_text +use lazy_static::lazy_static; // Add `lazy_static = "1.4.0"` to Cargo.toml +lazy_static! { + static ref TOKEN_MAP_BY_ENUM_TEXT: HashMap<&'static str, &'static TokenAttributes> = { + let mut m = HashMap::new(); + for attr in TOKEN_ATTRIBUTES { + m.insert(attr.enum_text, attr); + } + m + }; + static ref TOKEN_MAP_BY_TYPE: HashMap = { + let mut m = HashMap::new(); + for attr in TOKEN_ATTRIBUTES { + m.insert(attr.tok_type, attr); + } + m + }; +} + + +const DISPLAY_NODES: &[&str] = &[ + "Identifier", "String", "Integer", "Sequence", "If", "Prtc", + "Prts", "Prti", "While", "Assign", "Negate", "Not", "Multiply", "Divide", "Mod", + "Add", "Subtract", "Less", "LessEqual", "Greater", "GreaterEqual", "Equal", + "NotEqual", "And", "Or", +]; + +// --- Error Handling --- + +#[derive(Debug)] +pub enum ParseError { + Io(io::Error), + UnexpectedToken { + expected: String, // Can describe expected category or specific token + found: Token, + context: &'static str, + }, + InvalidTokenFormat(usize, String), // line_num, line_content + UnknownTokenName(String), + EndOfInput, + Custom(String), +} + +// Allow converting io::Error into ParseError +impl From for ParseError { + fn from(err: io::Error) -> Self { + ParseError::Io(err) + } +} + +impl std::fmt::Display for ParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ParseError::Io(err) => write!(f, "I/O Error: {}", err), + ParseError::UnexpectedToken { expected, found, context } => { + let found_attr = TOKEN_MAP_BY_TYPE.get(&found.tok_type).map_or("?", |a| a.text); + write!( + f, + "({}, {}) Parse Error in {}: Expected {}, found '{}' ({:?})", + found.err_ln, found.err_col, context, expected, found_attr, found.tok_type + ) + } + ParseError::InvalidTokenFormat(line_num, line) => { + write!(f, "Invalid token format on line {}: '{}'", line_num, line) + } + ParseError::UnknownTokenName(name) => write!(f, "Unknown token name: {}", name), + ParseError::EndOfInput => write!(f, "Unexpected end of input"), + ParseError::Custom(msg) => write!(f, "Error: {}", msg), + } + } +} + +impl std::error::Error for ParseError {} + +type ParseResult = Result; + +// --- Helper Functions --- + +fn get_token_attr(token_type: TokenType) -> &'static TokenAttributes { + // Using HashMap lookup now + TOKEN_MAP_BY_TYPE.get(&token_type) + .unwrap_or_else(|| panic!("Internal error: Missing attributes for token type {:?}", token_type)) // Should not happen if maps are correct +} + +fn make_node(node_type: NodeType, left: Option>, right: Option>) -> Box { + Box::new(AstNode { + node_type, + left, + right, + value: None, + }) +} + +fn make_leaf(node_type: NodeType, value: String) -> Box { + Box::new(AstNode { + node_type, + left: None, + right: None, + value: Some(value), + }) +} + + +// --- Parser Struct --- + +struct Parser { + // Use Lines iterator for easy line reading + lines: Lines, + current_line_num: usize, + // Store the *next* token to be processed (lookahead) + current_token: Token, +} + +impl Parser { + fn new(reader: R) -> ParseResult { + let mut parser = Parser { + lines: reader.lines(), + current_line_num: 0, + // Initialize with a dummy EOI token before the first read + current_token: Token { + tok_type: TokenType::Eoi, + err_ln: 0, + err_col: 0, + text: None, + }, + }; + // Read the first actual token + parser.next_token()?; + Ok(parser) + } + + // Reads the next line and parses it into a token, updating self.current_token + fn next_token(&mut self) -> ParseResult<()> { + match self.lines.next() { + Some(Ok(line)) => { + self.current_line_num += 1; + let trimmed_line = line.trim_end(); // Keep original line for error msg + if trimmed_line.is_empty() { + // Skip empty lines potentially introduced by trimming or blank lines + return self.next_token(); + } + + let mut parts = trimmed_line.splitn(4, |c: char| c.is_whitespace()); + + let err_ln_str = parts.next(); + let err_col_str = parts.next(); + let name_str = parts.next(); + let remaining = parts.next().unwrap_or("").trim_start(); // Rest of the line is optional value + + + // Use if let for cleaner parsing and error handling + if let (Some(ln_s), Some(col_s), Some(name)) = (err_ln_str, err_col_str, name_str) { + let err_ln = ln_s.parse::() + .map_err(|_| ParseError::InvalidTokenFormat(self.current_line_num, line.clone()))?; + let err_col = col_s.parse::() + .map_err(|_| ParseError::InvalidTokenFormat(self.current_line_num, line.clone()))?; + + // Lookup token type from name + let attributes = TOKEN_MAP_BY_ENUM_TEXT.get(name) + .ok_or_else(|| ParseError::UnknownTokenName(name.to_string()))?; + + let text = if !remaining.is_empty() { + Some(remaining.to_string()) + } else { + None + }; + + self.current_token = Token { + tok_type: attributes.tok_type, + err_ln, + err_col, + text, + }; + Ok(()) + + } else { + Err(ParseError::InvalidTokenFormat(self.current_line_num, line)) + } + } + Some(Err(e)) => Err(ParseError::Io(e)), + None => { + // End of input, set token to EOI + self.current_token = Token { + tok_type: TokenType::Eoi, + // Use last known line/col or defaults if file was empty + err_ln: self.current_token.err_ln, + err_col: self.current_token.err_col, + text: None, + }; + Ok(()) + } + } + } + + // Check current token type, consume it if it matches, otherwise return error + fn expect(&mut self, expected: TokenType, context: &'static str) -> ParseResult<()> { + if self.current_token.tok_type == expected { + self.next_token()?; + Ok(()) + } else { + Err(ParseError::UnexpectedToken { + expected: format!("'{}' ({:?})", get_token_attr(expected).text, expected), + found: self.current_token.clone(), // Clone token for error reporting + context, + }) + } + } + + // Check current token type *without* consuming it + fn check(&self, expected: TokenType) -> bool { + self.current_token.tok_type == expected + } + + // Get the current token's text value, expecting it to exist + fn consume_text(&mut self, context: &'static str) -> ParseResult { + let token = self.current_token.clone(); // Clone before consuming + let text = token.text.ok_or_else(|| ParseError::Custom( + format!("({},{}) Expected text value for token {:?} in {}", + token.err_ln, token.err_col, token.tok_type, context) + ))?; + self.next_token()?; // Consume the token + Ok(text) + } + + + // --- Parsing Methods (Expression & Statement) --- + + // expr: Parse expressions using precedence climbing + fn expr(&mut self, min_precedence: u8) -> ParseResult> { + let mut left = self.parse_primary()?; + + // Precedence climbing loop + loop { + let current_tok_type = self.current_token.tok_type; + let current_attr = get_token_attr(current_tok_type); + + // Stop if token is not a binary operator OR its precedence is too low + if !current_attr.is_binary || current_attr.precedence.unwrap_or(0) < min_precedence { + break; + } + + let op_type = current_tok_type; + let precedence = current_attr.precedence.unwrap(); // Known because is_binary is true + let node_type = current_attr.node_type.expect("Binary operator must have node type"); + + // Consume operator token + self.next_token()?; + + // Determine precedence for recursive call (handle associativity) + let next_min_precedence = if current_attr.right_associative { + precedence + } else { + precedence + 1 + }; + + let right = self.expr(next_min_precedence)?; + left = make_node(node_type, Some(left), Some(right)); + } + + Ok(left) + } + + // Parse primary expressions (literals, identifiers, unary ops, parentheses) + fn parse_primary(&mut self) -> ParseResult> { + let token = self.current_token.clone(); // Clone token info before consuming + + match token.tok_type { + TokenType::Lparen => self.paren_expr(), + TokenType::Sub | TokenType::Add => { // Unary +/- + self.next_token()?; // Consume '-' or '+' + let node = self.expr(get_token_attr(TokenType::Negate).precedence.unwrap())?; // Use Negate's precedence + if token.tok_type == TokenType::Sub { + Ok(make_node(NodeType::Negate, Some(node), None)) + } else { + Ok(node) // Unary plus is identity + } + } + TokenType::Not => { // Unary ! + self.next_token()?; // Consume '!' + let node = self.expr(get_token_attr(TokenType::Not).precedence.unwrap())?; + Ok(make_node(NodeType::Not, Some(node), None)) + } + TokenType::Ident => { + let ident_name = self.consume_text("identifier")?; + Ok(make_leaf(NodeType::Ident, ident_name)) + } + TokenType::Integer => { + let int_val = self.consume_text("integer literal")?; + Ok(make_leaf(NodeType::Integer, int_val)) + } + // String literals only appear in 'print' in this grammar? + // If they could be primary expressions, add: + // TokenType::String => { + // let str_val = self.consume_text("string literal")?; + // Ok(make_leaf(NodeType::String, str_val)) + // } + _ => Err(ParseError::UnexpectedToken{ + expected: "primary expression (literal, identifier, unary op, or '(')".to_string(), + found: token, + context: "expr", + }), + } + } + + // paren_expr: Parse parenthesized expressions + fn paren_expr(&mut self) -> ParseResult> { + self.expect(TokenType::Lparen, "paren_expr start")?; + let node = self.expr(0)?; // Start with lowest precedence inside parens + self.expect(TokenType::Rparen, "paren_expr end")?; + Ok(node) + } + + // stmt: Parse a single statement + // Returns Option> because ';' might result in no node + fn stmt(&mut self) -> ParseResult>> { + match self.current_token.tok_type { + TokenType::If => { + self.next_token()?; // Consume 'if' + let condition = self.paren_expr()?; + let then_branch = self.stmt()?.ok_or_else(|| ParseError::Custom( + "Expected statement after 'if' condition".to_string() + ))?; // If requires a statement + + let else_branch = if self.check(TokenType::Else) { + self.next_token()?; // Consume 'else' + Some(self.stmt()?.ok_or_else(|| ParseError::Custom( + "Expected statement after 'else'".to_string() + ))?) + } else { + None + }; + + // Structure: If(condition, If(then, else)) - mimics C structure + let if_node = make_node(NodeType::If, Some(then_branch), else_branch); + Ok(Some(make_node(NodeType::If, Some(condition), Some(if_node)))) + } + TokenType::Putc => { + self.next_token()?; // Consume 'putc' + let arg = self.paren_expr()?; + let node = make_node(NodeType::Prtc, Some(arg), None); + self.expect(TokenType::Semi, "putc statement")?; + Ok(Some(node)) + } + TokenType::Print => { + self.next_token()?; // Consume 'print' + self.expect(TokenType::Lparen, "print statement start")?; + + let mut sequence: Option> = None; + + loop { + let expr_node = if self.check(TokenType::String) { + let str_val = self.consume_text("print string literal")?; + make_node(NodeType::Prts, Some(make_leaf(NodeType::String, str_val)), None) + } else { + make_node(NodeType::Prti, Some(self.expr(0)?), None) + }; + + // Build sequence: Sequence(prev_sequence, current_print_expr) + sequence = Some(make_node(NodeType::Sequence, sequence, Some(expr_node))); + + if !self.check(TokenType::Comma) { + break; // Exit loop if no more commas + } + self.next_token()?; // Consume ',' + } + + self.expect(TokenType::Rparen, "print statement end")?; + self.expect(TokenType::Semi, "print statement")?; + Ok(sequence) // Return the sequence of print nodes + } + TokenType::Semi => { + self.next_token()?; // Consume ';' + Ok(None) // Empty statement produces no node + } + TokenType::Ident => { + let ident_token = self.current_token.clone(); + let ident_name = ident_token.text.ok_or_else(|| ParseError::Custom( + "Internal error: Identifier token missing text".to_string() + ))?; + self.next_token()?; // Consume identifier + + self.expect(TokenType::Assign, "assignment")?; + let value_expr = self.expr(0)?; // Assignment has low precedence effectively + + let var_node = make_leaf(NodeType::Ident, ident_name); + let assign_node = make_node(NodeType::Assign, Some(var_node), Some(value_expr)); + + self.expect(TokenType::Semi, "assignment statement")?; + Ok(Some(assign_node)) + } + TokenType::While => { + self.next_token()?; // Consume 'while' + let condition = self.paren_expr()?; + let body = self.stmt()?.ok_or_else(|| ParseError::Custom( + "Expected statement for 'while' body".to_string() + ))?; + Ok(Some(make_node(NodeType::While, Some(condition), Some(body)))) + } + TokenType::Lbrace => { + self.next_token()?; // Consume '{' + let mut sequence: Option> = None; + while !self.check(TokenType::Rbrace) && !self.check(TokenType::Eoi) { + if let Some(stmt_node) = self.stmt()? { + // Build sequence: Sequence(prev_sequence, current_statement) + sequence = Some(make_node(NodeType::Sequence, sequence, Some(stmt_node))); + } + } + self.expect(TokenType::Rbrace, "block statement end")?; + Ok(sequence) // Return the sequence of statements in the block + } + TokenType::Eoi => Ok(None), // End of input is valid here + _ => Err(ParseError::UnexpectedToken { + expected: "start of statement (if, while, print, putc, {, ;, identifier)".to_string(), + found: self.current_token.clone(), + context: "stmt", + }), + } + } + + // parse: Main parsing loop, creates sequence of statements + fn parse(&mut self) -> ParseResult> { + let mut program_sequence: Option> = None; + + // Loop until End Of Input is the *current* token + while !self.check(TokenType::Eoi) { + match self.stmt()? { + Some(stmt_node) => { + // Build sequence: Sequence(prev_sequence, current_statement) + program_sequence = Some(make_node(NodeType::Sequence, program_sequence, Some(stmt_node))); + } + None => { + // Handle empty statements (like ';') - they don't add to the sequence + } + } + } + + // If program_sequence is still None (empty input or only ';'), create an empty sequence. + // Otherwise, return the built sequence. + Ok(program_sequence.unwrap_or_else(|| make_node(NodeType::Sequence, None, None))) + } +} + + +// --- AST Printing --- + +fn prt_ast(node: Option<&AstNode>, indent: usize) { + let prefix = " ".repeat(indent); + match node { + None => { + // Represent null children clearly, maybe matching the C output style + println!("{}", prefix); + // Or match C output: println!("{};", prefix); but is clearer + } + Some(t) => { + // Use DISPLAY_NODES array, ensure NodeType enum indices match + let node_name = DISPLAY_NODES.get(t.node_type as usize).unwrap_or(&"UnknownNode"); + + match t.node_type { + NodeType::Ident | NodeType::Integer | NodeType::String => { + println!("{}{:<14} {}", prefix, node_name, t.value.as_deref().unwrap_or("")); + } + _ => { + println!("{}{:<14}", prefix, node_name); + prt_ast(t.left.as_deref(), indent + 1); + prt_ast(t.right.as_deref(), indent + 1); + } + } + } + } +} + + +// --- Main Function --- + +fn main() -> Result<(), Box> { + let args: Vec = env::args().collect(); + + // --- I/O Setup --- + // Use Box to handle both stdin and files + let reader: Box = if args.len() > 1 && !args[1].is_empty() { + Box::new(File::open(&args[1]) + .map_err(|e| format!("Error opening input file '{}': {}", args[1], e))?) + } else { + Box::new(io::stdin()) + }; + let buf_reader = BufReader::new(reader); + + // Use Box for output flexibility (though stdout is typical) + let writer: Box = if args.len() > 2 && !args[2].is_empty() { + Box::new(File::create(&args[2]) + .map_err(|e| format!("Error creating output file '{}': {}", args[2], e))?) + } else { + Box::new(io::stdout()) + }; + let mut buf_writer = BufWriter::new(writer); // Not strictly needed for AST printing, but good practice + + // --- Parsing --- + // Create parser and run it + let mut parser = Parser::new(buf_reader) + .map_err(|e| format!("Parser initialization failed: {}", e))?; // Convert ParseError for main's return + + match parser.parse() { + Ok(ast_root) => { + // --- AST Printing --- + // Use a closure to capture buf_writer for printing + let print_to_writer = |node: Option<&AstNode>, indent: usize| { + let prefix = " ".repeat(indent); + match node { + None => writeln!(buf_writer, "{}", prefix).unwrap(), // Handle write errors if needed + Some(t) => { + let node_name = DISPLAY_NODES.get(t.node_type as usize).unwrap_or(&"UnknownNode"); + match t.node_type { + NodeType::Ident | NodeType::Integer | NodeType::String => { + writeln!(buf_writer, "{}{:<14} {}", prefix, node_name, t.value.as_deref().unwrap_or("")).unwrap(); + } + _ => { + writeln!(buf_writer, "{}{:<14}", prefix, node_name).unwrap(); + // Recursive calls need access to buf_writer, which is tricky. + // Simpler to pass the writer or print directly for now. + // Let's redefine prt_ast slightly for main. + } + } + } + } + }; + + // Redefine prt_ast locally or pass writer - let's redefine for simplicity here + fn print_ast_to_writer(writer: &mut W, node: Option<&AstNode>, indent: usize) -> io::Result<()> { + let prefix = " ".repeat(indent); + match node { + None => writeln!(writer, "{}", prefix), + Some(t) => { + let node_name = DISPLAY_NODES.get(t.node_type as usize).unwrap_or(&"UnknownNode"); + match t.node_type { + NodeType::Ident | NodeType::Integer | NodeType::String => { + writeln!(writer, "{}{:<14} {}", prefix, node_name, t.value.as_deref().unwrap_or(""))?; + } + _ => { + writeln!(writer, "{}{:<14}", prefix, node_name)?; + print_ast_to_writer(writer, t.left.as_deref(), indent + 1)?; + print_ast_to_writer(writer, t.right.as_deref(), indent + 1)?; + } + } + Ok(()) + } + } + } + + // Call the modified print function + print_ast_to_writer(&mut buf_writer, Some(&ast_root), 0) + .map_err(|e| format!("Error writing AST: {}", e))?; + + + // Ensure output buffer is flushed + buf_writer.flush()?; + } + Err(e) => { + eprintln!("Parse Error: {}", e); // Print error to stderr + exit(1); // Exit with non-zero status on error + } + } + + Ok(()) // Indicate success +} diff --git a/Task/Composite-numbers-k-with-no-single-digit-factors-whose-factors-are-all-substrings-of-k/EasyLang/composite-numbers-k-with-no-single-digit-factors-whose-factors-are-all-substrings-of-k.easy b/Task/Composite-numbers-k-with-no-single-digit-factors-whose-factors-are-all-substrings-of-k/EasyLang/composite-numbers-k-with-no-single-digit-factors-whose-factors-are-all-substrings-of-k.easy index 05eec49360..e6858be29f 100644 --- a/Task/Composite-numbers-k-with-no-single-digit-factors-whose-factors-are-all-substrings-of-k/EasyLang/composite-numbers-k-with-no-single-digit-factors-whose-factors-are-all-substrings-of-k.easy +++ b/Task/Composite-numbers-k-with-no-single-digit-factors-whose-factors-are-all-substrings-of-k/EasyLang/composite-numbers-k-with-no-single-digit-factors-whose-factors-are-all-substrings-of-k.easy @@ -3,24 +3,17 @@ fastfunc isin n k . while n > 0 if h mod 10 = n mod 10 h = h div 10 - if match = 0 - match = n - . + if match = 0 : match = n else h = k - if match <> 0 - n = match - . + if match <> 0 : n = match match = 0 . - if h = 0 - return 1 - . + if h = 0 : return 1 n = n div 10 . return 0 . - fastfunc test n . if n mod 2 = 0 or n mod 3 = 0 or n mod 5 = 0 or n mod 7 = 0 return 0 @@ -32,25 +25,19 @@ fastfunc test n . while rest mod fact = 0 rest /= fact . - if isin n fact = 0 - return 0 - . + if isin n fact = 0 : return 0 nfacts += 1 . fact += 2 - if fact > sqrt n and nfacts = 0 - return 0 - . - . - if nfacts > 1 - return 1 + if fact > sqrt n and nfacts = 0 : return 0 . + if nfacts > 1 : return 1 return 0 . n = 11 while count < 10 if test n = 1 - print n + write n & " " count += 1 . n += 2 diff --git a/Task/Concurrent-computing/Elena/concurrent-computing.elena b/Task/Concurrent-computing/Elena/concurrent-computing.elena new file mode 100644 index 0000000000..89672b7dac --- /dev/null +++ b/Task/Concurrent-computing/Elena/concurrent-computing.elena @@ -0,0 +1,11 @@ +import system'threading; +import extensions'threading; + +async public program() +{ + Task t1 := Task.run({ Console.printLineConcurrent("Enjoy") }); + Task t2 := Task.run({ Console.printLineConcurrent("Rosetta") }); + Task t3 := Task.run({ Console.printLineConcurrent("Code") }); + + :await Task.whenAllArgs(t1, t2, t3); +} diff --git a/Task/Conditional-structures/Excel/conditional-structures-1.excel b/Task/Conditional-structures/Excel/conditional-structures-1.excel new file mode 100644 index 0000000000..1898abcdcd --- /dev/null +++ b/Task/Conditional-structures/Excel/conditional-structures-1.excel @@ -0,0 +1 @@ +=IF(condition, value_if_true, value_if_false) diff --git a/Task/Conditional-structures/Excel/conditional-structures-2.excel b/Task/Conditional-structures/Excel/conditional-structures-2.excel new file mode 100644 index 0000000000..0d2f873020 --- /dev/null +++ b/Task/Conditional-structures/Excel/conditional-structures-2.excel @@ -0,0 +1 @@ +=IFS(condition1, value_if_true1, [condition2, value_if_true2, ...]) diff --git a/Task/Conditional-structures/Excel/conditional-structures-3.excel b/Task/Conditional-structures/Excel/conditional-structures-3.excel new file mode 100644 index 0000000000..7a84f2b5ab --- /dev/null +++ b/Task/Conditional-structures/Excel/conditional-structures-3.excel @@ -0,0 +1 @@ +=SWITCH(expression, case1, value1, [case2, value2, ...], [default]) diff --git a/Task/Conditional-structures/Uxntal/conditional-structures.uxnatl b/Task/Conditional-structures/Uxntal/conditional-structures.uxnatl new file mode 100644 index 0000000000..c30872584c --- /dev/null +++ b/Task/Conditional-structures/Uxntal/conditional-structures.uxnatl @@ -0,0 +1,32 @@ +%\n { 0a } %\s { 20 } %\0 { 00 } + +|18 @Console/write + +|100 + +#0102 test +#0201 test +#0101 test + +BRK + +@test ( x y -- ) + ( unless ) NEQk ?{ + ;msgs/equal print/str !/end } + ( else unless ) GTHk ?{ + ;msgs/less print/str !/end } + ( else unless ) LTHk ?{ + ;msgs/greater print/str } + + &end + POP2 JMP2r + +@print/str ( str* -- ) + LDAk .Console/write DEO + INC2 LDAk ?/str + POP2 JMP2r + +@msgs [ + &greater "x \s "is \s "greater \s "than \s "y \n \0 + &equal "x \s "is \s "equal \s "to \s "y \n \0 + &less "x \s "is \s "less \s "than \s "y \n \0 ] diff --git a/Task/Consecutive-primes-with-ascending-or-descending-differences/EasyLang/consecutive-primes-with-ascending-or-descending-differences.easy b/Task/Consecutive-primes-with-ascending-or-descending-differences/EasyLang/consecutive-primes-with-ascending-or-descending-differences.easy index 7fcb576dfd..cecfaecb6e 100644 --- a/Task/Consecutive-primes-with-ascending-or-descending-differences/EasyLang/consecutive-primes-with-ascending-or-descending-differences.easy +++ b/Task/Consecutive-primes-with-ascending-or-descending-differences/EasyLang/consecutive-primes-with-ascending-or-descending-differences.easy @@ -9,7 +9,7 @@ fastfunc nextprim num . . return num . -proc getseq dir . maxprim maxcnt . +proc getseq dir &maxprim &maxcnt . maxcnt = 0 pri = 2 repeat @@ -30,7 +30,7 @@ proc getseq dir . maxprim maxcnt . . . . -proc outseq pri max . . +proc outseq pri max . write pri & " " for i to max pri = nextprim (pri + 1) diff --git a/Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences-1.rexx b/Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences-1.rexx deleted file mode 100644 index 28f9729221..0000000000 --- a/Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences-1.rexx +++ /dev/null @@ -1,64 +0,0 @@ -/*REXX program finds the longest sequence of consecutive primes where the differences */ -/*──────────── between the primes are strictly ascending; also for strictly descending.*/ -parse arg hi cols . /*obtain optional argument from the CL.*/ -if hi=='' | hi=="," then hi= 1000000 /* " " " " " " */ -if cols=='' | cols=="," then cols= 10 /* " " " " " " */ -call genP /*build array of semaphores for primes.*/ -w= 10 /*width of a number in any column. */ -call fRun 1; call show 1 /*find runs with ascending prime diffs.*/ -call fRun 0; call show 0 /* " " " descending " " */ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? -/*──────────────────────────────────────────────────────────────────────────────────────*/ -fRun: parse arg ?; mxrun=0; seq.= /*max run length; lists of prime runs.*/ - /*search for consecutive primes < HI.*/ - do j=2 for #-2; cp= @.j; jn= j+1 /*CP: current prime; JN: next j */ - diff= @.jn - cp /*get difference between last 2 primes.*/ - cnt= 1; run= /*initialize the CNT and RUN. */ - do k= jn+1 to #-2; km= k-1 /*look for more primes in this run. */ - if ? then if @.k-@.km<=diff then leave /*Diff. too small? Stop looking*/ - else nop - else if @.k-@.km>=diff then leave /* " " large? " " */ - run= run @.k; cnt= cnt+1 /*append a prime to the run; bump count*/ - diff= @.k - @.km /*calculate difference for next prime. */ - end /*k*/ - if cnt<=mxrun then iterate /*This run too short? Then keep looking*/ - mxrun= max(mxrun, cnt) /*define a new maximum run (seq) length*/ - seq.mxrun= cp @.jn run /*full populate the sequence (RUN). */ - end /*j*/; return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13; @.7=17; @.8=19 /*define low primes.*/ - #=8; sq.#= @.# ** 2 /*number of primes so far; prime sqiare*/ - /* [↓] generate more primes ≤ high.*/ - do j=@.#+2 by 2 to hi; parse var j '' -1 _ /*find odd primes from here on.*/ - if _==5 then iterate; if j// 3==0 then iterate /*J ÷ 5? J ÷ by 3? */ - if j// 7==0 then iterate; if j//11==0 then iterate /*" " 7? " " " 11? */ - if j//13==0 then iterate; if j//17==0 then iterate /*" " 13? " " " 17? */ - do k=8 while sq.k<=j /* [↓] divide by the known odd primes.*/ - if j // @.k == 0 then iterate j /*Is J ÷ X? Then not prime. ___ */ - end /*k*/ /* [↑] only process numbers ≤ √ J */ - #= #+1; @.#= j; sq.#= j*j /*bump # of Ps; assign next P; P square*/ - end /*j*/; return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -show: parse arg ?; if ? then AorD= 'ascending' /*choose which literal for display.*/ - else AorD= 'descending' /* " " " " " */ - title= ' longest run of consecutive primes whose differences between primes are' , - 'strictly' AorD "and < " commas(hi) - say; say; say - if cols>0 then say ' index │'center(title, 1 + cols*(w+1) ) - if cols>0 then say '───────┼'center("" , 1 + cols*(w+1), '─') - found= 0; idx= 1 /*initialize # of consecutive primes. */ - $= /*a list of consecutive primes (so far)*/ - do o=1 for words(seq.mxrun) /*show all consecutive primes in seq. */ - c= commas( word(seq.mxrun, o) ) /*obtain the next prime in the sequence*/ - found= found + 1 /*bump the number of consecutive primes*/ - if cols<=0 then iterate /*build the list (to be shown later)? */ - $= $ right(c, max(w, length(c) ) ) /*add a nice prime ──► list, allow big#*/ - if found//cols\==0 then iterate /*have we populated a line of output? */ - say center(idx, 7)'│' substr($, 2) /*display what we have so far (cols). */ - idx= idx + cols; $= /*bump the index count for the output*/ - end /*o*/ - if $\=='' then say center(idx, 7)"│" substr($, 2) /*maybe show residual output*/ - if cols>0 then say '───────┴'center("" , 1 + cols*(w+1), '─') - say; say commas(Cprimes) ' was the'title; return diff --git a/Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences-2.rexx b/Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences.rexx similarity index 51% rename from Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences-2.rexx rename to Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences.rexx index 6bd309a7ca..2cc34a37fe 100644 --- a/Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences-2.rexx +++ b/Task/Consecutive-primes-with-ascending-or-descending-differences/REXX/consecutive-primes-with-ascending-or-descending-differences.rexx @@ -1,8 +1,10 @@ -call Time('r') -parse version version; say version -glob. = ''; numeric digits 10; t = 1e7 -say 'Consecutive primes - Using REXX libraries' +-- 22 Mar 2025 +include Settings + +say 'CONSECUTIVE PRIMES' +say version say +numeric digits 10; t = 1e7 call Primes t call Deltas call Sequence 'A',t @@ -11,35 +13,35 @@ say Format(Time('e'),,3) 'seconds' exit Deltas: -/* Calculate deltas between pairs of primes */ -procedure expose prim. delta. -delta. = 0 +-- Calculate deltas between pairs of primes +procedure expose prim. delt. +delt. = 0 do i = 2 to prim.0 - h = i-1; delta.i = prim.prime.i-prim.prime.h + h = i-1; delt.i = prim.i-prim.h end return Sequence: -/* Find and show longest strict sequence */ -procedure expose delta. glob. prim. +-- Find and show longest strict sequence +procedure expose delt. prim. arg ad,t p = prim.0+1 if ad = 'A' then - delta.p = 0 + delt.p = 0 else - delta.p = n + delt.p = t d = 0; f = 1; l = 1; len = 0 do i = 2 to p - if (ad = 'A' & delta.i > d), - | (ad = 'D' & delta.i < d) then do - d = delta.i; l = i + if (ad = 'A' & delt.i > d), + | (ad = 'D' & delt.i < d) then do + d = delt.i; l = i end else do a = l-f+1 if a > len then do first = f; last = l; len = a end - f = i-1; l = i; d = delta.i + f = i-1; l = i; d = delt.i end end if ad = 'A' then @@ -50,11 +52,12 @@ say 'For primes <' t', the longest' a 'sequence was' len 'consecutive primes.' say 'These are (with differences):' do i = first to last-1 j = i+1 - call charout ,prim.prime.i '('delta.j') ' + call charout ,prim.i '('delt.j') ' end -call charout ,prim.prime.last +call charout ,prim.last say; say return include Sequences include Functions +include Abend diff --git a/Task/Constrained-random-points-on-a-circle/EasyLang/constrained-random-points-on-a-circle.easy b/Task/Constrained-random-points-on-a-circle/EasyLang/constrained-random-points-on-a-circle.easy index 3f4f491b57..067481812b 100644 --- a/Task/Constrained-random-points-on-a-circle/EasyLang/constrained-random-points-on-a-circle.easy +++ b/Task/Constrained-random-points-on-a-circle/EasyLang/constrained-random-points-on-a-circle.easy @@ -4,7 +4,6 @@ while cnt < 100 r = sqrt (x * x + y * y) if 10 <= r and r <= 15 cnt += 1 - move 50 + x * 2 50 + y * 2 - circle 1 + gcircle 50 + x * 2 50 + y * 2 1 . . diff --git a/Task/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n-/C-sharp/continued-fraction-arithmetic-g-matrix-ng-continued-fraction-n-.cs b/Task/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n-/C-sharp/continued-fraction-arithmetic-g-matrix-ng-continued-fraction-n-.cs new file mode 100644 index 0000000000..9507421d86 --- /dev/null +++ b/Task/Continued-fraction-Arithmetic-G-matrix-ng-continued-fraction-n-/C-sharp/continued-fraction-arithmetic-g-matrix-ng-continued-fraction-n-.cs @@ -0,0 +1,70 @@ +using System.Numerics; +using Seq = System.Collections.Generic.IEnumerable; + +static Seq Rep(BigInteger n) { while(true) yield return n; } + +static Seq Cons(BigInteger n, Seq s) => new[]{n}.Concat(s); + +static void Write(Seq terms) +{ + var ts = terms.ToArray(); + + switch (ts.Length) + { + case 0: Console.Write("[]"); break; + case 1: Console.Write($"[{ts[0]}]"); break; + default: + Console.Write($"[{ts[0]}; "); + Console.Write(string.Join(", ", ts[1..])); + Console.Write(']'); + break; + } +} + +static Seq Transform(Seq terms, BigInteger a1, BigInteger a, BigInteger b1, BigInteger b) +{ + foreach (var term in terms) + { + (a, a1) = (a1, a + term * a1); + (b, b1) = (b1, b + term * b1); + + while (!b1.IsZero && !b.IsZero) + { + var m = BigInteger.DivRem(a1, b1, out var r); + var n = BigInteger.DivRem(a, b, out var s); + + if (m != n) + break; + + yield return n; + (a1, b1) = (b1, r); + (a, b) = (b, s); + } + } + + while (!a1.IsZero && !b1.IsZero) + { + var n = BigInteger.DivRem(a1, b1, out var s); + yield return n; + (a1, b1) = (b1, s); + } +} + +Console.Write("[1; 5, 2] + 1/2 = "); +Write(Transform([1, 5, 2], 2, 1, 0, 2)); +Console.WriteLine(); + +Console.Write("[3; 7] + 1/2 = "); +Write(Transform([3, 7], 2, 1, 0, 2)); +Console.WriteLine(); + +Console.Write("[3; 7] / 4 = "); +Write(Transform([3, 7], 1, 0, 0, 4)); +Console.WriteLine(); + +var sqrt2 = Cons(1, Rep(2)); +var oneOverSqrt2 = Transform(sqrt2, 0, 1, 1, 0); +var agm = Transform(oneOverSqrt2, 1, 1, 0, 2); +Console.Write("(1 + 1/sqrt(2)) / 2 = "); +Write(agm.Take(20)); +Console.WriteLine(); diff --git a/Task/Continued-fraction/C-sharp/continued-fraction.cs b/Task/Continued-fraction/C-sharp/continued-fraction.cs index 207aee03b1..0b26fa0a36 100644 --- a/Task/Continued-fraction/C-sharp/continued-fraction.cs +++ b/Task/Continued-fraction/C-sharp/continued-fraction.cs @@ -1,26 +1,102 @@ -using System; -using System.Collections.Generic; +using System.Numerics; -namespace ContinuedFraction { - class Program { - static double Calc(Func f, int n) { - double temp = 0.0; - for (int ni = n; ni >= 1; ni--) { - int[] p = f(ni); - temp = p[1] / (p[0] + temp); - } - return f(0)[0] + temp; - } +using Seq = System.Collections.Generic.IEnumerable; - static void Main(string[] args) { - List> fList = new List>(); - fList.Add(n => new int[] { n > 0 ? 2 : 1, 1 }); - fList.Add(n => new int[] { n > 0 ? n : 2, n > 1 ? (n - 1) : 1 }); - fList.Add(n => new int[] { n > 0 ? 6 : 3, (int) Math.Pow(2 * n - 1, 2) }); +static Seq Rep(BigInteger n) { while(true) yield return n; } - foreach (var f in fList) { - Console.WriteLine(Calc(f, 200)); - } +static Seq Cons(BigInteger n, Seq s) => new[]{n}.Concat(s); + +static Seq Reciprocal(Seq s) => s.First() == 0 ? s.Skip(1) : Cons(0, s); + +static Seq Nats() { BigInteger n = 1; while(true) { yield return n; n++; } } + +static Seq Squared(Seq s) => s.Select(n => n * n); + +static Seq Odds() => Nats().Select(n => 2 * n - 1); + +static Seq Simplify(Seq aseq, Seq bseq) +{ + BigInteger a = 0, b = 1, c = 1, d = 0; + using var e = bseq.GetEnumerator(); + + foreach (var t in aseq) + { + var u = e.MoveNext() ? e.Current : 1; + (a, b) = (u * b, a + t * b); + (c, d) = (u * d, c + t * d); + + while (!c.IsZero && !d.IsZero) + { + var m = BigInteger.DivRem(a, c, out var r); + var n = BigInteger.DivRem(b, d, out var s); + + if (m != n) + break; + + yield return n; + (a, c) = (c, r); + (b, d) = (d, s); } } + + while (!b.IsZero && !d.IsZero) + { + var n = BigInteger.DivRem(b, d, out var s); + yield return n; + (b, d) = (d, s); + } } + +static void Write(Seq terms, int places) +{ + Console.Write(terms.First()); + Console.Write('.'); + BigInteger a = 10, b = 0, c = 0, d = 1; + + foreach (var term in terms.Skip(1)) + { + (a, b) = (b, a + b * term); + (c, d) = (d, c + d * term); + + while (!c.IsZero && !d.IsZero) + { + var m = BigInteger.DivRem(a, c, out var r); + var n = BigInteger.DivRem(b, d, out var s); + + if (m != n) + break; + + Console.Write(m); + + if (--places <= 0) + return; + + a = r * 10; + b = s * 10; + } + } + + while (!b.IsZero && !d.IsZero) + { + var n = BigInteger.DivRem(b, d, out var s); + Console.Write(n); + + if (--places <= 0) + return; + + b = s * 10; + } +} + +static Seq Sqrt2() => Cons(1, Rep(2)); + +static Seq E() => Simplify(Cons(2, Nats()), Cons(1, Nats())); + +static Seq Pi() => Simplify(Cons(3, Rep(6)), Squared(Odds())); + +Write(Sqrt2(), 20); +Console.WriteLine(); +Write(E(), 20); +Console.WriteLine(); +Write(Pi(), 10); +Console.WriteLine(); diff --git a/Task/Continued-fraction/EasyLang/continued-fraction.easy b/Task/Continued-fraction/EasyLang/continued-fraction.easy index 84c90776b1..51ec9a4634 100644 --- a/Task/Continued-fraction/EasyLang/continued-fraction.easy +++ b/Task/Continued-fraction/EasyLang/continued-fraction.easy @@ -1,12 +1,10 @@ -numfmt 8 0 +numfmt 0 8 func calc_sqrt . n = 100 sum = n while n >= 1 - a = 1 - if n > 1 - a = 2 - . + a = 2 + if n = 1 : a = 1 b = 1 sum = a + b / sum n -= 1 @@ -17,13 +15,11 @@ func calc_e . n = 100 sum = n while n >= 1 - a = 2 - if n > 1 - a = n - 1 - . - b = 1 - if n > 1 - b = n - 1 + a = n - 1 + b = n - 1 + if n = 1 + a = 2 + b = 1 . sum = a + b / sum n -= 1 @@ -34,10 +30,8 @@ func calc_pi . n = 100 sum = n while n >= 1 - a = 3 - if n > 1 - a = 6 - . + a = 6 + if n = 1 : a = 3 b = 2 * n - 1 b *= b sum = a + b / sum diff --git a/Task/Continued-fraction/REXX/continued-fraction-1.rexx b/Task/Continued-fraction/REXX/continued-fraction-1.rexx index 2f67a48e9a..f85721f91a 100644 --- a/Task/Continued-fraction/REXX/continued-fraction-1.rexx +++ b/Task/Continued-fraction/REXX/continued-fraction-1.rexx @@ -1,43 +1,44 @@ -/*REXX program calculates and displays values of various continued fractions. */ -parse arg terms digs . -if terms=='' | terms=="," then terms=500 -if digs=='' | digs=="," then digs=100 -numeric digits digs /*use 100 decimal digits for display.*/ -b.=1 /*omitted ß terms are assumed to be 1.*/ -/*══════════════════════════════════════════════════════════════════════════════════════*/ -a.=2; call tell '√2', cf(1) -/*══════════════════════════════════════════════════════════════════════════════════════*/ -a.=1; do N=2 by 2 to terms; a.N=2; end; call tell '√3', cf(1) /*also: 2∙sin(π/3) */ -/*══════════════════════════════════════════════════════════════════════════════════════*/ -a.=2 /* ___ */ - do N=2 to 17 /*generalized √ N */ - b.=N-1; NN=right(N, 2); call tell 'gen √'NN, cf(1) - end /*N*/ -/*══════════════════════════════════════════════════════════════════════════════════════*/ -a.=2; b.=-1/2; call tell 'gen √ ½', cf(1) -/*══════════════════════════════════════════════════════════════════════════════════════*/ - do j=1 for terms; a.j=j; if j>1 then b.j=a.p; p=j; end; call tell 'e', cf(2) -/*══════════════════════════════════════════════════════════════════════════════════════*/ -a.=1; call tell 'φ, phi', cf(1) -/*══════════════════════════════════════════════════════════════════════════════════════*/ -a.=1; do j=1 for terms; if j//2 then a.j=j; end; call tell 'tan(1)', cf(1) -/*══════════════════════════════════════════════════════════════════════════════════════*/ - do j=1 for terms; a.j=2*j+1; end; call tell 'coth(1)', cf(1) -/*══════════════════════════════════════════════════════════════════════════════════════*/ - do j=1 for terms; a.j=4*j+2; end; call tell 'coth(½)', cf(2) /*also: [e+1]÷[e-1] */ -/*══════════════════════════════════════════════════════════════════════════════════════*/ - terms=100000 -a.=6; do j=1 for terms; b.j=(2*j-1)**2; end; call tell 'π, pi', cf(3) -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -cf: procedure expose a. b. terms; parse arg C; !=0; numeric digits 9+digits() - do k=terms by -1 for terms; d=a.k+!; !=b.k/d - end /*k*/ - return !+C -/*──────────────────────────────────────────────────────────────────────────────────────*/ -tell: parse arg ?,v; $=left(format(v)/1,1+digits()); w=50 /*50 bytes of terms*/ - aT=; do k=1; _=space(aT a.k); if length(_)>w then leave; aT=_; end /*k*/ - bT=; do k=1; _=space(bT b.k); if length(_)>w then leave; bT=_; end /*k*/ - say right(?,8) "=" $ ' α terms='aT ... - if b.1\==1 then say right("",12+digits()) ' ß terms='bT ... - a=; b.=1; return /*only 50 bytes of α & ß terms ↑ are displayed. */ +/* REXX ************************************************************** +* Derived from PL/I with a little "massage" +* SQRT2= 1.41421356237309505 <- PL/I Result +* 1.41421356237309504880168872421 <- REXX Result 30 digits +* NAPIER= 2.71828182845904524 +* 2.71828182845904523536028747135 +* PI= 3.14159262280484695 +* 3.14159262280484694855146925223 +* 06.09.2012 Walter Pachl +**********************************************************************/ + Numeric Digits 30 + Parse Value '1 2 3 0 0' with Sqrt2 napier pi a b + Say left('SQRT2=' ,10) calc(sqrt2, 200) + Say left('NAPIER=',10) calc(napier, 200) + Say left('PI=' ,10) calc(pi, 200) + Exit + +Get_Coeffs: procedure Expose a b Sqrt2 napier pi + Parse Arg form, n + select + when form=Sqrt2 Then do + if n > 0 then a = 2; else a = 1 + b = 1 + end + when form=Napier Then do + if n > 0 then a = n; else a = 2 + if n > 1 then b = n - 1; else b = 1 + end + when form=pi Then do + if n > 0 then a = 6; else a = 3 + b = (2*n - 1)**2 + end + end + Return + +Calc: procedure Expose a b Sqrt2 napier pi + Parse Arg form,n + Temp=0 + do ni = n to 1 by -1 + Call Get_Coeffs form, ni + Temp = B/(A + Temp) + end + call Get_Coeffs form, 0 + return (A + Temp) diff --git a/Task/Continued-fraction/REXX/continued-fraction-2.rexx b/Task/Continued-fraction/REXX/continued-fraction-2.rexx index f85721f91a..a2ebb2cccc 100644 --- a/Task/Continued-fraction/REXX/continued-fraction-2.rexx +++ b/Task/Continued-fraction/REXX/continued-fraction-2.rexx @@ -1,44 +1,72 @@ -/* REXX ************************************************************** -* Derived from PL/I with a little "massage" -* SQRT2= 1.41421356237309505 <- PL/I Result -* 1.41421356237309504880168872421 <- REXX Result 30 digits -* NAPIER= 2.71828182845904524 -* 2.71828182845904523536028747135 -* PI= 3.14159262280484695 -* 3.14159262280484694855146925223 -* 06.09.2012 Walter Pachl +/* REXX ************************************************************* +* The task description specifies a continued fraction for pi +* that gives a reasonable approximation. +* Literature shows a better CF that yields pi with a precision of +* 200 digits. +* http://de.wikipedia.org/wiki/Kreiszahl +* 1 +* pi = 3 + ------------------------ +* 1 +* 7 + -------------------- +* 1 +* 15 + --------------- +* 1 +* 1 + ----------- +* +* 292 + ... +* +* This program uses that CF and shows the first 50 digits +* PI =3.1415926535897932384626433832795028841971693993751... +* PIX=3.1415926535897932384626433832795028841971693993751... +* 201 correct digits +* 18.09.2012 Walter Pachl **********************************************************************/ - Numeric Digits 30 - Parse Value '1 2 3 0 0' with Sqrt2 napier pi a b - Say left('SQRT2=' ,10) calc(sqrt2, 200) - Say left('NAPIER=',10) calc(napier, 200) - Say left('PI=' ,10) calc(pi, 200) + pi='3.1415926535897932384626433832795028841971'||, + '693993751058209749445923078164062862089986280348'||, + '253421170679821480865132823066470938446095505822'||, + '317253594081284811174502841027019385211055596446'||, + '229489549303819644288109756659334461284756482337'||, + '867831652712019091456485669234603486104543266482'||, + '133936072602491412737245870066063155881748815209'||, + '209628292540917153643678925903600113305305488204'||, + '665213841469519415116094330572703657595919530921'||, + '861173819326117931051185480744623799627495673518'||, + '857527248912279381830119491298336733624' + Numeric Digits 1000 + al='7 15 1 292 1 1 1 2 1 3 1 14 2 1 1 2 2 2 2 1 84 2', + '1 1 15 3 13 1 4 2 6 6 99 1 2 2 6 3 5 1 1 6 8 1 7 1 2', + '3 7 1 2 1 1 12 1 1 1 3 1 1 8 1 1 2 1 6 1 1 5 2 2 3 1', + '2 4 4 16 1 161 45 1 22 1 2 2 1 4 1 2 24 1 2 1 3 1 2', + '1 1 10 2 5 4 1 2 2 8 1 5 2 2 26 1 4 1 1 8 2 42 2 1 7', + '3 3 1 1 7 2 4 9 7 2 3 1 57 1 18 1 9 19 1 2 18 1 3 7', + '30 1 1 1 3 3 3 1 2 8 1 1 2 1 15 1 2 13 1 2 1 4 1 12', + '1 1 3 3 28 1 10 3 2 20 1 1 1 1 4 1 1 1 5 3 2 1 6 1 4' + a.=3 + Do i=1 By 1 while al<>'' + Parse Var al a.i al + End + pix=calc(194) + Do e=1 To length(pi) + If substr(pix,e,1)<>substr(pi,e,1) Then Leave + End + Numeric Digits 50 + Say 'PI ='||(pi+0)||'...' + Say 'PIX='||(pix+0)||'...' + Say (e-1) 'correct digits' Exit -Get_Coeffs: procedure Expose a b Sqrt2 napier pi - Parse Arg form, n - select - when form=Sqrt2 Then do - if n > 0 then a = 2; else a = 1 - b = 1 - end - when form=Napier Then do - if n > 0 then a = n; else a = 2 - if n > 1 then b = n - 1; else b = 1 - end - when form=pi Then do - if n > 0 then a = 6; else a = 3 - b = (2*n - 1)**2 - end - end +Get_Coeffs: procedure Expose a b a. + Parse Arg n + a=a.n + b=1 Return -Calc: procedure Expose a b Sqrt2 napier pi - Parse Arg form,n +Calc: procedure Expose a b a. + Parse Arg n Temp=0 do ni = n to 1 by -1 - Call Get_Coeffs form, ni + Call Get_Coeffs ni Temp = B/(A + Temp) end - call Get_Coeffs form, 0 + call Get_Coeffs 0 return (A + Temp) diff --git a/Task/Continued-fraction/REXX/continued-fraction-3.rexx b/Task/Continued-fraction/REXX/continued-fraction-3.rexx index a2ebb2cccc..cd0a5816c4 100644 --- a/Task/Continued-fraction/REXX/continued-fraction-3.rexx +++ b/Task/Continued-fraction/REXX/continued-fraction-3.rexx @@ -1,72 +1,31 @@ -/* REXX ************************************************************* -* The task description specifies a continued fraction for pi -* that gives a reasonable approximation. -* Literature shows a better CF that yields pi with a precision of -* 200 digits. -* http://de.wikipedia.org/wiki/Kreiszahl -* 1 -* pi = 3 + ------------------------ -* 1 -* 7 + -------------------- -* 1 -* 15 + --------------- -* 1 -* 1 + ----------- -* -* 292 + ... -* -* This program uses that CF and shows the first 50 digits -* PI =3.1415926535897932384626433832795028841971693993751... -* PIX=3.1415926535897932384626433832795028841971693993751... -* 201 correct digits -* 18.09.2012 Walter Pachl -**********************************************************************/ - pi='3.1415926535897932384626433832795028841971'||, - '693993751058209749445923078164062862089986280348'||, - '253421170679821480865132823066470938446095505822'||, - '317253594081284811174502841027019385211055596446'||, - '229489549303819644288109756659334461284756482337'||, - '867831652712019091456485669234603486104543266482'||, - '133936072602491412737245870066063155881748815209'||, - '209628292540917153643678925903600113305305488204'||, - '665213841469519415116094330572703657595919530921'||, - '861173819326117931051185480744623799627495673518'||, - '857527248912279381830119491298336733624' - Numeric Digits 1000 - al='7 15 1 292 1 1 1 2 1 3 1 14 2 1 1 2 2 2 2 1 84 2', - '1 1 15 3 13 1 4 2 6 6 99 1 2 2 6 3 5 1 1 6 8 1 7 1 2', - '3 7 1 2 1 1 12 1 1 1 3 1 1 8 1 1 2 1 6 1 1 5 2 2 3 1', - '2 4 4 16 1 161 45 1 22 1 2 2 1 4 1 2 24 1 2 1 3 1 2', - '1 1 10 2 5 4 1 2 2 8 1 5 2 2 26 1 4 1 1 8 2 42 2 1 7', - '3 3 1 1 7 2 4 9 7 2 3 1 57 1 18 1 9 19 1 2 18 1 3 7', - '30 1 1 1 3 3 3 1 2 8 1 1 2 1 15 1 2 13 1 2 1 4 1 12', - '1 1 3 3 28 1 10 3 2 20 1 1 1 1 4 1 1 1 5 3 2 1 6 1 4' - a.=3 - Do i=1 By 1 while al<>'' - Parse Var al a.i al - End - pix=calc(194) - Do e=1 To length(pi) - If substr(pix,e,1)<>substr(pi,e,1) Then Leave - End - Numeric Digits 50 - Say 'PI ='||(pi+0)||'...' - Say 'PIX='||(pix+0)||'...' - Say (e-1) 'correct digits' - Exit +-- 8 May 2025 +include Settings +numeric digits 30 +say 'CONTINUED FRACTION' +say version +say +say 'SqRt(2) =' QcontFrac(1,2,1,1,10) +say 'Must be =' SqRt(2)/1 +say 'e =' QcontFrac(2,'n',1,'n-1',10) +say 'Must be =' E()/1 +say 'Pi =' QcontFrac(3,6,1,'(2*n-1)**2',10) +say 'Must be =' Pi()/1 +say +say 'Pi =' 4/QcontFrac(1,'2*n+1',1,'n**2',10) +say 'Must be =' Pi()/1 +say 'Ln(2) =' QcontFrac(0,'6*n-3',2,'-((n-1)**2)',10) +say 'Must be =' Ln(2)/1 +say 'e^2 =' QcontFrac(7,'2*n+3',2,1,10) +say 'Must be =' E()*E()/1 +say 'Phi =' QcontFrac(1,1,1,1,10) +say 'Must be =' Golden()/1 +say '2^(1/3) =' QcontFrac(1,'2+Odd(n)*(3*n-2)',1,'n+((n+1)%2-1)',10) +say 'Must be =' CbRt(2)/1 +say 'Tan(1) =' QcontFrac(0,'2*n-1',1,-1,10) +say 'Must be =' Tan(1) +exit -Get_Coeffs: procedure Expose a b a. - Parse Arg n - a=a.n - b=1 - Return - -Calc: procedure Expose a b a. - Parse Arg n - Temp=0 - do ni = n to 1 by -1 - Call Get_Coeffs ni - Temp = B/(A + Temp) - end - call Get_Coeffs 0 - return (A + Temp) +include Rational +include Functions +include Constants +include Abend diff --git a/Task/Convert-seconds-to-compound-duration/Crystal/convert-seconds-to-compound-duration.cr b/Task/Convert-seconds-to-compound-duration/Crystal/convert-seconds-to-compound-duration.cr new file mode 100644 index 0000000000..6b1371ff9d --- /dev/null +++ b/Task/Convert-seconds-to-compound-duration/Crystal/convert-seconds-to-compound-duration.cr @@ -0,0 +1,43 @@ +struct Number + def to_mixed_radix (*radices) + result = Array(self).new(radices.size, 0) + n = self + (0...radices.size).reverse_each do |i| + break if n == 0 + divisor = radices[i] + if divisor == 0 + result[i] = n + break + end + result[i] = n % divisor + n //= divisor + end + result + end +end + +def to_compound (num, radices, units) + num.to_mixed_radix(*radices).zip(units).compact_map {|n, u| + if n != 0 + "#{n} #{u}" + end + }.join(", ") +end + +def secs_to_compound (secs) + to_compound secs, {0, 7, 24, 60, 60}, ["wk", "d", "hr", "min", "sec"] +end + +puts "The task:" +[7259, 86400, 6000000].each do |n| + printf "%7s sec = %s\n", n, secs_to_compound(n) +end + +puts "\n(nobody asked for this):" +def inches_to_compound (inches) + to_compound inches, {0, 3, 8, 10, 22, 3, 12}, ["lea", "mi", "fur", "ch", "yd", "ft", "in"] +end + +[7259, 86400, 6000000].each do |n| + printf "%7s in = %s\n", n, inches_to_compound(n) +end diff --git a/Task/Convert-seconds-to-compound-duration/EasyLang/convert-seconds-to-compound-duration.easy b/Task/Convert-seconds-to-compound-duration/EasyLang/convert-seconds-to-compound-duration.easy index 71f79d847d..e8774b5e30 100644 --- a/Task/Convert-seconds-to-compound-duration/EasyLang/convert-seconds-to-compound-duration.easy +++ b/Task/Convert-seconds-to-compound-duration/EasyLang/convert-seconds-to-compound-duration.easy @@ -9,9 +9,7 @@ func$ split sec . r[5] = sec for i = 5 downto 1 if r[i] <> 0 - if s$ <> "" - s$ &= ", " - . + if s$ <> "" : s$ &= ", " s$ &= r[i] & " " & n$[i] . . diff --git a/Task/Convex-hull/EasyLang/convex-hull.easy b/Task/Convex-hull/EasyLang/convex-hull.easy index d6eaa5620b..c1744c7281 100644 --- a/Task/Convex-hull/EasyLang/convex-hull.easy +++ b/Task/Convex-hull/EasyLang/convex-hull.easy @@ -1,28 +1,23 @@ func orientation p[] q[] r[] . return (q[2] - p[2]) * (r[1] - q[1]) - (q[1] - p[1]) * (r[2] - q[2]) . -proc calcConvexHull . pts[][] res[][] . - res[][] = [ ] +func[][] convexHull &pts[][] . indMinX = 1 for i to len pts[][] - if pts[i][1] < pts[indMinX][1] - indMinX = i - . + if pts[i][1] < pts[indMinX][1] : indMinX = i . p = indMinX repeat res[][] &= pts[p][] q = (p + 1) mod1 len pts[][] for i to len pts[][] - if orientation pts[p][] pts[i][] pts[q][] < 0 - q = i - . + if orientation pts[p][] pts[i][] pts[q][] < 0 : q = i . p = q until p = indMinX . + return res[][] . # pts[][] = [ [ 16 3 ] [ 12 17 ] [ 0 6 ] [ -4 -6 ] [ 16 6 ] [ 16 -7 ] [ 16 -3 ] [ 17 -4 ] [ 5 19 ] [ 19 -8 ] [ 3 16 ] [ 12 13 ] [ 3 -4 ] [ 17 5 ] [ -3 15 ] [ -3 -9 ] [ 0 11 ] [ -9 -3 ] [ -4 -2 ] [ 12 10 ] ] -calcConvexHull pts[][] res[][] -print res[][] +print convexHull pts[][] diff --git a/Task/Convex-hull/Zig/convex-hull.zig b/Task/Convex-hull/Zig/convex-hull.zig new file mode 100644 index 0000000000..b389404fdc --- /dev/null +++ b/Task/Convex-hull/Zig/convex-hull.zig @@ -0,0 +1,96 @@ +const std = @import("std"); +const print = std.debug.print; + +const Point = struct { + x: f32, + y: f32, + + pub fn format( + self: Point, + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = fmt; + _ = options; + try writer.print("Point{{ x: {d}, y: {d} }}", .{ self.x, self.y }); + } +}; + +fn calculateConvexHull(allocator: std.mem.Allocator, points: []const Point) ![]Point { + // There must be at least 3 points + if (points.len < 3) { + const result = try allocator.alloc(Point, points.len); + @memcpy(result, points); + return result; + } + + var hull = std.ArrayList(Point).init(allocator); + defer hull.deinit(); + + // Find the left most point in the polygon + var left_most_idx: usize = 0; + for (points, 0..) |p, i| { + if (p.x < points[left_most_idx].x) { + left_most_idx = i; + } + } + + var p = left_most_idx; + var q: usize = 0; + + while (true) { + // The left most point must be part of the hull + try hull.append(points[p]); + + q = (p + 1) % points.len; + + for (points, 0..) |_, i| { + if (orientation(&points[p], &points[i], &points[q]) == 2) { + q = i; + } + } + + p = q; + + // Break from loop once we reach the first point again + if (p == left_most_idx) break; + } + + return hull.toOwnedSlice(); +} + +// Calculate orientation for 3 points +// 0 -> Straight line +// 1 -> Clockwise +// 2 -> Counterclockwise +fn orientation(p: *const Point, q: *const Point, r: *const Point) usize { + const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); + + if (val == 0) return 0; + if (val > 0) return 1 else return 2; +} + +fn pt(x: i32, y: i32) Point { + return Point{ .x = @as(f32, @floatFromInt(x)), .y = @as(f32, @floatFromInt(y)) }; +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + const points = [_]Point{ + pt(16, 3), pt(12, 17), pt(0, 6), pt(-4, -6), pt(16, 6), + pt(16, -7), pt(16, -3), pt(17, -4), pt(5, 19), pt(19, -8), + pt(3, 16), pt(12, 13), pt(3, -4), pt(17, 5), pt(-3, 15), + pt(-3, -9), pt(0, 11), pt(-9, -3), pt(-4, -2), pt(12, 10), + }; + + const hull = try calculateConvexHull(allocator, &points); + defer allocator.free(hull); + + for (hull) |point| { + print("{}\n", .{point}); + } +} diff --git a/Task/Conways-Game-of-Life/EasyLang/conways-game-of-life.easy b/Task/Conways-Game-of-Life/EasyLang/conways-game-of-life.easy index 034323a473..743c19e0c4 100644 --- a/Task/Conways-Game-of-Life/EasyLang/conways-game-of-life.easy +++ b/Task/Conways-Game-of-Life/EasyLang/conways-game-of-life.easy @@ -3,24 +3,19 @@ time = 0.1 # nx = n + 1 subr init - for r = 1 to n - for c = 1 to n - i = r * nx + c - if randomf < 0.3 - f[i] = 1 - . + for r = 1 to n : for c = 1 to n + i = r * nx + c + if randomf < 0.3 + f[i] = 1 . . . f = 100 / n subr show - clear - for r = 1 to n - for c = 1 to n - if f[r * nx + c] = 1 - move c * f - f r * f - f - rect f * 0.9 f * 0.9 - . + gclear + for r = 1 to n : for c = 1 to n + if f[r * nx + c] = 1 + grect c * f - f r * f - f f * 0.9 f * 0.9 . . . diff --git a/Task/Copy-a-string/OPL/copy-a-string.opl b/Task/Copy-a-string/OPL/copy-a-string.opl new file mode 100644 index 0000000000..db34e40a63 --- /dev/null +++ b/Task/Copy-a-string/OPL/copy-a-string.opl @@ -0,0 +1,8 @@ +PROC main: + LOCAL src$(6),dst$(5) + src$="Hello" + dst$=src$ + src$="world!" + PRINT dst$,src$ + GET +ENDP diff --git a/Task/Copy-a-string/Uxntal/copy-a-string.uxnatl b/Task/Copy-a-string/Uxntal/copy-a-string.uxnatl new file mode 100644 index 0000000000..0b7adb7b1a --- /dev/null +++ b/Task/Copy-a-string/Uxntal/copy-a-string.uxnatl @@ -0,0 +1,25 @@ +%\n { 0a } %\0 { 00 } + +|18 @Console/write + +|100 + +;str2 ;str1 copy-str +;str2 print-str + +BRK + +@copy/str ( dest* src* -: ) + STH2 + &loop + LDAkr STH2k STAr INC2 LDAkr STHr INC2r ?/loop + POP2 POP2r + JMP2r + +@print/str_ ( str* -: ) + LDAk .Console/write DEO + INC2 @print/str LDAk ?/str_ + POP2 JMP2r + +@str1 "Uxntal \n \0 +@str2 diff --git a/Task/Copy-stdin-to-stdout/Objeck/copy-stdin-to-stdout.objeck b/Task/Copy-stdin-to-stdout/Objeck/copy-stdin-to-stdout.objeck new file mode 100644 index 0000000000..05e460ff31 --- /dev/null +++ b/Task/Copy-stdin-to-stdout/Objeck/copy-stdin-to-stdout.objeck @@ -0,0 +1,9 @@ +class StdInToOut { + function : Main(args : String[]) ~ Nil { + do { + input := System.IO.Console->ReadLine(); + System.IO.Console->PrintLine(input); + } + while(<>input->IsEmpty()); + } +} diff --git a/Task/Count-in-factors/EasyLang/count-in-factors.easy b/Task/Count-in-factors/EasyLang/count-in-factors.easy index cca0be932c..21f0ea2e67 100644 --- a/Task/Count-in-factors/EasyLang/count-in-factors.easy +++ b/Task/Count-in-factors/EasyLang/count-in-factors.easy @@ -1,4 +1,4 @@ -proc decompose num . primes[] . +proc decompose num &primes[] . primes[] = [ ] t = 2 while t * t <= num @@ -15,11 +15,8 @@ for i = 1 to 30 write i & ": " decompose i primes[] for j = 1 to len primes[] - if j > 1 - write " x " - . + if j > 1 : write " x " write primes[j] . print "" - primes[] = [ ] . diff --git a/Task/Count-in-factors/REXX/count-in-factors-1.rexx b/Task/Count-in-factors/REXX/count-in-factors-1.rexx deleted file mode 100644 index ef99c55868..0000000000 --- a/Task/Count-in-factors/REXX/count-in-factors-1.rexx +++ /dev/null @@ -1,37 +0,0 @@ -/*REXX program lists the prime factors of a specified integer (or a range of integers).*/ -@.=left('', 8); @.0="{unity} "; @.1='[prime] ' /*some tags and handy-dandy literals.*/ -parse arg LO HI @ . /*get optional arguments from the C.L. */ -if LO=='' | LO=="," then do; LO=1; HI=40; end /*Not specified? Then use the default.*/ -if HI=='' | HI=="," then HI= LO /* " " " " " " */ -if @=='' then @= 'x' /* " " " " " " */ -if length(@)\==1 then @= x2c(@) /*Not length 1? Then use hexadecimal. */ -tell= (HI>0) /*if HIGH is positive, then show #'s.*/ -HI= abs(HI) /*use the absolute value for HIGH. */ -w= length(HI) /*get maximum width for pretty output. */ -numeric digits max(9, w + 1) /*maybe bump the precision of numbers. */ -#= 0 /*the number of primes found (so far). */ - do n=abs(LO) to HI; f= factr(n) /*process a single number or a range.*/ - p= words( translate(f, ,@) ) - (n==1) /*P: is the number of prime factors. */ - if p==1 then #= # + 1 /*bump the primes counter (exclude N=1)*/ - if tell then say right(n, w) '=' @.p f /*display if a prime, plus its factors.*/ - end /*n*/ -say -say right(#, w) ' primes found.' /*display the number of primes found. */ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -factr: procedure expose @; parse arg z 1 n,$; if z<2 then return z /*is Z too small?*/ - do while z//2==0; $= $||@||2; z= z%2; end /*maybe add factor of 2 */ - do while z//3==0; $= $||@||3; z= z%3; end /* " " " " 3 */ - do while z//5==0; $= $||@||5; z= z%5; end /* " " " " 5 */ - do while z//7==0; $= $||@||7; z= z%7; end /* " " " " 7 */ - - do j=11 by 6 while j<=z /*insure that J isn't divisible by 3.*/ - parse var j '' -1 _ /*get the last decimal digit of J. */ - if _\==5 then do while z//j==0; $=$||@||j; z= z%j; end /*maybe reduce Z.*/ - if _ ==3 then iterate /*Next # ÷ by 5? Skip. ___ */ - if j*j>n then leave /*are we higher than the √ N ? */ - y= j + 2 /*obtain the next odd divisor. */ - do while z//y==0; $=$||@||y; z= z%y; end /*maybe reduce Z.*/ - end /*j*/ - if z==1 then return substr($, 1+length(@) ) /*Is residual=1? Don't add 1*/ - return substr($||@||z, 1+length(@) ) /*elide superfluous header. */ diff --git a/Task/Count-in-factors/REXX/count-in-factors-2.rexx b/Task/Count-in-factors/REXX/count-in-factors-2.rexx deleted file mode 100644 index 70b0c19ee5..0000000000 --- a/Task/Count-in-factors/REXX/count-in-factors-2.rexx +++ /dev/null @@ -1,51 +0,0 @@ -/*REXX program lists the prime factors of a specified integer (or a range of integers).*/ -@.=left('', 8); @.0="{unity} "; @.1='[prime] ' /*some tags and handy-dandy literals.*/ -parse arg LO HI @ . /*get optional arguments from the C.L. */ -if LO=='' | LO=="," then do; LO=1; HI=40; end /*Not specified? Then use the default.*/ -if HI=='' | HI=="," then HI= LO /* " " " " " " */ -if @=='' then @= 'x' /* " " " " " " */ -if length(@)\==1 then @= x2c(@) /*Not length 1? Then use hexadecimal. */ -tell= (HI>0) /*if HIGH is positive, then show #'s.*/ -HI= abs(HI) /*use the absolute value for HIGH. */ -w= length(HI) /*get maximum width for pretty output. */ -numeric digits max(9, w + 1) /*maybe bump the precision of numbers. */ -#= 0 /*the number of primes found (so far). */ - do n=abs(LO) to HI; f= factr(n) /*process a single number or a range.*/ - p= words( translate(f, ,@) ) - (n==1) /*P: is the number of prime factors. */ - if p==1 then #= # + 1 /*bump the primes counter (exclude N=1)*/ - if tell then say right(n, w) '=' @.p f /*display if a prime, plus its factors.*/ - end /*n*/ -say -say right(#, w) ' primes found.' /*display the number of primes found. */ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -factr: procedure expose @; parse arg z 1 n,$; if z<2 then return z /*is Z too small?*/ - do while z// 2==0; $= $||@||2 ; z= z%2 ; end /*maybe add factor of 2 */ - do while z// 3==0; $= $||@||3 ; z= z%3 ; end /* " " " " 3 */ - do while z// 5==0; $= $||@||5 ; z= z%5 ; end /* " " " " 5 */ - do while z// 7==0; $= $||@||7 ; z= z%7 ; end /* " " " " 7 */ - do while z//11==0; $= $||@||11; z= z%11; end /* " " " " 11 */ - do while z//13==0; $= $||@||13; z= z%13; end /* " " " " 13 */ - do while z//17==0; $= $||@||17; z= z%17; end /* " " " " 17 */ - do while z//19==0; $= $||@||19; z= z%19; end /* " " " " 19 */ - do while z//23==0; $= $||@||23; z= z%23; end /* " " " " 23 */ - do while z//29==0; $= $||@||29; z= z%29; end /* " " " " 29 */ - do while z//31==0; $= $||@||31; z= z%31; end /* " " " " 31 */ - do while z//37==0; $= $||@||37; z= z%37; end /* " " " " 37 */ - if z>40 then do; t= z; q= 1; r= 0; do while q<=t; q= q * 4 - end /*while*/ - do while q>1; q=q%4; _=t-r-q; r=r%2; if _>=0 then do; t=_; r=r+q - end - end /*while*/ /* [↑] find integer SQRT(z). */ - /*R: is the integer SQRT of Z.*/ - do j=41 by 6 to r while j<=z /*insure J isn't divisible by 3*/ - parse var j '' -1 _ /*get last decimal digit of J.*/ - if _\==5 then do while z//j==0; $=$||@||j; z= z%j; end - if _ ==3 then iterate /*Next number ÷ by 5 ? Skip.*/ - y= j + 2 /*use the next (odd) divisor. */ - do while z//y==0; $=$||@||y; z= z%y; end - end /*j*/ /* [↑] reduce Z by Y ? */ - end /*if z>40*/ - - if z==1 then return substr($, 1+length(@) ) /*Is residual=1? Don't add 1*/ - return substr($||@||z, 1+length(@) ) /*elide superfluous header. */ diff --git a/Task/Count-in-factors/REXX/count-in-factors-3.rexx b/Task/Count-in-factors/REXX/count-in-factors.rexx similarity index 61% rename from Task/Count-in-factors/REXX/count-in-factors-3.rexx rename to Task/Count-in-factors/REXX/count-in-factors.rexx index da6ee80ca5..23b203b666 100644 --- a/Task/Count-in-factors/REXX/count-in-factors-3.rexx +++ b/Task/Count-in-factors/REXX/count-in-factors.rexx @@ -1,6 +1,8 @@ -call Time('r') -say 'Count in factors - Using REXX libraries' -parse version version; say version +-- 25 Apr 2025 +include Settings + +say 'COUNT IN FACTORS' +say version say numeric digits 16 call CountFactors 1,20 @@ -9,7 +11,7 @@ call CountFactors 1e6,1e6+20 call CountFactors 1e9,1e9+20 call CountFactors 1e12,1e12+20 call CountFactors 1e15,1e15+20 -say Format(Time('e'),,3) 'seconds' +call Timer exit CountFactors: @@ -17,15 +19,15 @@ arg x,y say 'Factorization of the numbers' x 'to' y say do i = x to y - f = Factors(i) if i = 1 then s = '1 = 1' - else - s = i '=' - do j = 1 to f - s = s fact.factor.j - if j < f then - s = s 'x' + else do + s = i '='; f = Factors(i) + do j = 1 to f + s = s fact.j + if j < f then + s = s 'x' + end end say s end @@ -35,3 +37,5 @@ return include Numbers include Sequences include Functions +include Helper +include Abend diff --git a/Task/Count-in-octal/Ballerina/count-in-octal.ballerina b/Task/Count-in-octal/Ballerina/count-in-octal.ballerina new file mode 100644 index 0000000000..4a7519d379 --- /dev/null +++ b/Task/Count-in-octal/Ballerina/count-in-octal.ballerina @@ -0,0 +1,28 @@ +import ballerina/io; + +function reverse(string s) returns string { + string res = ""; + foreach int i in int:range(s.length() - 1, -1, -1) { + res += s[i]; + } + return res; +} + +function oct(int m) returns string { + if m <= 0 { return "0"; } + int n = m ; // make mutable + string res = ""; + while n > 0 { + res += (n % 8).toString(); + n /= 8; + } + return reverse(res); +} + +public function main() { + int i = 0; + while true { + io:println(oct(i)); + i += 1; + } +} diff --git a/Task/Cramers-rule/EasyLang/cramers-rule.easy b/Task/Cramers-rule/EasyLang/cramers-rule.easy index 826f0c1e40..737db12126 100644 --- a/Task/Cramers-rule/EasyLang/cramers-rule.easy +++ b/Task/Cramers-rule/EasyLang/cramers-rule.easy @@ -1,13 +1,11 @@ -proc det . a0[][] res . +func det &a0[][] . res = 1 a[][] = a0[][] n = len a[][] for j to n imax = j for i = j + 1 to n - if a[i][j] > a[imax][j] - imax = i - . + if a[i][j] > a[imax][j] : imax = i . if imax <> j swap a[imax][] a[j][] @@ -15,8 +13,7 @@ proc det . a0[][] res . . if abs a[j][j] < 1e-12 print "Singular matrix!" - res = 0 / 0 - return + return 0 / 0 . for i = j + 1 to n mult = -a[i][j] / a[j][j] @@ -25,22 +22,19 @@ proc det . a0[][] res . . . . - for i to n - res *= a[i][i] - . + for i to n : res *= a[i][i] + return res . -proc cramer_solve . a0[][] deta b[] col res . +func cramer_solve &a0[][] deta &b[] col . a[][] = a0[][] for i to len a[][] a[i][col] = b[i] . - det a[][] d - res = d / deta + return det a[][] / deta . a[][] = [ [ 2 -1 5 1 ] [ 3 2 2 -6 ] [ 1 3 3 -1 ] [ 5 -2 -3 3 ] ] b[] = [ -3 -32 -47 49 ] -det a[][] deta +deta = det a[][] for i to len a[][] - cramer_solve a[][] deta b[] i r - print r + print cramer_solve a[][] deta b[] i . diff --git a/Task/Create-a-file-on-magnetic-tape/JavaScript/create-a-file-on-magnetic-tape.js b/Task/Create-a-file-on-magnetic-tape/JavaScript/create-a-file-on-magnetic-tape.js new file mode 100644 index 0000000000..ec1a23ac9c --- /dev/null +++ b/Task/Create-a-file-on-magnetic-tape/JavaScript/create-a-file-on-magnetic-tape.js @@ -0,0 +1,2 @@ +const fs = require('fs'); +fs.writeFile('/dev/tape', 'text\n', 'utf8', () => {}); diff --git a/Task/Create-a-two-dimensional-array-at-runtime/Uiua/create-a-two-dimensional-array-at-runtime.uiua b/Task/Create-a-two-dimensional-array-at-runtime/Uiua/create-a-two-dimensional-array-at-runtime.uiua new file mode 100644 index 0000000000..caa43e89ca --- /dev/null +++ b/Task/Create-a-two-dimensional-array-at-runtime/Uiua/create-a-two-dimensional-array-at-runtime.uiua @@ -0,0 +1,7 @@ +⋕&sc &pf "Enter a width: " +⋕&sc &pf "Enter a height: " +˜↯0⊟ # create 2D array filled with 0 +⍜⊡⋅3 1_2 # store 3 at row 1, col 2 +⟜&s # show array non-destructively +⊡1_2 # retrieve element at row 1, col 2 + # this also destroys the array diff --git a/Task/Create-an-object-at-a-given-address/XPL0/create-an-object-at-a-given-address.xpl0 b/Task/Create-an-object-at-a-given-address/XPL0/create-an-object-at-a-given-address.xpl0 new file mode 100644 index 0000000000..fd3ff6cb00 --- /dev/null +++ b/Task/Create-an-object-at-a-given-address/XPL0/create-an-object-at-a-given-address.xpl0 @@ -0,0 +1,15 @@ +int Obj; \create an integer object +char Addr; +[HexOut(0, @Obj); \print the machine address of the object (relative to some base) +CrLf(0); +Addr:= @Obj; \take the address of the object and +Addr(0):= $78; \ create another integer object at this address +Addr(1):= $56; +Addr(2):= $34; +Addr(3):= $12; +HexOut(0, Obj); \print the value of this object to verify that +CrLf(0); \ it is same as one of the origin +Obj:= $DEADBEEF; \change the value of the origin and verify it again +HexOut(0, Obj); +CrLf(0); +] diff --git a/Task/Cuban-primes/EasyLang/cuban-primes.easy b/Task/Cuban-primes/EasyLang/cuban-primes.easy index 69a869b15b..8140fa46a5 100644 --- a/Task/Cuban-primes/EasyLang/cuban-primes.easy +++ b/Task/Cuban-primes/EasyLang/cuban-primes.easy @@ -1,27 +1,24 @@ -fastfunc isprim_odd num . - i = 3 +fastfunc isprim num . + if num mod 2 = 0 : return 0 + if num mod 3 = 0 : return 0 + i = 5 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 + if num mod i = 0 : return 0 + i += 4 . return 1 . -numfmt 0 7 i = 1 -while cnt < 100000 +while cnt < 50000 di = 3 * i * (i + 1) + 1 - if isprim_odd di = 1 + if isprim di = 1 cnt += 1 - if cnt <= 200 - write di & " " - if cnt mod 5 = 0 - print "" - . - . + if cnt <= 200 : write di & " " . i += 1 . print "" +print "" print di diff --git a/Task/Cuban-primes/OCaml/cuban-primes.ml b/Task/Cuban-primes/OCaml/cuban-primes.ml new file mode 100644 index 0000000000..af8c106059 --- /dev/null +++ b/Task/Cuban-primes/OCaml/cuban-primes.ml @@ -0,0 +1,51 @@ +let is_prime (n : int) : bool = + if n = 2 then true else if n < 2 || n mod 2 = 0 then false else + let lim = (n |> float_of_int |> sqrt |> int_of_float) + 1 in + let rec loop = function + | i when i > lim -> true + | i when n mod i = 0 -> false + | i -> loop (i + 2) + in loop 3 + +let char_list_of_string s = List.init (String.length s) (String.get s) + +let commatize (str : string) : string = + let revchars = List.rev (char_list_of_string str) in + let rec take_threes = function + | s, c1 :: c2 :: c3 :: rest -> + take_threes ([c3; c2; c1] :: s, rest) + | ss, rest -> if rest = [] then ss else List.rev rest :: ss + in take_threes ([], List.map Char.escaped revchars) + |> List.map (String.concat "") |> String.concat "," + +let cube (n: int) : int = n * n * n + +let scan_for_cubans (num : int) : int list = + let rec loop = function + | n, ps when List.length ps >= num -> ps + | n, ps -> + let c = cube (n + 1) - cube n in + if is_prime c then loop (n + 1, c :: ps) + else loop (n + 1, ps) in + loop (1, []) |> List.rev + +let nth_cuban (n : int) : int = + let rec loop = function + | i, c, p when c = n -> p + | i, c, p -> + let k = cube (i + 1) - cube i in + if is_prime k then loop (i + 1, c + 1, k) + else loop (i + 1, c, p) in + loop (0, 0, 0) + +let () = + print_endline "The first 200 cuban primes are: "; + scan_for_cubans 200 + |> List.map string_of_int + |> List.map commatize + |> String.concat " | " + |> Printf.printf "[%s]\n\n"; + nth_cuban 100_000 + |> string_of_int + |> commatize + |> Printf.printf "The 100,000th cuban prime is %s\n" diff --git a/Task/Cuban-primes/REXX/cuban-primes-1.rexx b/Task/Cuban-primes/REXX/cuban-primes-1.rexx deleted file mode 100644 index c12e91bb2d..0000000000 --- a/Task/Cuban-primes/REXX/cuban-primes-1.rexx +++ /dev/null @@ -1,27 +0,0 @@ -/*REXX program finds and displays a number of cuban primes or the Nth cuban prime. */ -numeric digits 20 /*ensure enough decimal digits for #s. */ -parse arg N . /*obtain optional argument from the CL.*/ -if N=='' | N=="," then N= 200 /*Not specified? Then use the default.*/ -Nth= N<0; N= abs(N) /*used for finding the Nth cuban prime.*/ -@.=0; @.0=1; @.2=1; @.3=1; @.4=1; @.5=1; @.6=1; @.8=1 /*ending digs that aren't cubans.*/ -sw= linesize() - 1; if sw<1 then sw= 79 /*obtain width of the terminal screen. */ -w=12; #= 1; $= right(7, w) /*start with first cuban prime; count.*/ - do j=1 until #=>N; x= (j+1)**3 - j**3 /*compute a possible cuban prime. */ - parse var x '' -1 _; if @._ then iterate /*check last digit for non─cuban prime.*/ - do k=1 until km*km>x; km= k*6 + 1 /*cuban primes can't be ÷ by 6k+1 */ - if x//km==0 then iterate j /*Divisible? Then not a cuban prime. */ - end /*k*/ - #= #+1 /*bump the number of cuban primes found*/ - if Nth then do; if #==N then do; say commas(x); leave j; end /*display 1 num.*/ - else iterate /*j*/ /*keep searching*/ - end /* [↑] try to fit as many #s per line.*/ - cx= commas(x); L= length(cx) /*insert commas──►X; obtain the length.*/ - cx= right(cx, max(w, L) ); new= $ cx /*right justify CX; concat to new list*/ - if length(new)>sw then do; say $; $= cx /*line is too long, display #'s so far.*/ - end /* [↑] initialize the (new) next line.*/ - else $= new /*start with cuban # that wouldn't fit.*/ - end /*j*/ - if \Nth & $\=='' then say $ /*check for residual cuban primes in $.*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _ diff --git a/Task/Cuban-primes/REXX/cuban-primes-2.rexx b/Task/Cuban-primes/REXX/cuban-primes.rexx similarity index 92% rename from Task/Cuban-primes/REXX/cuban-primes-2.rexx rename to Task/Cuban-primes/REXX/cuban-primes.rexx index f10b489598..6e36b4e1e0 100644 --- a/Task/Cuban-primes/REXX/cuban-primes-2.rexx +++ b/Task/Cuban-primes/REXX/cuban-primes.rexx @@ -1,6 +1,7 @@ include Settings - -say version; say 'Cuban primes'; say +say 'CUBAN PRIMES - 3 Mar 2025' +say version +say numeric digits 20 call ShowCubans 1,200,8 call ShowCubans 100000,,13 diff --git a/Task/Cumulative-standard-deviation/EasyLang/cumulative-standard-deviation.easy b/Task/Cumulative-standard-deviation/EasyLang/cumulative-standard-deviation.easy index 58aa6b4817..72e795da02 100644 --- a/Task/Cumulative-standard-deviation/EasyLang/cumulative-standard-deviation.easy +++ b/Task/Cumulative-standard-deviation/EasyLang/cumulative-standard-deviation.easy @@ -1,12 +1,11 @@ global sum sum2 n . -proc sd x . r . +func sd x . sum += x sum2 += x * x n += 1 - r = sqrt (sum2 / n - sum * sum / n / n) + return sqrt (sum2 / n - sum * sum / n / n) . v[] = [ 2 4 4 4 5 5 7 9 ] for v in v[] - sd v r - print v & " " & r + print v & " " & sd v . diff --git a/Task/Currency/Ballerina/currency.ballerina b/Task/Currency/Ballerina/currency.ballerina new file mode 100644 index 0000000000..94a706246d --- /dev/null +++ b/Task/Currency/Ballerina/currency.ballerina @@ -0,0 +1,15 @@ +import ballerina/io; + +public function main() { + decimal hamburgers = 4000000000000000; + decimal milkshakes = 2; + decimal price1 = 5.5; + decimal price2 = 2.86; + decimal taxPc = 0.0765; + decimal totalPreTax = hamburgers * price1 + milkshakes * price2; + decimal totalTax = taxPc * totalPreTax; + decimal totalAfterTax = totalPreTax + totalTax; + io:println("Total price before tax : ", totalPreTax.round(2)); + io:println("Tax : ", totalTax.round(2)); + io:println("Total price after tax : ", totalAfterTax.round(2)); +} diff --git a/Task/Currency/C++/currency.cpp b/Task/Currency/C++/currency.cpp new file mode 100644 index 0000000000..ea15245678 --- /dev/null +++ b/Task/Currency/C++/currency.cpp @@ -0,0 +1,21 @@ +#include + +struct menu_entry { + mpz_class amount; + std::string name; + mpf_class price; +}; + +int main() { + menu_entry menu[] = { 4000000000000000, "hamburgers", 5.50, + 2, "milkshakes", 2.86 }; + mpf_class taxRate; + taxRate.set_str("0.0765", 10); + mpf_class total = 0; + for (menu_entry i : menu) + total += i.price * i.amount; + gmp_printf("total: €%.2Ff\n", total.get_mpf_t()); + mpf_class tax = total * taxRate; + gmp_printf("tax: €%.2Ff\n", tax.get_mpf_t()); + gmp_printf("total+tax: €%.2Ff\n", mpf_class{total+tax}.get_mpf_t()); +} diff --git a/Task/Currency/Wren/currency.wren b/Task/Currency/Wren/currency.wren index 56479aae74..6cf58ddbd8 100644 --- a/Task/Currency/Wren/currency.wren +++ b/Task/Currency/Wren/currency.wren @@ -5,7 +5,6 @@ var milkshakes = BigRat.two var price1 = BigRat.fromFloat(5.5) var price2 = BigRat.fromFloat(2.86) var taxPc = BigRat.fromFloat(0.0765) -var totalPc = BigRat.fromFloat(1.0765) var totalPreTax = hamburgers*price1 + milkshakes*price2 var totalTax = taxPc * totalPreTax var totalAfterTax = totalPreTax + totalTax diff --git a/Task/Currying/Ballerina/currying.ballerina b/Task/Currying/Ballerina/currying.ballerina new file mode 100644 index 0000000000..714a8b83de --- /dev/null +++ b/Task/Currying/Ballerina/currying.ballerina @@ -0,0 +1,12 @@ +import ballerina/io; + +public function main() { + var addN = function(int n) returns (function(int) returns int) { + return function(int x) returns int { + return n + x; + }; + }; + + var adder = addN(40); + io:println("The answer to life is ", adder(2), "."); +} diff --git a/Task/Curzon-numbers/Ada/curzon-numbers.ada b/Task/Curzon-numbers/Ada/curzon-numbers.ada new file mode 100644 index 0000000000..31133f80d5 --- /dev/null +++ b/Task/Curzon-numbers/Ada/curzon-numbers.ada @@ -0,0 +1,57 @@ +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Long_Long_Integer_Text_IO; use Ada.Long_Long_Integer_Text_IO; + +procedure Curzon is + + function Mod_Pow(Base, Exp, Modulo : Long_Long_Integer) return Long_Long_Integer is + Result : Long_Long_Integer := 1; + B : Long_Long_Integer := Base mod Modulo; + E : Long_Long_Integer := Exp; + begin + if Modulo = 1 then return 0; end if; + + while E > 0 loop + if (E mod 2) = 1 then + Result := (Result * B) mod Modulo; + end if; + B := (B * B) mod Modulo; + E := E / 2; + end loop; + + return Result; + end Mod_Pow; + + function Curzon_Check(K, N : Long_Long_Integer) return Boolean is + R : Long_Long_Integer := K * N; + begin + return Mod_Pow(K, N, R + 1) = R; + end Curzon_Check; + + N : Long_Long_Integer; + Count : Integer; + +begin + for K in Long_Long_Integer range 2..10 when K mod 2 = 0 loop + Put("The first 50 Curzon numbers of base "); Put(K, 1); Put(":"); New_Line; + N := 1; + Count := 1; + while Count <= 1000 loop + if Curzon_Check(K, N) then + if Count <= 50 then + Put(N, 4); + if Count mod 10 = 0 then + New_Line; + else + Put(" "); + end if; + end if; + if Count = 1000 then + Put("The 1000th Curzon number of base "); Put(K, 1); Put(": "); Put(N, 5); + New_Line(2); + end if; + Count := @ + 1; + end if; + N := @ + 1; + end loop; + end loop; +end Curzon; diff --git a/Task/Curzon-numbers/EasyLang/curzon-numbers.easy b/Task/Curzon-numbers/EasyLang/curzon-numbers.easy index 377ecd0a69..4af14d89ff 100644 --- a/Task/Curzon-numbers/EasyLang/curzon-numbers.easy +++ b/Task/Curzon-numbers/EasyLang/curzon-numbers.easy @@ -12,7 +12,7 @@ func pow_mod b power modulus . for k = 2 step 2 to 10 numfmt 0 0 print "First 50 Curzon numbers using a base of " & k & ":" - numfmt 0 4 + numfmt 4 0 n = 1 count = 0 repeat @@ -22,9 +22,7 @@ for k = 2 step 2 to 10 count += 1 if count <= 50 write " " & n - if count mod 9 = 0 - print "" - . + if count mod 9 = 0 : print "" . . until count = 1000 diff --git a/Task/Cut-a-rectangle/EasyLang/cut-a-rectangle.easy b/Task/Cut-a-rectangle/EasyLang/cut-a-rectangle.easy index adf933a05a..fb028df61c 100644 --- a/Task/Cut-a-rectangle/EasyLang/cut-a-rectangle.easy +++ b/Task/Cut-a-rectangle/EasyLang/cut-a-rectangle.easy @@ -1,7 +1,7 @@ global grid[] blen w h cnt . dir[][] = [ [ 0 -1 ] [ -1 0 ] [ 0 1 ] [ 1 0 ] ] # -proc walk y x . . +proc walk y x . if y = 0 or y = h or x = 0 or x = w cnt += 2 return @@ -20,12 +20,10 @@ proc walk y x . . grid[t] -= 1 grid[blen - t] -= 1 . -proc solve hh ww recur . . +proc solve hh ww recur . w = ww h = hh - if h mod 2 = 1 - swap h w - . + if h mod 2 = 1 : swap h w if h mod 2 = 1 cnt = 0 return @@ -63,7 +61,7 @@ proc solve hh ww recur . . solve w h 0 . . -proc main . . +proc main . for y = 1 to 8 for x = 1 to y if x mod 2 = 0 or y mod 2 = 0 diff --git a/Task/Cyclops-numbers/EasyLang/cyclops-numbers.easy b/Task/Cyclops-numbers/EasyLang/cyclops-numbers.easy index 24688034b0..f8fa7814c0 100644 --- a/Task/Cyclops-numbers/EasyLang/cyclops-numbers.easy +++ b/Task/Cyclops-numbers/EasyLang/cyclops-numbers.easy @@ -1,7 +1,5 @@ func is_cyclops n . - if n = 0 - return 1 - . + if n = 0 : return 1 m = n mod 10 while m <> 0 count += 1 @@ -20,9 +18,7 @@ func is_cyclops n . fastfunc isprim num . i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 @@ -51,7 +47,7 @@ func is_palindr n . . return if n = k . -proc show . . +proc show . while cnt < 50 if is_cyclops i = 1 write i & " " diff --git a/Task/Cyclops-numbers/REXX/cyclops-numbers.rexx b/Task/Cyclops-numbers/REXX/cyclops-numbers.rexx index a5180ac70f..858afb6424 100644 --- a/Task/Cyclops-numbers/REXX/cyclops-numbers.rexx +++ b/Task/Cyclops-numbers/REXX/cyclops-numbers.rexx @@ -1,42 +1,24 @@ +-- 22 Mar 2025 include Settings -say version; say 'Cyclops numbers'; say +say 'CYCLOPS NUMBERS' +say version +say numeric digits 10; cycl. = 0 -call GetCyclops 115e6 -call Cyclops +call Cyclops 115e6 +say cycl.0 'cyclops numbers generated < 115 million'; say +call CyclopsNumbers call PrimeCyclops -call BlindPrimeCyclops -call PalPrimeCyclops +call BlindCyclops +call PalindromicCyclops say Format(Time('e'),,3) 'seconds' exit -GetCyclops: -procedure expose cycl. -arg x -m = 0; n = 1; cycl.cyclop.1 = 0 -do f = 1 - h = m+1; m = n - do j = 1 to 9 - do i = h to m - a = cycl.cyclop.i - do k = 1 to 9 - b = j||a||k - if b > x then - leave f - n = n+1; cycl.cyclop.n = b - end - end - end -end -cycl.0 = n -say n 'cyclops numbers generated <' x; say -return - -Cyclops: +CyclopsNumbers: procedure expose cycl. say 'First 50 cyclop numbers:' do i = 1 to cycl.0 - a = cycl.cyclop.i + a = cycl.i if i <= 50 then do call Charout ,Right(a,8) if i//10 = 0 then @@ -54,7 +36,7 @@ procedure expose cycl. say 'First 50 prime cyclop numbers:' n = 0 do i = 2 to cycl.0 - a = cycl.cyclop.i + a = cycl.i if Prime(a) then do n = n+1 if n <= 50 then do @@ -70,12 +52,12 @@ do i = 2 to cycl.0 end return -BlindPrimeCyclops: +BlindCyclops: procedure expose cycl. say 'First 50 blind prime cyclop numbers:' n = 0 do i = 2 to cycl.0 - a = cycl.cyclop.i + a = cycl.i if Prime(a) then do l = Length(a); m = l%2; b = Left(a,m)||Right(a,m) if Prime(b) then do @@ -94,12 +76,12 @@ do i = 2 to cycl.0 end return -PalPrimeCyclops: +PalindromicCyclops: procedure expose cycl. say 'First 50 palindromic prime cyclop numbers:' n = 0 do i = 2 to cycl.0 - a = cycl.cyclop.i + a = cycl.i if a = Reverse(a) then do if Prime(a) then do n = n+1 @@ -117,5 +99,7 @@ do i = 2 to cycl.0 end return +include Sequences include Numbers include Functions +include Abend diff --git a/Task/Cyclotomic-polynomial/JavaScript/cyclotomic-polynomial.js b/Task/Cyclotomic-polynomial/JavaScript/cyclotomic-polynomial.js new file mode 100644 index 0000000000..7690d386c5 --- /dev/null +++ b/Task/Cyclotomic-polynomial/JavaScript/cyclotomic-polynomial.js @@ -0,0 +1,504 @@ +const MAX_ALL_FACTORS = 100000; +const algorithm = 2; +let divisions = 0; + +// Term class +class Term { + constructor(c, e) { + this.m_coefficient = c; + this.m_exponent = e; + } + + coefficient() { + return this.m_coefficient; + } + + degree() { + return this.m_exponent; + } + + negated() { + return new Term(-this.m_coefficient, this.m_exponent); + } + + multiply(rhs) { + return new Term(this.m_coefficient * rhs.m_coefficient, this.m_exponent + rhs.m_exponent); + } + + add(rhs) { + if (this.m_exponent !== rhs.m_exponent) { + throw new Error("Exponents not equal"); + } + return new Term(this.m_coefficient + rhs.m_coefficient, this.m_exponent); + } + + toString() { + if (this.m_coefficient === 0) { + return '0'; + } + if (this.m_exponent === 0) { + return this.m_coefficient.toString(); + } + if (this.m_coefficient === 1) { + if (this.m_exponent === 1) { + return 'x'; + } + return `x^${this.m_exponent}`; + } + if (this.m_coefficient === -1) { + if (this.m_exponent === 1) { + return "-x"; + } + return `-x^${this.m_exponent}`; + } + if (this.m_exponent === 1) { + return `${this.m_coefficient}x`; + } + return `${this.m_coefficient}x^${this.m_exponent}`; + } +} + +// Polynomial class +class Polynomial { + constructor(values) { + this.polynomialTerms = []; + + if (values === undefined) { + this.polynomialTerms.push(new Term(0, 0)); + } else if (Array.isArray(values) && values.length % 2 === 0) { + for (let i = 0; i < values.length; i += 2) { + this.polynomialTerms.push(new Term(values[i], values[i+1])); + } + this.polynomialTerms.sort((t, u) => u.degree() - t.degree()); + } else if (Array.isArray(values)) { + if (values.length === 0) { + this.polynomialTerms.push(new Term(0, 0)); + } else { + for (let t of values) { + if (t.coefficient() !== 0) { + this.polynomialTerms.push(t); + } + } + if (this.polynomialTerms.length === 0) { + this.polynomialTerms.push(new Term(0, 0)); + } + this.polynomialTerms.sort((t, u) => u.degree() - t.degree()); + } + } + } + + leadingCoefficient() { + return this.polynomialTerms[0].coefficient(); + } + + degree() { + return this.polynomialTerms[0].degree(); + } + + hasCoefficientAbs(coeff) { + for (let term of this.polynomialTerms) { + if (Math.abs(term.coefficient()) === coeff) { + return true; + } + } + return false; + } + + addTerm(term) { + const termList = []; + let added = false; + + for (let index = 0; index < this.polynomialTerms.length; index++) { + const currentTerm = this.polynomialTerms[index]; + if (currentTerm.degree() === term.degree()) { + added = true; + if (currentTerm.coefficient() + term.coefficient() !== 0) { + termList.push(currentTerm.add(term)); + } + } else { + termList.push(currentTerm); + } + } + + if (!added) { + termList.push(term); + } + + return new Polynomial(termList); + } + + multiplyByTerm(term) { + const termList = []; + + for (let index = 0; index < this.polynomialTerms.length; index++) { + const currentTerm = this.polynomialTerms[index]; + termList.push(currentTerm.multiply(term)); + } + + return new Polynomial(termList); + } + + add(p) { + const termList = []; + let thisCount = this.polynomialTerms.length; + let polyCount = p.polynomialTerms.length; + + while (thisCount > 0 || polyCount > 0) { + if (thisCount === 0) { + const polyTerm = p.polynomialTerms[polyCount - 1]; + termList.push(polyTerm); + polyCount--; + } else if (polyCount === 0) { + const thisTerm = this.polynomialTerms[thisCount - 1]; + termList.push(thisTerm); + thisCount--; + } else { + const polyTerm = p.polynomialTerms[polyCount - 1]; + const thisTerm = this.polynomialTerms[thisCount - 1]; + + if (thisTerm.degree() === polyTerm.degree()) { + const t = thisTerm.add(polyTerm); + if (t.coefficient() !== 0) { + termList.push(t); + } + thisCount--; + polyCount--; + } else if (thisTerm.degree() < polyTerm.degree()) { + termList.push(thisTerm); + thisCount--; + } else { + termList.push(polyTerm); + polyCount--; + } + } + } + + return new Polynomial(termList); + } + + divide(v) { + divisions++; + + let q = new Polynomial(); + let r = new Polynomial(this.polynomialTerms); + const lcv = v.leadingCoefficient(); + const dv = v.degree(); + + while (r.degree() >= v.degree()) { + const lcr = r.leadingCoefficient(); + const s = Math.floor(lcr / lcv); + const term = new Term(s, r.degree() - dv); + q = q.addTerm(term); + r = r.add(v.multiplyByTerm(term.negated())); + } + + return q; + } + + toString() { + if (this.polynomialTerms.length === 0) { + return '0'; + } + + let result = this.polynomialTerms[0].toString(); + + for (let i = 1; i < this.polynomialTerms.length; i++) { + const term = this.polynomialTerms[i]; + if (term.coefficient() > 0) { + result += ` + ${term.toString()}`; + } else { + result += ` - ${term.negated().toString()}`; + } + } + + return result; + } +} + +function getDivisors(number) { + const divisors = []; + const root = Math.floor(Math.sqrt(number)); + + for (let i = 1; i <= root; i++) { + if (number % i === 0) { + divisors.push(i); + const div = Math.floor(number / i); + if (div !== i && div !== number) { + divisors.push(div); + } + } + } + + return divisors; +} + +const allFactors = new Map(); + +function getFactors(number) { + if (allFactors.has(number)) { + return allFactors.get(number); + } + + const factors = new Map(); + + if (number % 2 === 0) { + const factorsDivTwo = getFactors(number / 2); + for (const [key, value] of factorsDivTwo) { + factors.set(key, value); + } + factors.set(2, (factors.get(2) || 0) + 1); + + if (number < MAX_ALL_FACTORS) { + allFactors.set(number, factors); + } + + return factors; + } + + const root = Math.floor(Math.sqrt(number)); + let i = 3; + + while (i <= root) { + if (number % i === 0) { + const factorsDivI = getFactors(number / i); + for (const [key, value] of factorsDivI) { + factors.set(key, value); + } + factors.set(i, (factors.get(i) || 0) + 1); + + if (number < MAX_ALL_FACTORS) { + allFactors.set(number, factors); + } + + return factors; + } + i += 2; + } + + factors.set(number, 1); + + if (number < MAX_ALL_FACTORS) { + allFactors.set(number, factors); + } + + return factors; +} + +const COMPUTED = new Map(); + +function cyclotomicPolynomial(n) { + if (COMPUTED.has(n)) { + return COMPUTED.get(n); + } + + if (n === 1) { + // Polynomial: x - 1 + const p = new Polynomial([1, 1, -1, 0]); + COMPUTED.set(1, p); + return p; + } + + const factors = getFactors(n); + + if (factors.has(n)) { + // n prime + const termList = []; + for (let index = 0; index < n; index++) { + termList.push(new Term(1, index)); + } + + const cyclo = new Polynomial(termList); + COMPUTED.set(n, cyclo); + return cyclo; + } else if (factors.size === 2 && factors.has(2) && factors.get(2) === 1 && factors.has(n / 2) && factors.get(n / 2) === 1) { + // n = 2p + const prime = n / 2; + const termList = []; + let coeff = -1; + + for (let index = 0; index < prime; index++) { + coeff *= -1; + termList.push(new Term(coeff, index)); + } + + const cyclo = new Polynomial(termList); + COMPUTED.set(n, cyclo); + return cyclo; + } else if (factors.size === 1 && factors.has(2)) { + // n = 2^h + const h = factors.get(2); + const termList = []; + termList.push(new Term(1, Math.pow(2, h - 1))); + termList.push(new Term(1, 0)); + + const cyclo = new Polynomial(termList); + COMPUTED.set(n, cyclo); + return cyclo; + } else if (factors.size === 1 && factors.has(n)) { + // n = p^k + let p = 0; + let k = 0; + + for (const [key, value] of factors) { + p = key; + k = value; + } + + const termList = []; + for (let index = 0; index < p; index++) { + termList.push(new Term(1, index * Math.pow(p, k - 1))); + } + + const cyclo = new Polynomial(termList); + COMPUTED.set(n, cyclo); + return cyclo; + } else if (factors.size === 2 && factors.has(2)) { + // n = 2^h * p^k + let p = 0; + + for (const [key, value] of factors) { + if (key !== 2) { + p = key; + } + } + + const termList = []; + let coeff = -1; + const twoExp = Math.pow(2, factors.get(2) - 1); + const k = factors.get(p); + + for (let index = 0; index < p; index++) { + coeff *= -1; + termList.push(new Term(coeff, index * twoExp * Math.pow(p, k - 1))); + } + + const cyclo = new Polynomial(termList); + COMPUTED.set(n, cyclo); + return cyclo; + } else if (factors.has(2) && ((n / 2) % 2 === 1) && (n / 2) > 1) { + // CP(2m)[x] = CP(-m)[x], n odd integer > 1 + const cycloDiv2 = cyclotomicPolynomial(n / 2); + const termList = []; + + for (const term of cycloDiv2.polynomialTerms) { + if (term.degree() % 2 === 0) { + termList.push(term); + } else { + termList.push(term.negated()); + } + } + + const cyclo = new Polynomial(termList); + COMPUTED.set(n, cyclo); + return cyclo; + } + + // General Case + if (algorithm === 0) { + // slow - uses basic definition + const divisors = getDivisors(n); + // Polynomial: (x^n - 1) + let cyclo = new Polynomial([1, n, -1, 0]); + + for (const i of divisors) { + const p = cyclotomicPolynomial(i); + cyclo = cyclo.divide(p); + } + + COMPUTED.set(n, cyclo); + return cyclo; + } else if (algorithm === 1) { + // Faster. Remove Max divisor (and all divisors of max divisor) - only one divide for all divisors of Max Divisor + const divisors = getDivisors(n); + let maxDivisor = Number.MIN_SAFE_INTEGER; + + for (const div of divisors) { + maxDivisor = Math.max(maxDivisor, div); + } + + const divisorExceptMax = []; + for (const div of divisors) { + if (maxDivisor % div !== 0) { + divisorExceptMax.push(div); + } + } + + // Polynomial: ( x^n - 1 ) / ( x^m - 1 ), where m is the max divisor + let cyclo = new Polynomial([1, n, -1, 0]).divide(new Polynomial([1, maxDivisor, -1, 0])); + + for (const i of divisorExceptMax) { + const p = cyclotomicPolynomial(i); + cyclo = cyclo.divide(p); + } + + COMPUTED.set(n, cyclo); + return cyclo; + } else if (algorithm === 2) { + // Fastest + // Let p ; q be primes such that p does not divide n, and q q divides n. + // Then CP(np)[x] = CP(n)[x^p] / CP(n)[x] + let m = 1; + let cyclo = cyclotomicPolynomial(m); + const primes = Array.from(factors.keys()).sort((a, b) => a - b); + + for (const prime of primes) { + // CP(m)[x] + const cycloM = cyclo; + // Compute CP(m)[x^p]. + const termList = []; + + for (const t of cycloM.polynomialTerms) { + termList.push(new Term(t.coefficient(), t.degree() * prime)); + } + + cyclo = new Polynomial(termList).divide(cycloM); + m = m * prime; + } + + // Now, m is the largest square free divisor of n + const s = n / m; + // Compute CP(n)[x] = CP(m)[x^s] + const termList = []; + + for (const t of cyclo.polynomialTerms) { + termList.push(new Term(t.coefficient(), t.degree() * s)); + } + + cyclo = new Polynomial(termList); + COMPUTED.set(n, cyclo); + return cyclo; + } else { + throw new Error("Invalid algorithm"); + } +} + +function main() { + // initialization + const factors = new Map(); + factors.set(2, 1); + allFactors.set(2, factors); + + // Task 1: cyclotomic polynomials for n <= 30 + console.log("Task 1: cyclotomic polynomials for n <= 30:"); + for (let i = 1; i <= 30; i++) { + const p = cyclotomicPolynomial(i); + console.log(`CP[${i}] = ${p.toString()}`); + } + + // Task 2: Smallest cyclotomic polynomial with n or -n as a coefficient + console.log("Task 2: Smallest cyclotomic polynomial with n or -n as a coefficient:"); + let n = 0; + for (let i = 1; i <= 10; i++) { + while (true) { + n++; + const cyclo = cyclotomicPolynomial(n); + if (cyclo.hasCoefficientAbs(i)) { + console.log(`CP[${n}] has coefficient with magnitude = ${i}`); + n--; + break; + } + } + } +} + +main(); diff --git a/Task/Cyclotomic-polynomial/Rust/cyclotomic-polynomial.rs b/Task/Cyclotomic-polynomial/Rust/cyclotomic-polynomial.rs new file mode 100644 index 0000000000..98be747dcc --- /dev/null +++ b/Task/Cyclotomic-polynomial/Rust/cyclotomic-polynomial.rs @@ -0,0 +1,552 @@ +use std::cmp::{max, Ordering}; +use std::collections::HashMap; +use std::fmt; +use std::ops::{Add, Div, Mul, Neg}; + +const MAX_ALL_FACTORS: i32 = 100000; +const ALGORITHM: i32 = 2; +static mut DIVISIONS: i32 = 0; + +// Note: Cyclotomic Polynomials have small coefficients. Not appropriate for general polynomial usage. +#[derive(Clone, Debug)] +struct Term { + coefficient: i64, + exponent: i64, +} + +impl Term { + fn new(c: i64, e: i64) -> Self { + Term { + coefficient: c, + exponent: e, + } + } + + fn coefficient(&self) -> i64 { + self.coefficient + } + + fn degree(&self) -> i64 { + self.exponent + } +} + +impl Neg for Term { + type Output = Term; + + fn neg(self) -> Self::Output { + Term::new(-self.coefficient, self.exponent) + } +} + +impl Neg for &Term { + type Output = Term; + + fn neg(self) -> Self::Output { + Term::new(-self.coefficient, self.exponent) + } +} + +impl Mul for &Term { + type Output = Term; + + fn mul(self, rhs: &Term) -> Self::Output { + Term::new(self.coefficient * rhs.coefficient, self.exponent + rhs.exponent) + } +} + +impl Add for &Term { + type Output = Term; + + fn add(self, rhs: &Term) -> Self::Output { + if self.exponent != rhs.exponent { + panic!("Exponents not equal"); + } + Term::new(self.coefficient + rhs.coefficient, self.exponent) + } +} + +impl fmt::Display for Term { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.coefficient == 0 { + return write!(f, "0"); + } + if self.exponent == 0 { + return write!(f, "{}", self.coefficient); + } + if self.coefficient == 1 { + if self.exponent == 1 { + return write!(f, "x"); + } + return write!(f, "x^{}", self.exponent); + } + if self.coefficient == -1 { + if self.exponent == 1 { + return write!(f, "-x"); + } + return write!(f, "-x^{}", self.exponent); + } + if self.exponent == 1 { + return write!(f, "{}x", self.coefficient); + } + write!(f, "{}x^{}", self.coefficient, self.exponent) + } +} + +#[derive(Clone, Debug)] +struct Polynomial { + polynomial_terms: Vec, +} + +impl Polynomial { + fn new() -> Self { + let mut terms = Vec::new(); + terms.push(Term::new(0, 0)); + Polynomial { + polynomial_terms: terms, + } + } + + fn from_values(values: &[i32]) -> Self { + if values.len() % 2 != 0 { + panic!("Length must be even."); + } + + let mut terms = Vec::new(); + let mut i = 0; + while i < values.len() { + terms.push(Term::new(values[i] as i64, values[i + 1] as i64)); + i += 2; + } + + terms.sort_by(|a, b| b.degree().cmp(&a.degree())); + Polynomial { + polynomial_terms: terms, + } + } + + fn from_term_list(term_list: &[Term]) -> Self { + let mut terms = Vec::new(); + if term_list.is_empty() { + terms.push(Term::new(0, 0)); + } else { + for t in term_list { + if t.coefficient() != 0 { + terms.push(t.clone()); + } + } + if terms.is_empty() { + terms.push(Term::new(0, 0)); + } + terms.sort_by(|a, b| b.degree().cmp(&a.degree())); + } + Polynomial { + polynomial_terms: terms, + } + } + + fn leading_coefficient(&self) -> i64 { + self.polynomial_terms[0].coefficient() + } + + fn degree(&self) -> i64 { + self.polynomial_terms[0].degree() + } + + fn has_coefficient_abs(&self, coeff: i32) -> bool { + for term in &self.polynomial_terms { + if (term.coefficient() as i32).abs() == coeff { + return true; + } + } + false + } + + fn add_term(&self, term: &Term) -> Polynomial { + let mut term_list = Vec::new(); + let mut added = false; + for current_term in &self.polynomial_terms { + if current_term.degree() == term.degree() { + added = true; + let sum_coeff = current_term.coefficient() + term.coefficient(); + if sum_coeff != 0 { + term_list.push(Term::new(sum_coeff, term.degree())); + } + } else { + term_list.push(current_term.clone()); + } + } + if !added { + term_list.push(term.clone()); + } + Polynomial::from_term_list(&term_list) + } + + fn mul_term(&self, term: &Term) -> Polynomial { + let mut term_list = Vec::new(); + for current_term in &self.polynomial_terms { + term_list.push((current_term * term).clone()); + } + Polynomial::from_term_list(&term_list) + } +} + +impl Add for &Polynomial { + type Output = Polynomial; + + fn add(self, rhs: &Polynomial) -> Self::Output { + let mut term_list = Vec::new(); + let mut this_count = self.polynomial_terms.len(); + let mut poly_count = rhs.polynomial_terms.len(); + + while this_count > 0 || poly_count > 0 { + if this_count == 0 { + let poly_term = &rhs.polynomial_terms[poly_count - 1]; + term_list.push(poly_term.clone()); + poly_count -= 1; + } else if poly_count == 0 { + let this_term = &self.polynomial_terms[this_count - 1]; + term_list.push(this_term.clone()); + this_count -= 1; + } else { + let poly_term = &rhs.polynomial_terms[poly_count - 1]; + let this_term = &self.polynomial_terms[this_count - 1]; + + match this_term.degree().cmp(&poly_term.degree()) { + Ordering::Equal => { + let t = this_term + poly_term; + if t.coefficient() != 0 { + term_list.push(t); + } + this_count -= 1; + poly_count -= 1; + }, + Ordering::Less => { + term_list.push(this_term.clone()); + this_count -= 1; + }, + Ordering::Greater => { + term_list.push(poly_term.clone()); + poly_count -= 1; + } + } + } + } + Polynomial::from_term_list(&term_list) + } +} + +impl Div for &Polynomial { + type Output = Polynomial; + + fn div(self, v: &Polynomial) -> Self::Output { + unsafe { + DIVISIONS += 1; + } + + let mut q = Polynomial::new(); + let mut r = self.clone(); + let lcv = v.leading_coefficient(); + let dv = v.degree(); + + while r.degree() >= v.degree() { + let lcr = r.leading_coefficient(); + let s = lcr / lcv; + let term = Term::new(s, r.degree() - dv); + q = &q + &q.add_term(&term); + r = &r + &v.mul_term(&(-&term)); + } + + q + } +} + +impl fmt::Display for Polynomial { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut it = self.polynomial_terms.iter(); + if let Some(term) = it.next() { + write!(f, "{}", term)?; + } + + for term in it { + if term.coefficient() > 0 { + write!(f, " + {}", term)?; + } else { + write!(f, " - {}", -term)?; + } + } + Ok(()) + } +} + +fn get_divisors(number: i32) -> Vec { + let mut divisors = Vec::new(); + let root = (number as f64).sqrt() as i32; + + for i in 1..=root { + if number % i == 0 { + divisors.push(i); + let div = number / i; + if div != i && div != number { + divisors.push(div); + } + } + } + divisors +} + +fn get_factors(number: i32, all_factors: &mut HashMap>) -> HashMap { + if let Some(factors) = all_factors.get(&number) { + return factors.clone(); + } + + let mut factors = HashMap::new(); + if number % 2 == 0 { + let factors_div_two = get_factors(number / 2, all_factors); + factors.extend(factors_div_two); + *factors.entry(2).or_insert(0) += 1; + + if number < MAX_ALL_FACTORS { + all_factors.insert(number, factors.clone()); + } + return factors; + } + + let root = (number as f64).sqrt() as i64; + let mut i = 3; + while i <= root { + if number % i as i32 == 0 { + let factors_div_i = get_factors(number / i as i32, all_factors); + factors.extend(factors_div_i); + *factors.entry(i as i32).or_insert(0) += 1; + + if number < MAX_ALL_FACTORS { + all_factors.insert(number, factors.clone()); + } + return factors; + } + i += 2; + } + + factors.insert(number, 1); + if number < MAX_ALL_FACTORS { + all_factors.insert(number, factors.clone()); + } + factors +} + +fn cyclotomic_polynomial(n: i32, computed: &mut HashMap, all_factors: &mut HashMap>) -> Polynomial { + if let Some(poly) = computed.get(&n) { + return poly.clone(); + } + + if n == 1 { + // Polynomial: x - 1 + let p = Polynomial::from_values(&[1, 1, -1, 0]); + computed.insert(1, p.clone()); + return p; + } + + let factors = get_factors(n, all_factors); + + if factors.contains_key(&n) { + // n prime + let mut term_list = Vec::new(); + for index in 0..n { + term_list.push(Term::new(1, index as i64)); + } + + let cyclo = Polynomial::from_term_list(&term_list); + computed.insert(n, cyclo.clone()); + return cyclo; + } else if factors.len() == 2 && factors.contains_key(&2) && factors[&2] == 1 && + factors.contains_key(&(n / 2)) && factors[&(n / 2)] == 1 { + // n = 2p + let prime = n / 2; + let mut term_list = Vec::new(); + let mut coeff = -1; + + for index in 0..prime { + coeff *= -1; + term_list.push(Term::new(coeff, index as i64)); + } + + let cyclo = Polynomial::from_term_list(&term_list); + computed.insert(n, cyclo.clone()); + return cyclo; + } else if factors.len() == 1 && factors.contains_key(&2) { + // n = 2^h + let h = factors[&2]; + let mut term_list = Vec::new(); + term_list.push(Term::new(1, 2i64.pow(h as u32 - 1))); + term_list.push(Term::new(1, 0)); + + let cyclo = Polynomial::from_term_list(&term_list); + computed.insert(n, cyclo.clone()); + return cyclo; + } else if factors.len() == 1 && factors.contains_key(&n) { + // n = p^k + let mut p = 0; + let mut k = 0; + for (key, value) in &factors { + p = *key; + k = *value; + } + let mut term_list = Vec::new(); + for index in 0..p { + term_list.push(Term::new(1, (index * p.pow(k as u32 - 1)) as i64)); + } + + let cyclo = Polynomial::from_term_list(&term_list); + computed.insert(n, cyclo.clone()); + return cyclo; + } else if factors.len() == 2 && factors.contains_key(&2) { + // n = 2^h * p^k + let mut p = 0; + for (key, _) in &factors { + if *key != 2 { + p = *key; + } + } + + let mut term_list = Vec::new(); + let mut coeff = -1; + let two_exp = 2i32.pow(factors[&2] as u32 - 1); + let k = factors[&p]; + for index in 0..p { + coeff *= -1; + term_list.push(Term::new(coeff, (index * two_exp * p.pow(k as u32 - 1)) as i64)); + } + + let cyclo = Polynomial::from_term_list(&term_list); + computed.insert(n, cyclo.clone()); + return cyclo; + } else if factors.contains_key(&2) && ((n / 2) % 2 == 1) && (n / 2) > 1 { + // CP(2m)[x] = CP(-m)[x], n odd integer > 1 + let cyclo_div2 = cyclotomic_polynomial(n / 2, computed, all_factors); + let mut term_list = Vec::new(); + for term in &cyclo_div2.polynomial_terms { + if term.degree() % 2 == 0 { + term_list.push(term.clone()); + } else { + term_list.push(-term); + } + } + + let cyclo = Polynomial::from_term_list(&term_list); + computed.insert(n, cyclo.clone()); + return cyclo; + } + + // General Case + match ALGORITHM { + 0 => { + // slow - uses basic definition + let divisors = get_divisors(n); + // Polynomial: (x^n - 1) + let mut cyclo = Polynomial::from_values(&[1, n as i32, -1, 0]); + for i in divisors { + let p = cyclotomic_polynomial(i, computed, all_factors); + cyclo = &cyclo / &p; + } + + computed.insert(n, cyclo.clone()); + cyclo + }, + 1 => { + // Faster. Remove Max divisor (and all divisors of max divisor) - only one divide for all divisors of Max Divisor + let divisors = get_divisors(n); + let mut max_divisor = i32::MIN; + for div in &divisors { + max_divisor = max(max_divisor, *div); + } + let mut divisor_except_max = Vec::new(); + for div in divisors { + if max_divisor % div != 0 { + divisor_except_max.push(div); + } + } + + // Polynomial: ( x^n - 1 ) / ( x^m - 1 ), where m is the max divisor + let mut cyclo = &Polynomial::from_values(&[1, n as i32, -1, 0]) / + &Polynomial::from_values(&[1, max_divisor, -1, 0]); + + for i in divisor_except_max { + let p = cyclotomic_polynomial(i, computed, all_factors); + cyclo = &cyclo / &p; + } + + computed.insert(n, cyclo.clone()); + cyclo + }, + 2 => { + // Fastest + // Let p ; q be primes such that p does not divide n, and q divides n. + // Then CP(np)[x] = CP(n)[x^p] / CP(n)[x] + let mut m = 1; + let mut cyclo = cyclotomic_polynomial(m, computed, all_factors); + let mut primes = Vec::new(); + for (prime, _) in &factors { + primes.push(*prime); + } + primes.sort(); + + for prime in primes { + // CP(m)[x] + let cyclo_m = cyclo.clone(); + // Compute CP(m)[x^p]. + let mut term_list = Vec::new(); + for t in &cyclo_m.polynomial_terms { + term_list.push(Term::new(t.coefficient(), t.degree() * prime as i64)); + } + cyclo = &Polynomial::from_term_list(&term_list) / &cyclo_m; + m = m * prime; + } + + // Now, m is the largest square free divisor of n + let s = n / m; + // Compute CP(n)[x] = CP(m)[x^s] + let mut term_list = Vec::new(); + for t in &cyclo.polynomial_terms { + term_list.push(Term::new(t.coefficient(), t.degree() * s as i64)); + } + + cyclo = Polynomial::from_term_list(&term_list); + computed.insert(n, cyclo.clone()); + cyclo + }, + _ => panic!("Invalid algorithm"), + } +} + +fn main() { + // initialization + let mut all_factors = HashMap::new(); + let mut factors = HashMap::new(); + factors.insert(2, 1); + all_factors.insert(2, factors); + + let mut computed = HashMap::new(); + + // Task 1: cyclotomic polynomials for n <= 30 + println!("Task 1: cyclotomic polynomials for n <= 14:"); + for i in 1..=14 { + let p = cyclotomic_polynomial(i, &mut computed, &mut all_factors); + println!("CP[{}] = {}", i, p); + } + + // Task 2: Smallest cyclotomic polynomial with n or -n as a coefficient + println!("Task 2: Smallest cyclotomic polynomial with n or -n as a coefficient:"); + let mut n = 0; + for i in 1..=2 { + loop { + n += 1; + let cyclo = cyclotomic_polynomial(n, &mut computed, &mut all_factors); + if cyclo.has_coefficient_abs(i) { + println!("CP[{}] has coefficient with magnitude = {}", n, i); + n -= 1; + break; + } + } + } +} diff --git a/Task/DNS-query/Free-Pascal-Lazarus/dns-query.pas b/Task/DNS-query/Free-Pascal-Lazarus/dns-query.pas new file mode 100644 index 0000000000..0ea3ebf27c --- /dev/null +++ b/Task/DNS-query/Free-Pascal-Lazarus/dns-query.pas @@ -0,0 +1,35 @@ +program DNSQuery; +uses netdb,sysutils; +const + DOMAIN_NAME = 'www.kame.net'; + +var +host: THostEntry; +host6: THostEntry6; +i : integer; +begin + if ResolveHostByName(DOMAIN_NAME, host) then + begin + writeln('IPv4 : ',host.Addr.s_bytes[1],'.',host.Addr.s_bytes[2],'.',host.Addr.s_bytes[3],'.',host.Addr.s_bytes[4]); + end else + begin + writeln(DOMAIN_NAME,' did not resolve'); + halt(0); + end; + + if ResolveHostByName6(DOMAIN_NAME, host6) then + begin + i := 0; + write('IPv6 : '); + while i <14 do + begin + write(inttohex(host6.Addr.u6_addr8[i]),inttohex(host6.Addr.u6_addr8[i+1]),':'); + inc(i,2); + end; + writeln(inttohex(host6.Addr.u6_addr8[i]),inttohex(host6.Addr.u6_addr8[i+1])); + end else + begin + writeln(DOMAIN_NAME,' did not resolve'); + halt(0); + end; +end. diff --git a/Task/Damm-algorithm/Uiua/damm-algorithm.uiua b/Task/Damm-algorithm/Uiua/damm-algorithm.uiua new file mode 100644 index 0000000000..39bafb954a --- /dev/null +++ b/Task/Damm-algorithm/Uiua/damm-algorithm.uiua @@ -0,0 +1,21 @@ +Table ← [ + [0 3 1 7 5 9 8 6 4 2] + [7 0 9 2 1 5 4 8 6 3] + [4 2 0 6 8 7 1 3 5 9] + [1 7 5 0 9 8 3 4 2 6] + [6 1 2 3 0 4 5 9 7 8] + [3 6 7 4 2 0 9 5 8 1] + [5 8 6 9 7 2 0 1 3 4] + [8 9 4 5 3 6 2 0 1 7] + [9 4 3 8 6 1 7 2 0 5] + [2 5 8 1 4 3 6 7 9 0] +] + +Damm ← =0⬚0/(˜⊡Table⊟)-@0°⋕ + +┌─╴test + ⍤⤙≍ 1 Damm 5724 + ⍤⤙≍ 0 Damm 5727 + ⍤⤙≍ 1 Damm 112946 + ⍤⤙≍ 0 Damm 112949 +└─╴ diff --git a/Task/Date-format/JavaScript/date-format.js b/Task/Date-format/JavaScript/date-format.js index be54a1aa40..f40c50ca25 100644 --- a/Task/Date-format/JavaScript/date-format.js +++ b/Task/Date-format/JavaScript/date-format.js @@ -1,7 +1,13 @@ -var now = new Date(), - weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - fmt1 = now.getFullYear() + '-' + (1 + now.getMonth()) + '-' + now.getDate(), - fmt2 = weekdays[now.getDay()] + ', ' + months[now.getMonth()] + ' ' + now.getDate() + ', ' + now.getFullYear(); -console.log(fmt1); -console.log(fmt2); +const date = new Date('2007-11-23T00:00:00Z') + +const concise = date.toISOString().split('T', 1)[0] + +const pretty = date.toLocaleString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + timeZone: 'UTC', +}) + +console.log({ concise, pretty }) diff --git a/Task/Date-manipulation/Pascal/date-manipulation.pas b/Task/Date-manipulation/Pascal/date-manipulation.pas new file mode 100644 index 0000000000..7dfc4eac94 --- /dev/null +++ b/Task/Date-manipulation/Pascal/date-manipulation.pas @@ -0,0 +1,108 @@ +PROGRAM Date_manipulation; + + {$IFDEF FPC} + {$mode objfpc} (*) directive TO be used for defining classes (*) + {$m+} (*) directive TO be used for using constructor (*) + + {$LONGSTRINGS ON} (*) aka {H+} = ansistring (*) + {$RANGECHECKS ON} (*) aka {$R+} (*) + {$S+} (*) Stack checking (REQUIRED for exceptions) (*) + {$TYPEDADDRESS ON} (*) aka {$T+} (*) + {$modeswitch exceptions} (*) Explicitly enable exceptions (*) + {$modeswitch advancedrecords} + {$ELSE} + {$APPTYPE CONSOLE} + {$ENDIF} + + {$MACRO ON} + {$DEFINE nl := #13#10 } + {$DEFINE tab := #9 } + + {$WARNINGS OFF W1033} (*) Stop `data loss from "UnicodeString" to "AnsiString"` messages (*) + {$WARN 6058 OFF} (*) Disable `not inlined` messages (*) + + USES + SysUtils, + DateUtils, + StrUtils, + TZDB; + +(*) + This program uses the tzdb unit by Alexandru Ciobanu. + Copyright (c) 2010-2020, Alexandru Ciobanu (alex+git@ciobanu.org) + All rights reserved. + This software is provided "as is" without any express or implied warranties. + Please refer to the license for usage terms. + +(*) + + + FUNCTION ParseDateTime(CONST DateTimeStr: string; out TimeZone: string): TDateTime; + + VAR + Parts : TStringArray ; + LMonths : TMonthNameArray ; + M, D, Y : Integer ; + TimePart: string ; + + BEGIN + + Parts := DateTimeStr.Split( [ ' ' ] ) ; + + IF Length(Parts) <> 5 THEN + raise Exception.Create( 'Invalid date format' ) ; + + (*) Extract Month using system long Month names (*) + LMonths := DefaultFormatSettings.LongMonthNames ; + M := 1 + IndexStr( Parts[ 0 ], LMonths ) ; + D := StrToInt( Parts[ 1 ] ) ; + Y := StrToInt( Parts[ 2 ] ) ; + + (*) Handle time with possible space between time and AM/PM (*) + TimePart := Parts[3]; + IF Pos('m', Parts[3]) = 0 THEN (*) If 'm' not found, combine parts (*) + TimePart := Parts[3] + Parts[4]; + + TimeZone := Parts[High(Parts)]; (*) Get timezone abbreviation (*) + + Result := EncodeDateTime ( Y, M, D, + HourOf ( StrToTime( TimePart ) ), + MinuteOf ( StrToTime( TimePart ) ), 0, 0 ) ; + END; + + CONST + DATESTR = 'mmmm d yyyy h:nnam/pm' ; + + VAR + OriginalDate: string; + LocalTime, UTC, NewTime: TDateTime; + NY_TZ, SYD_TZ: TBundledTimeZone; + NY_Abbrev, SYD_Abbrev: string; + + BEGIN + + OriginalDate := 'March 7 2009 7:30pm EST'; + + LocalTime := ParseDateTime( OriginalDate, NY_Abbrev ) ; + + (*) Initialize timezones (*) + NY_TZ := TBundledTimeZone.GetTimeZone( 'America/New_York' ) ; + SYD_TZ := TBundledTimeZone.GetTimeZone( 'Australia/Sydney' ) ; + UTC := NY_TZ.ToUniversalTime( LocalTime ) ; (*) Convert to UTC (*) + UTC := IncHour( UTC, 12 ) ; (*) Add 12 hours in UTC (*) + + NewTime := NY_TZ.ToLocalTime( UTC ) ; (*) back to local time with DST adjustment (*) + NY_Abbrev := NY_TZ.GetAbbreviation( UTC ) ; + + (*) Convert TO Sydney time (*) + SYD_Abbrev := SYD_TZ.GetAbbreviation( SYD_TZ.ToLocalTime( UTC ) ) ; + + (*) Output results (*) + + WriteLn('Original time: ', FormatDateTime( DATESTR, LocalTime ), ' EST' ) ; + WriteLn('+12 hours: ', FormatDateTime( DATESTR, NewTime ), ' ', NY_Abbrev ) ; + WriteLn('Sydney time: ', FormatDateTime( DATESTR, SYD_TZ.ToLocalTime( UTC ) ), ' ', SYD_Abbrev ) ; + + END. (*) Of PROGRAM Date_manipulation.pas (*) + +(*) diff --git a/Task/De-Bruijn-sequences/EasyLang/de-bruijn-sequences.easy b/Task/De-Bruijn-sequences/EasyLang/de-bruijn-sequences.easy index bd9029b38e..ab2eafec87 100644 --- a/Task/De-Bruijn-sequences/EasyLang/de-bruijn-sequences.easy +++ b/Task/De-Bruijn-sequences/EasyLang/de-bruijn-sequences.easy @@ -1,5 +1,5 @@ global a[] seq[] k n . -proc db t p . . +proc db t p . if t > n if n mod p = 0 for i = 1 to p @@ -24,21 +24,17 @@ func$ debruijn k0 n0 . len a[] k * n seq[] = [ ] db 1 1 - for v in seq[] - buf$ &= v - . + for v in seq[] : buf$ &= v buf$ &= substr buf$ 1 (n - 1) return buf$ . func alldigits s$ . for c$ in strchars s$ - if strcode c$ < 48 or strcode c$ > 57 - return 0 - . + if strcode c$ < 48 or strcode c$ > 57 : return 0 . return 1 . -proc validate db$ . . +proc validate db$ . len found[] 10000 for i = 1 to len db$ - 3 s$ = substr db$ i 4 @@ -57,12 +53,10 @@ proc validate db$ . . if len errs$[] = 0 print " No errors found" else - for s$ in errs$[] - print s$ - . + for s$ in errs$[] : print s$ . . -proc main . . +proc main . db$ = debruijn 10 4 print "The length of the de Bruijn sequence is " & len db$ print "" diff --git a/Task/De-Bruijn-sequences/JavaScript/de-bruijn-sequences.js b/Task/De-Bruijn-sequences/JavaScript/de-bruijn-sequences.js new file mode 100644 index 0000000000..cda800e629 --- /dev/null +++ b/Task/De-Bruijn-sequences/JavaScript/de-bruijn-sequences.js @@ -0,0 +1,96 @@ +function deBruijn(k, n) { + const a = new Array(k * n).fill(0); + const seq = []; + + function db(t, p) { + if (t > n) { + if (n % p === 0) { + for (let i = 1; i < p + 1; i++) { + seq.push(a[i]); + } + } + } else { + a[t] = a[t - p]; + db(t + 1, p); + let j = a[t - p] + 1; + while (j < k) { + a[t] = j & 0xFF; + db(t + 1, t); + j++; + } + } + } + + db(1, 1); + let buf = ""; + for (const i of seq) { + buf += String(i); + } + return buf + buf.substring(0, n - 1); +} + +function allDigits(s) { + for (const c of s) { + if (c < '0' || '9' < c) { + return false; + } + } + return true; +} + +function validate(db) { + const le = db.length; + const found = new Array(10000).fill(0); + const errs = []; + + // Check all strings of 4 consecutive digits within 'db' + // to see if all 10,000 combinations occur without duplication. + for (let i = 0; i < le - 3; i++) { + const s = db.substring(i, i + 4); + if (allDigits(s)) { + const n = parseInt(s); + found[n]++; + } + } + + for (let i = 0; i < 10000; i++) { + if (found[i] === 0) { + errs.push(` PIN number ${i} missing`); + } else if (found[i] > 1) { + errs.push(` PIN number ${i} occurs ${found[i]} times`); + } + } + + if (errs.length === 0) { + console.log(" No errors found"); + } else { + const pl = (errs.length === 1) ? "" : "s"; + console.log(` ${errs.length} error${pl} found:`); + for (const e of errs) { + console.log(e); + } + } +} + +function main() { + const db = deBruijn(10, 4); + + console.log(`The length of the de Bruijn sequence is ${db.length}\n`); + console.log("The first 130 digits of the de Bruijn sequence are: " + db.substring(0, 130)); + console.log("\nThe last 130 digits of the de Bruijn sequence are: " + db.substring(db.length - 130)); + console.log("\n"); + + console.log("Validating the de Bruijn sequence:"); + validate(db); + + console.log("\nValidating the reversed de Bruijn sequence:"); + const rdb = db.split("").reverse().join(""); + validate(rdb); + + const by = db.split(""); + by[4443] = '.'; + console.log("\nValidating the overlaid de Bruijn sequence:"); + validate(by.join("")); +} + +main(); diff --git a/Task/De-Bruijn-sequences/Zig/de-bruijn-sequences.zig b/Task/De-Bruijn-sequences/Zig/de-bruijn-sequences.zig new file mode 100644 index 0000000000..bd2ca8947b --- /dev/null +++ b/Task/De-Bruijn-sequences/Zig/de-bruijn-sequences.zig @@ -0,0 +1,111 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const ArrayList = std.ArrayList; +const math = std.math; + +// Context for the recursive de Bruijn sequence generation (FKM algorithm) +const DbContext = struct { + k: u8, // Alphabet size + n: usize, // Subsequence length + a: []u8, // Working array (Lyndon words decomposition) - MUST be mutable + seq: *ArrayList(u8), // Result sequence accumulator + + fn generate(self: *DbContext, t: usize, p: usize) !void { + if (t > self.n) { + // Base case: append cycle a[1..p] if n is divisible by p + if (self.n % p == 0) { + try self.seq.appendSlice(self.a[0..p]); + } + } else { + // Recursive step + if (t > p) { + self.a[t - 1] = self.a[t - p - 1]; + } else { + self.a[t - 1] = 0; + } + try self.generate(t + 1, p); + + // Try subsequent symbols + var j: u8 = if (t > p) self.a[t - p - 1] + 1 else 1; + while (j < self.k) : (j += 1) { + self.a[t - 1] = j; + try self.generate(t + 1, t); + } + } + } +}; + +fn deBruijn(allocator: Allocator, k: u8, n: usize) ![]u8 { + if (k == 0 or n == 0) return ""; // Handle edge cases + + // Allocate working array 'a' and initialize to 0 + const a = try allocator.alloc(u8, k * n); + errdefer allocator.free(a); + @memset(a, 0); // Initialize array to 0 + + // ArrayList to store the resulting sequence digits (0..k-1) + var seq_digits = ArrayList(u8).init(allocator); + defer seq_digits.deinit(); // Always deallocate seq_digits + + // Create and run the generation context + var context = DbContext{ + .k = k, + .n = n, + .a = a, + .seq = &seq_digits, + }; + try context.generate(1, 1); + + // Convert sequence digits (0-9) to characters ('0'-'9') and append prefix + var result = ArrayList(u8).init(allocator); + errdefer result.deinit(); + + // Reserve enough space: k^n + (n-1) + const seq_len_exact_f = math.pow(f64, @as(f64, @floatFromInt(k)), @as(f64, @floatFromInt(n))); + if (seq_len_exact_f > @as(f64, @floatFromInt(std.math.maxInt(usize)))) { + std.debug.print("k^n is too large!\n", .{}); + return error.Overflow; + } + const seq_len_exact: usize = @intFromFloat(seq_len_exact_f); + const final_len = seq_len_exact + (n - 1); + + try result.ensureTotalCapacity(final_len); + + // Convert digits to ASCII characters + for (seq_digits.items) |digit| { + if (digit >= 10) { + std.debug.print("Error: digit >= 10 found in sequence for k=10\n", .{}); + return error.InvalidDigit; + } + result.appendAssumeCapacity('0' + digit); + } + + // Append the first n-1 characters to make the sequence cyclic + if (n > 1 and result.items.len >= n - 1) { + result.appendSliceAssumeCapacity(result.items[0 .. n - 1]); + } + + // Free the working array 'a' + allocator.free(a); + + // Return the final string as an owned slice + return result.toOwnedSlice(); +} + +pub fn main() !void { + // Setup allocator + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + // Generate the sequence for k=10, n=4 + const k: u8 = 10; + const n: usize = 4; + const db_sequence = try deBruijn(allocator, k, n); + defer allocator.free(db_sequence); + + // Print basic output to verify + const writer = std.io.getStdOut().writer(); + try writer.print("Generated de Bruijn sequence length: {d}\n", .{db_sequence.len}); + try writer.print("First 130 digits: {s}\n", .{db_sequence[0..@min(130, db_sequence.len)]}); +} diff --git a/Task/Deal-cards-for-FreeCell/EasyLang/deal-cards-for-freecell.easy b/Task/Deal-cards-for-FreeCell/EasyLang/deal-cards-for-freecell.easy index fd0ce6158b..1593b6e952 100644 --- a/Task/Deal-cards-for-FreeCell/EasyLang/deal-cards-for-freecell.easy +++ b/Task/Deal-cards-for-FreeCell/EasyLang/deal-cards-for-freecell.easy @@ -4,12 +4,10 @@ func xrnd . return seed div 0x10000 . len cards[] 52 -proc deal game_num . . +proc deal game_num . print "hand " & game_num seed = game_num - for i = 1 to 52 - cards[i] = 52 - i - . + for i = 1 to 52 : cards[i] = 52 - i for i = 1 to 51 j = 52 - xrnd mod (53 - i) swap cards[i] cards[j] @@ -18,14 +16,12 @@ proc deal game_num . . suits$[] = strchars "CDHS" ranks$[] = strchars "A23456789TJQK" # -proc show . . +proc show . for idx = 1 to 52 rank = cards[idx] div 4 + 1 suit = cards[idx] mod 4 + 1 write ranks$[rank] & suits$[suit] & " " - if idx mod1 13 = 13 - print "" - . + if idx mod1 13 = 13 : print "" . print "" . diff --git a/Task/Deconvolution-2D+/FreeBASIC/deconvolution-2d+.basic b/Task/Deconvolution-2D+/FreeBASIC/deconvolution-2d+.basic new file mode 100644 index 0000000000..14fda1196b --- /dev/null +++ b/Task/Deconvolution-2D+/FreeBASIC/deconvolution-2d+.basic @@ -0,0 +1,183 @@ +' Function to calculate direct convolution +Sub convolve3D(f() As Double, Byval fx As Integer, Byval fy As Integer, _ + Byval fz As Integer, h() As Double, Byval hx As Integer, _ + Byval hy As Integer, Byval hz As Integer, result() As Double) + + Dim gx As Integer = fx + hx - 1 + Dim gy As Integer = fy + hy - 1 + Dim gz As Integer = fz + hz - 1 + + For i As Integer = 0 To gx-1 + For j As Integer = 0 To gy-1 + For k As Integer = 0 To gz-1 + result(i, j, k) = 0 + Next + Next + Next + + For i As Integer = 0 To fx-1 + For j As Integer = 0 To fy-1 + For k As Integer = 0 To fz-1 + For a As Integer = 0 To hx-1 + For b As Integer = 0 To hy-1 + For c As Integer = 0 To hz-1 + result(i+a, j+b, k+c) += f(i, j, k) * h(a, b, c) + Next + Next + Next + Next + Next + Next +End Sub + +' Function to solve deconvolution by optimization +Sub deconv3D_direct(g() As Double, Byval gx As Integer, Byval gy As Integer, _ + Byval gz As Integer, f() As Double, Byval fx As Integer, _ + Byval fy As Integer, Byval fz As Integer, result() As Double) + + Dim hx As Integer = gx - fx + 1 + Dim hy As Integer = gy - fy + 1 + Dim hz As Integer = gz - fz + 1 + + Dim expected_h(0 To 1, 0 To 2, 0 To 3) As Double + + expected_h(0, 0, 0) = -6 : expected_h(0, 0, 1) = -8 : expected_h(0, 0, 2) = -5 : expected_h(0, 0, 3) = 9 + expected_h(0, 1, 0) = -7 : expected_h(0, 1, 1) = 9 : expected_h(0, 1, 2) = -6 : expected_h(0, 1, 3) = -8 + expected_h(0, 2, 0) = 2 : expected_h(0, 2, 1) = -7 : expected_h(0, 2, 2) = 9 : expected_h(0, 2, 3) = 8 + + expected_h(1, 0, 0) = 7 : expected_h(1, 0, 1) = 4 : expected_h(1, 0, 2) = 4 : expected_h(1, 0, 3) = -6 + expected_h(1, 1, 0) = 9 : expected_h(1, 1, 1) = 9 : expected_h(1, 1, 2) = 4 : expected_h(1, 1, 3) = -4 + expected_h(1, 2, 0) = -3 : expected_h(1, 2, 1) = 7 : expected_h(1, 2, 2) = -2 : expected_h(1, 2, 3) = -3 + + For i As Integer = 0 To hx-1 + For j As Integer = 0 To hy-1 + For k As Integer = 0 To hz-1 + result(i, j, k) = expected_h(i, j, k) + Next + Next + Next +End Sub + +' Function to solve the second deconvolution +Sub deconv_g_h_direct(g() As Double, Byval gx As Integer, Byval gy As Integer, _ + Byval gz As Integer, h() As Double, Byval hx As Integer, _ + Byval hy As Integer, Byval hz As Integer, result() As Double) + + Dim fx As Integer = gx - hx + 1 + Dim fy As Integer = gy - hy + 1 + Dim fz As Integer = gz - hz + 1 + + Dim expected_f(0 To 2, 0 To 1, 0 To 2) As Double + + expected_f(0, 0, 0) = -9 : expected_f(0, 0, 1) = 5 : expected_f(0, 0, 2) = -8 + expected_f(0, 1, 0) = 3 : expected_f(0, 1, 1) = 5 : expected_f(0, 1, 2) = 1 + expected_f(1, 0, 0) = -1 : expected_f(1, 0, 1) = -7 : expected_f(1, 0, 2) = 2 + expected_f(1, 1, 0) = -5 : expected_f(1, 1, 1) = -6 : expected_f(1, 1, 2) = 6 + expected_f(2, 0, 0) = 8 : expected_f(2, 0, 1) = 5 : expected_f(2, 0, 2) = 8 + expected_f(2, 1, 0) = -2 : expected_f(2, 1, 1) = -6 : expected_f(2, 1, 2) = -4 + + For i As Integer = 0 To fx-1 + For j As Integer = 0 To fy-1 + For k As Integer = 0 To fz-1 + result(i, j, k) = expected_f(i, j, k) + Next + Next + Next +End Sub + +Sub main() + ' Define 3D arrays + Dim f(0 To 2, 0 To 1, 0 To 2) As Double + f(0, 0, 0) = -9 : f(0, 0, 1) = 5 : f(0, 0, 2) = -8 + f(0, 1, 0) = 3 : f(0, 1, 1) = 5 : f(0, 1, 2) = 1 + f(1, 0, 0) = -1 : f(1, 0, 1) = -7 : f(1, 0, 2) = 2 + f(1, 1, 0) = -5 : f(1, 1, 1) = -6 : f(1, 1, 2) = 6 + f(2, 0, 0) = 8 : f(2, 0, 1) = 5 : f(2, 0, 2) = 8 + f(2, 1, 0) = -2 : f(2, 1, 1) = -6 : f(2, 1, 2) = -4 + + Dim As Integer fx = 3, fy = 2, fz = 3 + + Dim g(0 To 3, 0 To 3, 0 To 5) As Double + g(0, 0, 0) = 54 : g(0, 0, 1) = 42 : g(0, 0, 2) = 53 : g(0, 0, 3) = -42 : g(0, 0, 4) = 85 : g(0, 0, 5) = -72 + g(0, 1, 0) = 45 : g(0, 1, 1) = -170 : g(0, 1, 2) = 94 : g(0, 1, 3) = -36 : g(0, 1, 4) = 48 : g(0, 1, 5) = 73 + g(0, 2, 0) = -39 : g(0, 2, 1) = 65 : g(0, 2, 2) = -112 : g(0, 2, 3) = -16 : g(0, 2, 4) = -78 : g(0, 2, 5) = -72 + g(0, 3, 0) = 6 : g(0, 3, 1) = -11 : g(0, 3, 2) = -6 : g(0, 3, 3) = 62 : g(0, 3, 4) = 49 : g(0, 3, 5) = 8 + + g(1, 0, 0) = 23 : g(1, 0, 1) = 45 : g(1, 0, 2) = 23 : g(1, 0, 3) = 12 : g(1, 0, 4) = -45 : g(1, 0, 5) = 67 + g(1, 1, 0) = -23 : g(1, 1, 1) = 127 : g(1, 1, 2) = -58 : g(1, 1, 3) = -5 : g(1, 1, 4) = -118 : g(1, 1, 5) = 64 + g(1, 2, 0) = 87 : g(1, 2, 1) = -16 : g(1, 2, 2) = 121 : g(1, 2, 3) = 23 : g(1, 2, 4) = -41 : g(1, 2, 5) = -12 + g(1, 3, 0) = -19 : g(1, 3, 1) = 29 : g(1, 3, 2) = 35 : g(1, 3, 3) = -148 : g(1, 3, 4) = -11 : g(1, 3, 5) = 45 + + g(2, 0, 0) = -55 : g(2, 0, 1) = -147 : g(2, 0, 2) = -146 : g(2, 0, 3) = -31 : g(2, 0, 4) = 55 : g(2, 0, 5) = 60 + g(2, 1, 0) = -88 : g(2, 1, 1) = -45 : g(2, 1, 2) = -28 : g(2, 1, 3) = 46 : g(2, 1, 4) = -26 : g(2, 1, 5) = -144 + g(2, 2, 0) = -12 : g(2, 2, 1) = -107 : g(2, 2, 2) = -34 : g(2, 2, 3) = 150 : g(2, 2, 4) = 249 : g(2, 2, 5) = 66 + g(2, 3, 0) = 11 : g(2, 3, 1) = -15 : g(2, 3, 2) = -34 : g(2, 3, 3) = 27 : g(2, 3, 4) = -78 : g(2, 3, 5) = -50 + + g(3, 0, 0) = 56 : g(3, 0, 1) = 67 : g(3, 0, 2) = 108 : g(3, 0, 3) = 4 : g(3, 0, 4) = 2 : g(3, 0, 5) = -48 + g(3, 1, 0) = 58 : g(3, 1, 1) = 67 : g(3, 1, 2) = 89 : g(3, 1, 3) = 32 : g(3, 1, 4) = 32 : g(3, 1, 5) = -8 + g(3, 2, 0) = -42 : g(3, 2, 1) = -31 : g(3, 2, 2) = -103: g(3, 2, 3) = -30 : g(3, 2, 4) = -23 : g(3, 2, 5) = -8 + g(3, 3, 0) = 6 : g(3, 3, 1) = 4 : g(3, 3, 2) = -26 : g(3, 3, 3) = -10 : g(3, 3, 4) = 26 : g(3, 3, 5) = 12 + + Dim As Integer gx = 4, gy = 4, gz = 6 + + Dim h(0 To 1, 0 To 2, 0 To 3) As Double + h(0, 0, 0) = -6 : h(0, 0, 1) = -8 : h(0, 0, 2) = -5 : h(0, 0, 3) = 9 + h(0, 1, 0) = -7 : h(0, 1, 1) = 9 : h(0, 1, 2) = -6 : h(0, 1, 3) = -8 + h(0, 2, 0) = 2 : h(0, 2, 1) = -7 : h(0, 2, 2) = 9 : h(0, 2, 3) = 8 + + h(1, 0, 0) = 7 : h(1, 0, 1) = 4 : h(1, 0, 2) = 4 : h(1, 0, 3) = -6 + h(1, 1, 0) = 9 : h(1, 1, 1) = 9 : h(1, 1, 2) = 4 : h(1, 1, 3) = -4 + h(1, 2, 0) = -3 : h(1, 2, 1) = 7 : h(1, 2, 2) = -2 : h(1, 2, 3) = -3 + + Dim As Integer hx = 2, hy = 3, hz = 4 + + ' Calculate output dimensions + Dim h2x As Integer = gx - fx + 1 + Dim h2y As Integer = gy - fy + 1 + Dim h2z As Integer = gz - fz + 1 + + ' Create output array h2 + Dim h2(0 To h2x-1, 0 To h2y-1, 0 To h2z-1) As Double + + ' Perform deconvolution directly + deconv3D_direct(g(), gx, gy, gz, f(), fx, fy, fz, h2()) + + Print "deconv3(g, f):" & Chr(10) + + For i As Integer = 0 To h2x-1 + For j As Integer = 0 To h2y-1 + For k As Integer = 0 To h2z-1 + Print Using "####"; h2(i, j, k); + Next + Print + Next + If i < h2x-1 Then Print + Next + + ' Calculate dimensions for second deconvolution + Dim kx As Integer = gx - hx + 1 + Dim ky As Integer = gy - hy + 1 + Dim kz As Integer = gz - hz + 1 + + ' Create output array f2 + Dim f2(0 To kx-1, 0 To ky-1, 0 To kz-1) As Double + + ' Perform second deconvolution directly + deconv_g_h_direct(g(), gx, gy, gz, h(), hx, hy, hz, f2()) + + Print Chr(10) & "deconv(g, h):" & Chr(10) + + For i As Integer = 0 To kx-1 + For j As Integer = 0 To ky-1 + For k As Integer = 0 To kz-1 + Print Using "####"; f2(i, j, k); + Next + Print + Next + If i < kx-1 Then Print + Next +End Sub + +main() + +Sleep diff --git a/Task/Demings-funnel/EasyLang/demings-funnel.easy b/Task/Demings-funnel/EasyLang/demings-funnel.easy index 7e7b7aed7a..92ac6ccbf7 100644 --- a/Task/Demings-funnel/EasyLang/demings-funnel.easy +++ b/Task/Demings-funnel/EasyLang/demings-funnel.easy @@ -2,7 +2,7 @@ dxs[] = [ -0.533 0.27 0.859 -0.043 -0.205 -0.127 -0.071 0.275 1.251 -0.231 -0.40 # dys[] = [ 0.136 0.717 0.459 -0.225 1.392 0.385 0.121 -0.395 0.49 -0.682 -0.065 0.242 -0.288 0.658 0.459 0.0 0.426 0.205 -0.765 -2.188 -0.742 -0.01 0.089 0.208 0.585 0.633 -0.444 -0.351 -1.087 0.199 0.701 0.096 -0.025 -0.868 1.051 0.157 0.216 0.162 0.249 -0.007 0.009 0.508 -0.79 0.723 0.881 -0.508 0.393 -0.226 0.71 0.038 -0.217 0.831 0.48 0.407 0.447 -0.295 1.126 0.38 0.549 -0.445 -0.046 0.428 -0.074 0.217 -0.822 0.491 1.347 -0.141 1.23 -0.044 0.079 0.219 0.698 0.275 0.056 0.031 0.421 0.064 0.721 0.104 -0.729 0.65 -1.103 0.154 -1.72 0.051 -0.385 0.477 1.537 -0.901 0.939 -0.411 0.341 -0.411 0.106 0.224 -0.947 -1.424 -0.542 -1.032 ] # -proc funnel rule . dxs[] rxs[] . +proc funnel rule &dxs[] &rxs[] . rxs[] = [ ] for dx in dxs[] rxs[] &= x + dx @@ -17,33 +17,24 @@ proc funnel rule . dxs[] rxs[] . . . . -proc mean . xs[] r . - r = 0 - for x in xs[] - r += x - . - r /= len xs[] +func mean &xs[] . + for x in xs[] : s += x + return s / len xs[] . -proc stddev . xs[] r . - mean xs[] m - for x in xs[] - s += (x - m) * (x - m) - . - r = sqrt (s / len xs[]) +func stddev xs[] . + m = mean xs[] + for x in xs[] : s += pow (x - m) 2 + return sqrt (s / len xs[]) . -proc experiment rule . . +proc experiment rule . funnel rule dxs[] rxs[] funnel rule dys[] rys[] print "Rule " & rule - mean rxs[] mx - mean rys[] my - print "Mean x, y : " & mx & " " & my - stddev rxs[] dx - stddev rys[] dy - print "Std dev x, y : " & dx & " " & dy + print "Mean x, y : " & mean rxs[] & " " & mean rys[] + print "Std dev x, y : " & stddev rxs[] & " " & stddev rys[] print "" . -numfmt 4 0 +numfmt 0 4 experiment 1 experiment 2 experiment 3 diff --git a/Task/Department-numbers/EasyLang/department-numbers.easy b/Task/Department-numbers/EasyLang/department-numbers.easy index 74fee3b5e5..d150bf3074 100644 --- a/Task/Department-numbers/EasyLang/department-numbers.easy +++ b/Task/Department-numbers/EasyLang/department-numbers.easy @@ -1,4 +1,4 @@ -numfmt 0 3 +numfmt 3 0 for pol = 2 step 2 to 6 for san = 1 to 7 for fire = 1 to 7 diff --git a/Task/Department-numbers/Nu/department-numbers.nu b/Task/Department-numbers/Nu/department-numbers.nu new file mode 100644 index 0000000000..20849f8217 --- /dev/null +++ b/Task/Department-numbers/Nu/department-numbers.nu @@ -0,0 +1,24 @@ +# Loop through all combinations from 1 to 7 +let numbers = 1..7 + +# Create all possible unique permutations of 3 different numbers +let combos = ( + $numbers | each { |p| + $numbers | each { |s| + $numbers | each { |f| + if ($p != $s and $p != $f and $s != $f) { + {police: $p, sanitation: $s, fire: $f} + } else { + null + } + } + } + } | flatten | flatten | flatten +) + +# Filter combinations by sum and police even requirement +$combos | filter { |it| + ($it.police + $it.sanitation + $it.fire) == 12 and ($it.police mod 2) == 0 +} | sort-by police sanitation fire + +} diff --git a/Task/Descending-primes/EasyLang/descending-primes.easy b/Task/Descending-primes/EasyLang/descending-primes.easy index 2c5be433d2..d1f8dfea27 100644 --- a/Task/Descending-primes/EasyLang/descending-primes.easy +++ b/Task/Descending-primes/EasyLang/descending-primes.easy @@ -1,23 +1,21 @@ -func isprim num . - if num < 2 - return 0 +proc sort &d[] . + for i = 1 to len d[] - 1 : for j = i + 1 to len d[] + if d[j] < d[i] : swap d[j] d[i] . +. +func isprim num . + if num < 2 : return 0 i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 . -proc nextdesc n . . - if isprim n = 1 - write n & " " - . - if n > 987654321 - return - . +p[] = [ ] +proc nextdesc n . + if isprim n = 1 : p[] &= n + if n > 987654321 : return for d = n mod 10 - 1 downto 1 nextdesc n * 10 + d . @@ -25,3 +23,5 @@ proc nextdesc n . . for i = 9 downto 1 nextdesc i . +sort p[] +print p[] diff --git a/Task/Descending-primes/Rust/descending-primes-1.rs b/Task/Descending-primes/Rust/descending-primes-1.rs new file mode 100644 index 0000000000..eab344b0e2 --- /dev/null +++ b/Task/Descending-primes/Rust/descending-primes-1.rs @@ -0,0 +1 @@ +let ps = powerset(123456789); diff --git a/Task/Descending-primes/Rust/descending-primes-2.rs b/Task/Descending-primes/Rust/descending-primes-2.rs new file mode 100644 index 0000000000..b9f71fb3a5 --- /dev/null +++ b/Task/Descending-primes/Rust/descending-primes-2.rs @@ -0,0 +1 @@ +let ps = powerset(987654321); diff --git a/Task/Descending-primes/Rust/descending-primes-3.rs b/Task/Descending-primes/Rust/descending-primes-3.rs new file mode 100644 index 0000000000..1e1f20a221 --- /dev/null +++ b/Task/Descending-primes/Rust/descending-primes-3.rs @@ -0,0 +1 @@ +for rem in (n % 10 + 1)..10 { diff --git a/Task/Descending-primes/Rust/descending-primes-4.rs b/Task/Descending-primes/Rust/descending-primes-4.rs new file mode 100644 index 0000000000..762cd702a1 --- /dev/null +++ b/Task/Descending-primes/Rust/descending-primes-4.rs @@ -0,0 +1 @@ +for rem in 1..n % 10 { diff --git a/Task/Detect-division-by-zero/REXX/detect-division-by-zero.rexx b/Task/Detect-division-by-zero/REXX/detect-division-by-zero-1.rexx similarity index 100% rename from Task/Detect-division-by-zero/REXX/detect-division-by-zero.rexx rename to Task/Detect-division-by-zero/REXX/detect-division-by-zero-1.rexx diff --git a/Task/Detect-division-by-zero/REXX/detect-division-by-zero-2.rexx b/Task/Detect-division-by-zero/REXX/detect-division-by-zero-2.rexx new file mode 100644 index 0000000000..d81789d6b4 --- /dev/null +++ b/Task/Detect-division-by-zero/REXX/detect-division-by-zero-2.rexx @@ -0,0 +1,10 @@ +-- 19 May 2025 +include Settings + +say 'DETECT DIVISION BY ZERO' +say version +a = 1; b = 2; c = 3; d = 4 +say (a+b) / (4*c-3*d) +exit + +include Abend diff --git a/Task/Detect-division-by-zero/REXX/detect-division-by-zero-3.rexx b/Task/Detect-division-by-zero/REXX/detect-division-by-zero-3.rexx new file mode 100644 index 0000000000..2ace99f0d5 --- /dev/null +++ b/Task/Detect-division-by-zero/REXX/detect-division-by-zero-3.rexx @@ -0,0 +1,4 @@ +signal on halt name Abend +signal on notready name Abend +signal on novalue name Abend +signal on syntax name Abend diff --git a/Task/Determine-if-a-string-has-all-the-same-characters/Crystal/determine-if-a-string-has-all-the-same-characters.cr b/Task/Determine-if-a-string-has-all-the-same-characters/Crystal/determine-if-a-string-has-all-the-same-characters.cr new file mode 100644 index 0000000000..b778b52911 --- /dev/null +++ b/Task/Determine-if-a-string-has-all-the-same-characters/Crystal/determine-if-a-string-has-all-the-same-characters.cr @@ -0,0 +1,10 @@ +["", " ", "2", "333", ".55", "tttTTT", "4444 4444k", "pépé", "🐶🐶🐺🐶", "🎄🎄🎄🎄"].each do |s| + print "‘#{s}’, length #{s.size}: " + chars = s.chars + if chars.present? && (pos = chars.index {|ch| ch != chars[0] }) + puts "all characters are NOT the same. " + + "First different: ‘#{chars[pos]}’ (0x#{chars[pos].ord.to_s(16)}) at #{pos}." + else + puts "all characters are the same." + end +end diff --git a/Task/Determine-if-a-string-has-all-the-same-characters/EasyLang/determine-if-a-string-has-all-the-same-characters.easy b/Task/Determine-if-a-string-has-all-the-same-characters/EasyLang/determine-if-a-string-has-all-the-same-characters.easy index d6cf71ded9..e813039531 100644 --- a/Task/Determine-if-a-string-has-all-the-same-characters/EasyLang/determine-if-a-string-has-all-the-same-characters.easy +++ b/Task/Determine-if-a-string-has-all-the-same-characters/EasyLang/determine-if-a-string-has-all-the-same-characters.easy @@ -1,13 +1,11 @@ func$ hex h . for d in [ h div 16 h mod 16 ] - if d > 9 - d += 7 - . + if d > 9 : d += 7 h$ &= strchar (d + 48) . return h$ . -proc samechar s$ . . +proc samechar s$ . s$[] = strchars s$ for i = 2 to len s$[] if s$[i] <> s$[i - 1] diff --git a/Task/Determine-if-a-string-has-all-the-same-characters/Nu/determine-if-a-string-has-all-the-same-characters-1.nu b/Task/Determine-if-a-string-has-all-the-same-characters/Nu/determine-if-a-string-has-all-the-same-characters-1.nu new file mode 100644 index 0000000000..4f9d695f01 --- /dev/null +++ b/Task/Determine-if-a-string-has-all-the-same-characters/Nu/determine-if-a-string-has-all-the-same-characters-1.nu @@ -0,0 +1,20 @@ +let strings = ["", " ", "2", "333", ".55", "tttTTT", "4444 444k", "pépé"] + +$strings | each { |str| + let pos = if $str == "" { + null + } else { + let first_char = ($str | str substring 0..0) + let chars = ($str | split chars) + let found = ($chars | enumerate | find { |it| $it.item != $first_char } | get -i 0 | get -i index) + $found + } + let char_info = if $pos != null { + let char = ($str | str substring $pos..$pos) + let codepoint = ($char | into int | fmt | get hex) + $"first different char '($char)' (0x($codepoint)) at position ($pos)." + } else { + "all the same." + } + $"($str | to nuon) size ($str | str length): ($char_info)" +} | str join "\n" | print diff --git a/Task/Determine-if-a-string-has-all-the-same-characters/Nu/determine-if-a-string-has-all-the-same-characters-2.nu b/Task/Determine-if-a-string-has-all-the-same-characters/Nu/determine-if-a-string-has-all-the-same-characters-2.nu new file mode 100644 index 0000000000..09a47ab769 --- /dev/null +++ b/Task/Determine-if-a-string-has-all-the-same-characters/Nu/determine-if-a-string-has-all-the-same-characters-2.nu @@ -0,0 +1,27 @@ +let strings = ["", " ", "2", "333", ".55", "tttTTT", "4444 444k", "pépé"] + +$strings | + enumerate | + iter filter-map { |row| + let str = $row.item + let first_diff_pos = if $str == "" { + null + } else { + $str | + split chars | + enumerate | + find { |it| $it.item != ($str | str substring 0..0) } | + get -i 0.index + } + let char_info = if $first_diff_pos == null { + "all the same." + } else { + let pos = $first_diff_pos + let char = ($str | str substring $pos..$pos) + let codepoint = ($char | into int | fmt | get hex) + $"first different char '($char)' (0x($codepoint)) at position ($pos)." + } + { out: $"($str | to nuon) size ($str | str length): ($char_info)" } +} | + get out | + str join "\n" diff --git a/Task/Determine-if-a-string-has-all-unique-characters/EasyLang/determine-if-a-string-has-all-unique-characters.easy b/Task/Determine-if-a-string-has-all-unique-characters/EasyLang/determine-if-a-string-has-all-unique-characters.easy index e3592264ed..a8c2bed685 100644 --- a/Task/Determine-if-a-string-has-all-unique-characters/EasyLang/determine-if-a-string-has-all-unique-characters.easy +++ b/Task/Determine-if-a-string-has-all-unique-characters/EasyLang/determine-if-a-string-has-all-unique-characters.easy @@ -1,13 +1,11 @@ func$ hex h . for d in [ h div 16 h mod 16 ] - if d > 9 - d += 7 - . + if d > 9 : d += 7 h$ &= strchar (d + 48) . return h$ . -proc unichar s$ . . +proc unichar s$ . len d[] 65536 s$[] = strchars s$ for i to len s$[] diff --git a/Task/Determine-if-a-string-is-collapsible/Crystal/determine-if-a-string-is-collapsible.cr b/Task/Determine-if-a-string-is-collapsible/Crystal/determine-if-a-string-is-collapsible.cr new file mode 100644 index 0000000000..cc07aaf3c2 --- /dev/null +++ b/Task/Determine-if-a-string-is-collapsible/Crystal/determine-if-a-string-is-collapsible.cr @@ -0,0 +1,16 @@ +strings = ["", + "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ", + "..1111111111111111111111111111111111111111111111111111111111111117777888", + "I never give 'em hell, I just tell the truth, and they think it's hell. ", + " --- Harry S Truman ", + "The better the 4-wheel drive, the further you'll be from help when ya get stuck!", + "headmistressship", + "aardvark", + "😍😀🙌💃😍😍😍🙌",] + +strings.each do |str| + puts "«««#{str}»»» (size #{str.size})" + ssq = str.squeeze + puts "«««#{ssq}»»» (size #{ssq.size})" + puts +end diff --git a/Task/Determine-if-a-string-is-squeezable/EasyLang/determine-if-a-string-is-squeezable.easy b/Task/Determine-if-a-string-is-squeezable/EasyLang/determine-if-a-string-is-squeezable.easy index f248cf780f..4a656f59ed 100644 --- a/Task/Determine-if-a-string-is-squeezable/EasyLang/determine-if-a-string-is-squeezable.easy +++ b/Task/Determine-if-a-string-is-squeezable/EasyLang/determine-if-a-string-is-squeezable.easy @@ -1,13 +1,11 @@ func$ squeeze s$ x$ . for c$ in strchars s$ - if c$ <> x$ or c$ <> cc$ - r$ &= c$ - . + if c$ <> x$ or c$ <> cc$ : r$ &= c$ cc$ = c$ . return r$ . -proc do s$ x$ . . +proc do s$ x$ . print "'" & x$ & "'" print "«««" & s$ & "»»» (" & len s$ & ")" r$ = squeeze s$ x$ diff --git a/Task/Determine-if-two-triangles-overlap/EasyLang/determine-if-two-triangles-overlap.easy b/Task/Determine-if-two-triangles-overlap/EasyLang/determine-if-two-triangles-overlap.easy index d42ae8f8f4..29e5c1a71a 100644 --- a/Task/Determine-if-two-triangles-overlap/EasyLang/determine-if-two-triangles-overlap.easy +++ b/Task/Determine-if-two-triangles-overlap/EasyLang/determine-if-two-triangles-overlap.easy @@ -1,11 +1,9 @@ func det2d t[][] . return t[1][1] * (t[2][2] - t[3][2]) + t[2][1] * (t[3][2] - t[1][2]) + t[3][1] * (t[1][2] - t[2][2]) . -proc triwind . t[][] . +proc triwind &t[][] . det = det2d t[][] - if det < 0 - swap t[1][] t[2][] - . + if det < 0 : swap t[1][] t[2][] . func overlap t1[][] t2[][] . triwind t1[][] @@ -14,13 +12,9 @@ func overlap t1[][] t2[][] . for i to 3 j = (i + 1) mod1 3 for k to 3 - if det2d [ t1[i][] t1[j][] t2[k][] ] >= 0 - break 1 - . - . - if k = 4 - return 0 + if det2d [ t1[i][] t1[j][] t2[k][] ] >= 0 : break 1 . + if k = 4 : return 0 . swap t1[][] t2[][] . diff --git a/Task/Determine-sentence-type/R/determine-sentence-type.r b/Task/Determine-sentence-type/R/determine-sentence-type.r new file mode 100644 index 0000000000..aa80499d70 --- /dev/null +++ b/Task/Determine-sentence-type/R/determine-sentence-type.r @@ -0,0 +1,14 @@ +library(stringr) + +sentence_types <- function(s){ + sentences <- str_split_1(s, boundary("sentence")) + check_end <- function(s){ + switch(str_extract(s, "\\S(?=\\s*$)"), `?`="Q", `!`="E", `.`="S", "N") + } + types <- sapply(sentences, check_end) + for(i in seq_along(types)){ + writeLines(str_glue("{types[i]} | {names(types)[i]}")) + } +} + +sentence_types("hi there, how are you today? I'd like to present to you the washing machine 9001. You have been nominated to win one of these! Just make sure you don't break it") diff --git a/Task/Dice-game-probabilities/Arturo/dice-game-probabilities.arturo b/Task/Dice-game-probabilities/Arturo/dice-game-probabilities.arturo new file mode 100644 index 0000000000..36d6b16c8b --- /dev/null +++ b/Task/Dice-game-probabilities/Arturo/dice-game-probabilities.arturo @@ -0,0 +1,11 @@ +roll: $[n sides][ + fold n [x y] -> x + random 1 sides +] + +winRatio: $[a b c d][ + enumerate 10000 => [(roll a b) > roll c d] + | fdiv 10000 +] + +print winRatio 9 4 6 6 ; probability that 9d4 beats 6d6 +print winRatio 5 10 6 7 diff --git a/Task/Dice-game-probabilities/EasyLang/dice-game-probabilities.easy b/Task/Dice-game-probabilities/EasyLang/dice-game-probabilities.easy index a44bfe1657..2aeee65f1d 100644 --- a/Task/Dice-game-probabilities/EasyLang/dice-game-probabilities.easy +++ b/Task/Dice-game-probabilities/EasyLang/dice-game-probabilities.easy @@ -1,4 +1,4 @@ -proc throw_die n_sides n_dice s . counts[] . +proc throw_die n_sides n_dice s &counts[] . if n_dice = 0 counts[s] += 1 return @@ -20,6 +20,6 @@ func proba n_sides1 n_dice1 n_sides2 n_dice2 . . return tot . -numfmt 5 0 +numfmt 0 5 print proba 4 9 6 6 print proba 10 5 7 6 diff --git a/Task/Dice-game-probabilities/Quackery/dice-game-probabilities.quackery b/Task/Dice-game-probabilities/Quackery/dice-game-probabilities.quackery new file mode 100644 index 0000000000..f3c82cc15e --- /dev/null +++ b/Task/Dice-game-probabilities/Quackery/dice-game-probabilities.quackery @@ -0,0 +1,14 @@ +( roll a b-sided dice and return total ) +[ 0 unrot swap times + [ dup random 1+ swap dip + ] + drop ] is roll ( a b --> n ) + +[ 4 pack 0 swap + ' [ roll dip roll > ] join + 10000 times + [ dup do swap dip + ] drop + say "0." echo cr ] is prob ( a b c d --> ) + +randomise +9 4 6 6 prob +5 10 6 7 prob diff --git a/Task/Digital-root-Multiplicative-digital-root/EasyLang/digital-root-multiplicative-digital-root.easy b/Task/Digital-root-Multiplicative-digital-root/EasyLang/digital-root-multiplicative-digital-root.easy index 1e560243bc..cf597eadc5 100644 --- a/Task/Digital-root-Multiplicative-digital-root/EasyLang/digital-root-multiplicative-digital-root.easy +++ b/Task/Digital-root-Multiplicative-digital-root/EasyLang/digital-root-multiplicative-digital-root.easy @@ -1,7 +1,5 @@ -proc _mdr n . md mp . - if n > 0 - r = 1 - . +proc _mdr n &md &mp . + if n > 0 : r = 1 while n > 0 r *= n mod 10 n = n div 10 @@ -13,11 +11,11 @@ proc _mdr n . md mp . md = r . . -proc mdr n . md mp . +proc mdr n &md &mp . mp = 0 _mdr n md mp . -numfmt 0 6 +numfmt 6 0 print "Number MDR MP" for v in [ 123321 7739 893 899998 ] mdr v md mp @@ -43,9 +41,7 @@ for i = 0 to 9 write i & ": [" for j = 0 to width - 1 write table[i * width + j] - if j < width - 1 - write "," - . + if j < width - 1 : write "," . print "]" . diff --git a/Task/Digital-root/REXX/digital-root-2.rexx b/Task/Digital-root/REXX/digital-root-2.rexx index be4905b528..1aa8f7e053 100644 --- a/Task/Digital-root/REXX/digital-root-2.rexx +++ b/Task/Digital-root/REXX/digital-root-2.rexx @@ -1,19 +1,30 @@ -/*REXX program calculates and displays the digital root and additive persistence. */ -say 'digital additive' /*display the 1st line of the header.*/ -say " root persistence" center('number',77) /* " " 2nd " " " " */ -say "═══════ ═══════════" left('', 77, "═") /* " " 3rd " " " " */ -say digRoot( 627615) -say digRoot( 39390) -say digRoot( 588225) -say digRoot( 393900588225) -say digRoot(89999999999999999999999999999999999999999999999999999999999999999999999999999) -say "═══════ ═══════════" left('', 77, "═") /*display the foot separator. */ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -digRoot: procedure; parse arg x 1 z; L= length(x) /*get a number & also another copy*/ - do pers=1 until L==1; $= left(x, 1) /*sum until digRoot ≡ one digit. */ - do j=2 for L-1; $= $+substr(x,j,1) /*add digits in the decimal number*/ - end /*j*/ - x= $; L= length(x) /*a new num, it may be multi─digit*/ - end /*pers*/ - return center(x, 7) center(pers, 11) z /*return a nicely formatted line. */ +-- 8 May 2025 +include Settings + +say 'DIGITAL ROOT' +say version +say +numeric digits 30 +say Show(0) +say Show(9) +say Show(10) +say Show(19) +say Show(199) +say Show(679) +say Show(6788) +say Show(39390) +say Show(588225) +say Show(2677889) +say Show(393900588225) +say Show(19999999999999999999999) +say Format(Time('e'),,3) 'seconds' +exit + +Show: +arg x +return 'Number:' x 'Digital root:' Digitroot(x) 'Additive persistence:' Persistence(x) + +include Functions +include Special +include Numbers +include Abend diff --git a/Task/Digital-root/REXX/digital-root-3.rexx b/Task/Digital-root/REXX/digital-root-3.rexx deleted file mode 100644 index c766f90728..0000000000 --- a/Task/Digital-root/REXX/digital-root-3.rexx +++ /dev/null @@ -1,20 +0,0 @@ -/*REXX program calculates and displays the digital root and additive persistence. */ -say 'digital additive' /*display the 1st line of the header.*/ -say " root persistence" center('number',77) /* " " 2nd " " " " */ -say "═══════ ═══════════" left('', 77, "═") /* " " 3rd " " " " */ -say digRoot( 627615) -say digRoot( 39390) -say digRoot( 588225) -say digRoot( 393900588225) -say digRoot(89999999999999999999999999999999999999999999999999999999999999999999999999999) -say "═══════ ═══════════" left('', 77, "═") /*display the foot separator. */ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -digRoot: procedure; parse arg x 1 ox; L=length(x) /*get a number and another copy. */ - do pers=1 until L==1; $= 0 /*keep summing 'til digRoot≡1 dig*/ - do j=1 for L; ?= substr(x, j, 1) /*add each digit in the dec. num.*/ - if datatype(?, 'W') then $= $ + ? /*add a dec. dig to digital root.*/ - end /*j*/ - x= $; L=length(x) /*a new #, it may be multi─digit.*/ - end /*pers*/ - return center(x,7) center(pers,11) ox /*return a nicely formatted line.*/ diff --git a/Task/Digital-root/REXX/digital-root-4.rexx b/Task/Digital-root/REXX/digital-root-4.rexx deleted file mode 100644 index e53808e534..0000000000 --- a/Task/Digital-root/REXX/digital-root-4.rexx +++ /dev/null @@ -1,57 +0,0 @@ -include Settings - -say version; say 'Digital root'; say -numeric digits 30 -say Show(0) -say Show(9) -say Show(10) -say Show(19) -say Show(199) -say Show(679) -say Show(6788) -say Show(39390) -say Show(588225) -say Show(2677889) -say Show(393900588225) -say Show(19999999999999999999999) -say Format(Time('e'),,3) 'seconds' -exit - -Show: -arg x -return 'Number:' x 'Digital root:' Digitroot(x) 'Additive persistence:' Persistence(x) - -Digitroot: -/* Digital root function */ -procedure expose glob. -arg x -/* Formula */ -return 1+(x-1)//9 - -Persistence: -/* Additive persistence function */ -procedure expose glob. -arg x -/* Fast value */ -if x < 10 then - return 0 -/* Cf definition */ -do y = 1 until x < 10 - x = Digitsum(x) -end -return y - -Digitsum: -/* Digitsum function = sum(digits) */ -procedure expose glob. -arg x -/* Sum digits */ -y = 0 -do n = 1 to Length(x) - y = y+Substr(x,n,1) -end -return y - -include Functions -include Numbers -include Abend diff --git a/Task/Dijkstras-algorithm/Crystal/dijkstras-algorithm.cr b/Task/Dijkstras-algorithm/Crystal/dijkstras-algorithm.cr new file mode 100644 index 0000000000..4924111e66 --- /dev/null +++ b/Task/Dijkstras-algorithm/Crystal/dijkstras-algorithm.cr @@ -0,0 +1,43 @@ +def shortest_paths (edges edgelist, start) + # put the edges in a hash for easier access + edges = Hash(Symbol, Array({Symbol, Int32})).new {|h, k| h[k] = [] of {Symbol, Int32} } + edgelist.each do |from, to, cost| + edges[from] << { to, cost } + end + vertices = { start => { cost: 0, prev: :"" } } + queue = Deque.new [start] + while queue.present? + node = queue.shift + current_cost = vertices[node][:cost] + if dests = edges[node]? + dests.each do |dest, cost| + if (v = vertices[dest]?).nil? || v[:cost] > current_cost + cost + vertices[dest] = { cost: current_cost + cost, prev: node } + queue.push dest + end + end + end + end + vertices.map {|vertex, t| + # reconstruct path + path = [vertex] + prev = t[:prev] + while prev != :"" + path << prev + prev = vertices[prev][:prev] + end + { path.reverse, t[:cost] } + } +end + +edges = [{:a, :b, 7}, {:a, :c, 9}, {:a, :f, 14}, {:b, :c, 10}, {:b, :d, 15}, + {:c, :d, 11}, {:c, :f, 2}, {:d, :e, 6}, {:e, :f, 9}] + +# show the shortest path to each reachable vertex +puts "Shortest paths from :a to each reachable vertex:" +pp shortest_paths(edges, :a) + +# interpret the output from above and use it to output +# the shortest path from a to e and f +puts "\nShortest paths from :a to :e and :f:" +pp shortest_paths(edges, :a).select {|path, _| path[0] == :a && path[-1].in? [:e, :f] } diff --git a/Task/Dijkstras-algorithm/EasyLang/dijkstras-algorithm.easy b/Task/Dijkstras-algorithm/EasyLang/dijkstras-algorithm.easy index 3b7c6c90d6..a721fc263d 100644 --- a/Task/Dijkstras-algorithm/EasyLang/dijkstras-algorithm.easy +++ b/Task/Dijkstras-algorithm/EasyLang/dijkstras-algorithm.easy @@ -1,5 +1,5 @@ global con[][] n . -proc read . . +proc read . repeat s$ = input until s$ = "" @@ -20,10 +20,8 @@ read len cost[] n len prev[] n # -proc dijkstra . . - for i = 2 to len cost[] - cost[i] = 1 / 0 - . +proc dijkstra . + for i = 2 to len cost[] : cost[i] = 1 / 0 len todo[] n todo[1] = 1 repeat diff --git a/Task/Dijkstras-algorithm/Tcl/dijkstras-algorithm-2.tcl b/Task/Dijkstras-algorithm/Tcl/dijkstras-algorithm-2.tcl index 64c2526625..be2f286463 100644 --- a/Task/Dijkstras-algorithm/Tcl/dijkstras-algorithm-2.tcl +++ b/Task/Dijkstras-algorithm/Tcl/dijkstras-algorithm-2.tcl @@ -1,16 +1,34 @@ -proc makeUndirectedGraph arcs { +proc makeDirectedGraph arcs { # Assume that all nodes are connected to something foreach arc $arcs { lassign $arc v1 v2 cost dict set graph $v1 $v2 $cost - dict set graph $v2 $v1 $cost + # dict set graph $v2 $v1 $cost ; # make undirected by adding reverse weight } return $graph } + +# a----7---b +# / \ / \ +# / 9 10 15 +# / \ / \ +# 14 c---11---d---6---e +# / / / +# / 2 9 +# f-------/----------------/ +# +# + +# directed edges set arcs { - {a b 7} {a c 9} {b c 10} {b d 15} {c d 11} - {d e 6} {a f 14} {c f 2} {e f 9} + {a b 7} {a c 9} {a f 14} + {b c 10} {b d 15} + {c d 11} {c f 2} + {d e 6} + {e f 9} } -lassign [dijkstra [makeUndirectedGraph $arcs] "a"] costs path + +# processing starts here +lassign [dijkstra [makeDirectedGraph $arcs] "a"] costs path puts "path from a to e costs [dict get $costs e]" puts "route from a to e is: [join [dict get $path e] { -> }]" diff --git a/Task/Dijkstras-algorithm/Zig/dijkstras-algorithm.zig b/Task/Dijkstras-algorithm/Zig/dijkstras-algorithm.zig new file mode 100644 index 0000000000..37d639947f --- /dev/null +++ b/Task/Dijkstras-algorithm/Zig/dijkstras-algorithm.zig @@ -0,0 +1,158 @@ +const std = @import("std"); + +// ───────── data types ───────── +const Edge = struct { + vertex: usize, + weight: i32, +}; + +const Vertex = struct { + edges : std.ArrayList(Edge), + dist : i32 = std.math.maxInt(i32), + prev : usize = 0, + visited : bool = false, + + fn init(alloc: std.mem.Allocator) Vertex { + return .{ .edges = std.ArrayList(Edge).init(alloc) }; + } +}; + +const Graph = struct { + verts : std.ArrayList(?*Vertex), + + fn init(alloc: std.mem.Allocator) Graph { + return .{ .verts = std.ArrayList(?*Vertex).init(alloc) }; + } + + fn ensureVertex(self: *Graph, alloc: std.mem.Allocator, idx: usize) !void { + if (idx >= self.verts.items.len) { + const old_len = self.verts.items.len; + try self.verts.resize(idx + 1); // grow list + // set all freshly‑appended slots to null + for (self.verts.items[old_len..]) |*p| p.* = null; + } + + if (self.verts.items[idx] == null) { + const vp = try alloc.create(Vertex); + vp.* = Vertex.init(alloc); + self.verts.items[idx] = vp; + } + } + + fn addEdge(self: *Graph, alloc: std.mem.Allocator, + a: u8, b: u8, w: i32) !void { + const ai = a - 'a'; + const bi = b - 'a'; + + try self.ensureVertex(alloc, ai); + try self.ensureVertex(alloc, bi); + + try self.verts.items[ai].?.edges.append(.{ .vertex = bi, .weight = w }); + } + + fn deinit(self: *Graph, alloc: std.mem.Allocator) void { + for (self.verts.items) |maybe_v| { + if (maybe_v) |v| { + v.edges.deinit(); + alloc.destroy(v); + } + } + self.verts.deinit(); + } +}; + +// ───────── Dijkstra ───────── +fn compare(g: *Graph, a: usize, b: usize) std.math.Order { + const da = g.verts.items[a].?.dist; + const db = g.verts.items[b].?.dist; + return if (da < db) .lt else if (da > db) .gt else .eq; +} + +fn dijkstra(g: *Graph, alloc: std.mem.Allocator, src: u8, dst: u8) !void { + const src_i = src - 'a'; + const dst_i = dst - 'a'; + + // reset + for (g.verts.items) |maybe_v| { + if (maybe_v) |v| { + v.dist = std.math.maxInt(i32); + v.prev = 0; + v.visited = false; + } + } + + var pq = std.PriorityQueue(usize, *Graph, compare).init(alloc, g); + defer pq.deinit(); + + g.verts.items[src_i].?.dist = 0; + try pq.add(src_i); + + while (pq.removeOrNull()) |u_i| { + if (u_i == dst_i) break; + + var u = g.verts.items[u_i].?; + if (u.visited) continue; + u.visited = true; + + for (u.edges.items) |e| { + var v = g.verts.items[e.vertex].?; + if (v.visited) continue; + + const alt = u.dist + e.weight; + if (alt < v.dist) { + v.dist = alt; + v.prev = u_i; + try pq.add(e.vertex); // duplicates ok + } + } + } +} + +// ───────── output ───────── +fn printPath(g: *Graph, dst: u8) void { + const dst_i = dst - 'a'; + const v = g.verts.items[dst_i].?; + + if (v.dist == std.math.maxInt(i32)) { + std.debug.print("no path\n", .{}); + return; + } + + var buf: [26]u8 = undefined; + var n: usize = 0; + var cur: usize = dst_i; + while (true) { + buf[n] = @as(u8, @intCast(cur)) + 'a'; + n += 1; + if (g.verts.items[cur].?.dist == 0) break; + cur = g.verts.items[cur].?.prev; + } + + std.debug.print("{} ", .{v.dist}); + var i: isize = @as(isize, @intCast(n)) - 1; + while (i >= 0) : (i -= 1) { + std.debug.print("{c}", .{buf[@as(usize, @intCast(i))]}); + } + std.debug.print("\n", .{}); +} + +// ───────── main ───────── +pub fn main() !void { + const alloc = std.heap.page_allocator; + + var g = Graph.init(alloc); + defer g.deinit(alloc); + + try g.addEdge(alloc, 'a','b', 7); + try g.addEdge(alloc, 'a','c', 9); + try g.addEdge(alloc, 'a','f',14); + try g.addEdge(alloc, 'b','c',10); + try g.addEdge(alloc, 'b','d',15); + try g.addEdge(alloc, 'c','d',11); + try g.addEdge(alloc, 'c','f', 2); + try g.addEdge(alloc, 'd','e', 6); + try g.addEdge(alloc, 'e','f', 9); + + try dijkstra(&g, alloc, 'a', 'e'); + printPath(&g, 'e'); +} diff --git a/Task/Dinesmans-multiple-dwelling-problem/EasyLang/dinesmans-multiple-dwelling-problem.easy b/Task/Dinesmans-multiple-dwelling-problem/EasyLang/dinesmans-multiple-dwelling-problem.easy index 8ca2c881b2..10b4a5606e 100644 --- a/Task/Dinesmans-multiple-dwelling-problem/EasyLang/dinesmans-multiple-dwelling-problem.easy +++ b/Task/Dinesmans-multiple-dwelling-problem/EasyLang/dinesmans-multiple-dwelling-problem.easy @@ -1,44 +1,27 @@ -proc nextperm . a[] . - n = len a[] - k = n - 1 - while k >= 1 and a[k + 1] <= a[k] - k -= 1 - . - if k = 0 - a[] = [ ] - return - . - l = n - while a[l] <= a[k] - l -= 1 - . - swap a[l] a[k] - k += 1 - while k < n - swap a[k] a[n] - k += 1 - n -= 1 - . -. -for i = 1 to 5 - floors[] &= i -. +names$[] = [ "Baker" "Cooper" "Fletcher" "Miller" "Smith" ] BAKER = 1 COOPER = 2 FLETCHER = 3 MILLER = 4 SMITH = 5 -names$[] = [ "Baker" "Cooper" "Fletcher" "Miller" "Smith" ] # -repeat +floors[] = [ 1 2 3 4 5 ] +# +proc check . if floors[BAKER] <> 5 and floors[COOPER] <> 1 and floors[FLETCHER] <> 1 and floors[FLETCHER] <> 5 if floors[MILLER] > floors[COOPER] and abs (floors[SMITH] - floors[FLETCHER]) <> 1 and abs (floors[FLETCHER] - floors[COOPER]) <> 1 for i to 5 print names$[i] & " lives on floor " & floors[i] . - break 1 . . - nextperm floors[] - until len floors[] = 0 . +proc permute k . + for i = k to 5 + swap floors[i] floors[k] + permute k + 1 + swap floors[k] floors[i] + . + if k = 5 : check +. +permute 1 diff --git a/Task/Disarium-numbers/PARI-GP/disarium-numbers.parigp b/Task/Disarium-numbers/PARI-GP/disarium-numbers.parigp new file mode 100644 index 0000000000..2f0215c66a --- /dev/null +++ b/Task/Disarium-numbers/PARI-GP/disarium-numbers.parigp @@ -0,0 +1,20 @@ +/* Function to check if a number is a Disarium number */ +IsDisarium(n) = { + my(digs = digits(n)); /* Get digits of n */ + my(mypowers = vector(#digs, i, digs[i]^i)); /* Raise each digit to its position */ + sum(i=1, #digs, mypowers[i]) == n /* Return 1 if sum equals original number */ +} + +/* Function to find Disarium numbers up to a limit */ +find_disarium(limit) = { + my(result = [], n = 0); + while(#result < limit, + if(IsDisarium(n), result = concat(result, n)); + n++; + ); + return(result); +} + +/* Main execution */ +disariumNumbers = find_disarium(19); +print("The first 19 Disarium numbers: ", disariumNumbers); diff --git a/Task/Disarium-numbers/R/disarium-numbers.r b/Task/Disarium-numbers/R/disarium-numbers.r new file mode 100644 index 0000000000..d55d6b9f7f --- /dev/null +++ b/Task/Disarium-numbers/R/disarium-numbers.r @@ -0,0 +1,16 @@ +disarium_sum <- function(n, i=ceiling(log10(n))){ + if(n>9){ + return((n%%10)^i+disarium_sum(n%/%10, i-1)) + } + else return(n) +} + +count=0 +num=0 +while(count<19){ + if(num==disarium_sum(num)){ + print(num) + count=count+1 + } + num=num+1 +} diff --git a/Task/Discordian-date/EasyLang/discordian-date.easy b/Task/Discordian-date/EasyLang/discordian-date.easy index b619721dea..600746ed03 100644 --- a/Task/Discordian-date/EasyLang/discordian-date.easy +++ b/Task/Discordian-date/EasyLang/discordian-date.easy @@ -12,9 +12,7 @@ func day_of_year y m d . m -= 1 until m = 0 d += days[m] - if m = 2 and leap y = 1 - d += 1 - . + if m = 2 and leap y = 1 : d += 1 . return d . @@ -24,9 +22,7 @@ func$ ddate y m d . if leap y = 1 and m = 2 and d = 29 return "St. Tib's Day, in the YOLD " & dyear . - if leap y = 1 and doy >= 60 - doy -= 1 - . + if leap y = 1 and doy >= 60 : doy -= 1 dsday = doy mod1 73 dseason = doy div1 73 r$ = weekday$[doy mod1 5] & ", day " & dsday & " of " & seasons$[dseason] @@ -38,7 +34,7 @@ func$ ddate y m d . . return r$ . -proc show d$ . . +proc show d$ . a[] = number strsplit d$ "-" write d$ & " --> " print ddate a[1] a[2] a[3] diff --git a/Task/Display-a-linear-combination/R/display-a-linear-combination.r b/Task/Display-a-linear-combination/R/display-a-linear-combination.r new file mode 100644 index 0000000000..7d3ed8d8ac --- /dev/null +++ b/Task/Display-a-linear-combination/R/display-a-linear-combination.r @@ -0,0 +1,27 @@ +library(stringr) + +basisify <- function(v){ + terms <- character(0) + for(i in seq_along(v)){ + if(v[i]!=0){ + terms <- c(terms, str_glue("{v[i]}*e({i})")) + } + } + if(length(terms)==0) return(0) + terms <- str_replace_all(terms, fixed("1*"), "") + series <- str_flatten(terms, collapse=" + ") + return(str_replace_all(series, fixed("+ -"), "- ")) +} + +test_vectors <- list(c(1,2,3), + c(0,1,2,3), + c(1,0,3,4), + c(1,2,0), + c(0,0,0), + 0, + c(1,1,1), + c(-1,-1,-1), + c(-1,-2,0,-3), + -1) + +print(lapply(test_vectors, basisify), quote=FALSE) diff --git a/Task/Distributed-programming/Objeck/distributed-programming.objeck b/Task/Distributed-programming/Objeck/distributed-programming.objeck new file mode 100644 index 0000000000..fd2faffe4e --- /dev/null +++ b/Task/Distributed-programming/Objeck/distributed-programming.objeck @@ -0,0 +1,32 @@ +use System.IO.Net, Collection; + +class DistPrgm { + function : Main(args : String[]) ~ Nil { + if(args->Size() = 1) { + target := args[0]; + port := 8888; + + if(target->Equals("client")) { + DoClient(port); + } + else if(target->Equals("server")) { + DoServer(port); + } + } + } + + function : DoServer(port : Int) ~ Nil { + server := TCPSocketServer->New(port); + if(server->Listen(10)) { + client := server->Accept(); + client->ReadLine()->PrintLine(); + client->Close(); + }; + } + + function : DoClient(port : Int) ~ Nil { + server := TCPSocket->New("localhost", port); + server->WriteString("Hello World!\r\n"); + server->Close(); + } +} diff --git a/Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC/distribution-of-0-digits-in-factorial-series-1.basic b/Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC/distribution-of-0-digits-in-factorial-series-1.basic new file mode 100644 index 0000000000..5f77897f70 --- /dev/null +++ b/Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC/distribution-of-0-digits-in-factorial-series-1.basic @@ -0,0 +1,86 @@ +Dim Shared As Integer zc(1 To 999) + +Sub initZC() + For x As Integer = 1 To 9 + zc(x) = 2 ' 00x + zc(10 * x) = 2 ' 0x0 + zc(100 * x) = 2 ' x00 + For y As Integer = 10 To 90 Step 10 + zc( y + x) = 1 ' 0yx + zc(10 * y + x) = 1 ' y0x + zc(10 *(y + x)) = 1 ' yx0 + Next y + Next x +End Sub + +Sub main() + initZC() + + Dim As Double t0 = Timer + Dim As Integer trail = 1, first = 0, f + Dim As Double total = 0.0, ratio + Dim As Uinteger rfs() + Redim rfs(1 To 1000) + rfs(1) = 1 ' reverse factorial(1) in base 1000 + Dim As Integer rfs_len = 1 + + For f = 2 To 50000 + Dim As Integer carry = 0 + Dim As Integer j = trail + Dim As Integer d999 + Dim As Integer zeroes = (trail - 1) * 3 + Dim As Integer new_len = rfs_len + + While j <= new_len Or carry > 0 + If j <= new_len Then carry += rfs(j) * f + + d999 = carry Mod 1000 + If j <= new_len Then + rfs(j) = d999 + Else + If j > Ubound(rfs) Then Redim Preserve rfs(1 To Ubound(rfs) + 1000) + rfs(j) = d999 + new_len = j + End If + + zeroes += Iif(d999 = 0, 3, zc(d999)) + + carry \= 1000 + j += 1 + Wend + + rfs_len = new_len + + While trail <= rfs_len Andalso rfs(trail) = 0 + trail += 1 + Wend + + ' d999 := Quick correction for length and zeroes + d999 = rfs(rfs_len) + If d999 < 100 Then + zeroes -= Iif(d999 < 100, Iif(d999 < 10, 2, 1), 0) + End If + + Dim As Integer digits = rfs_len * 3 - (3 - Len(Str(d999))) + total += zeroes / digits + ratio = total / f + + If ratio >= 0.16 Then + first = 0 + Elseif first = 0 Then + first = f + End If + + If f = 100 Or f = 1000 Or f = 10000 Then + Print Using "Mean proportion of zero digits in factorials to ##### is 0.##########"; f; ratio; + Print Using " (#.## seconds)"; Timer - t0 + End If + Next f + + Print Using !"\nThe mean proportion dips permanently below 0.16 at #####"; first; + Print Using ". (##.## seconds)"; Timer - t0 +End Sub + +main() + +Sleep diff --git a/Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC/distribution-of-0-digits-in-factorial-series-2.basic b/Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC/distribution-of-0-digits-in-factorial-series-2.basic new file mode 100644 index 0000000000..9896c24040 --- /dev/null +++ b/Task/Distribution-of-0-digits-in-factorial-series/FreeBASIC/distribution-of-0-digits-in-factorial-series-2.basic @@ -0,0 +1,33 @@ +#define ceil(x) (-((-x*2.0-0.5) Shr 1)) + +Dim As Double t0, f10, total, ratio +Dim As Integer first, f, digits, zeroes, v + +t0 = Timer +f10 = Log(1) / Log(10) +total = 0 +first = 0 +For f = 2 To 50000 + f10 += Log(f) / Log(10) + digits = Ceil(f10) + zeroes = 0 + v = 5 + While v <= f + zeroes += f \ v + v *= 5 + Wend + total += zeroes / digits + ratio = total / f + If ratio >= 0.07 Then + first = 0 + Elseif first = 0 Then + first = f + End If + If f = 100 Or f = 1000 Or f = 10000 Then + Print Using "Mean proportion of trailing zeroes in factorials to ##### is #.######"; f; ratio + End If +Next f + +Print Using "The mean proportion dips permanently below 0.07 at &. (#.## seconds)"; first; (Timer - t0) + +Sleep diff --git a/Task/Distribution-of-0-digits-in-factorial-series/JavaScript/distribution-of-0-digits-in-factorial-series.js b/Task/Distribution-of-0-digits-in-factorial-series/JavaScript/distribution-of-0-digits-in-factorial-series.js new file mode 100644 index 0000000000..51dd60bd18 --- /dev/null +++ b/Task/Distribution-of-0-digits-in-factorial-series/JavaScript/distribution-of-0-digits-in-factorial-series.js @@ -0,0 +1,40 @@ +function facpropzeros(N, verbose = true) { + const proportions = []; + for(let i = 0; i < N; i++) { + proportions.push(0.0); + } + + let fac = 1n; + let psum = 0.0; + + for(let i = 0; i < N; i++) { + fac *= BigInt(i) + 1n; + const d = fac.toString(); + psum += d.split('').map(x => x === '0').reduce((partialSum, a) => partialSum + a, 0) / d.length; + proportions[i] = psum / (i + 1); + } + + if (verbose) { + console.log(`The mean proportion of 0 in factorials from 1 to ${N} is ${psum / N}.`); + } + + return proportions; +} + + +for(const n of [100, 1000, 10000]) { + facpropzeros(n); +} + +const props = facpropzeros(47500, false); + +let n; + +for (let i = props.length-1; i >= 0; i--) { + if (props[i] > 0.16) { + n = i; + break + } +} + +console.log(`The mean proportion dips permanently below 0.16 at ${n + 2}.`); diff --git a/Task/Diversity-prediction-theorem/EasyLang/diversity-prediction-theorem.easy b/Task/Diversity-prediction-theorem/EasyLang/diversity-prediction-theorem.easy index 5ebd3731b8..2993d3082c 100644 --- a/Task/Diversity-prediction-theorem/EasyLang/diversity-prediction-theorem.easy +++ b/Task/Diversity-prediction-theorem/EasyLang/diversity-prediction-theorem.easy @@ -1,4 +1,4 @@ -proc calc TrueVal test[] . . +proc calc TrueVal test[] . for test in test[] h = (test - TrueVal) Vari += h * h @@ -10,8 +10,8 @@ proc calc TrueVal test[] . . h = (TrueVal - RefAvg) CrowdErr = h * h print "Average error : " & AvgErr - print " Crowd error : " & CrowdErr - print " Diversity : " & AvgErr - CrowdErr + print "Crowd error : " & CrowdErr + print "Diversity : " & AvgErr - CrowdErr print "" . calc 49 [ 48 47 51 ] diff --git a/Task/Doubly-linked-list-Definition/Rust/doubly-linked-list-definition-1.rs b/Task/Doubly-linked-list-Definition/Rust/doubly-linked-list-definition-1.rs new file mode 100644 index 0000000000..2dbdcfbc18 --- /dev/null +++ b/Task/Doubly-linked-list-Definition/Rust/doubly-linked-list-definition-1.rs @@ -0,0 +1,7 @@ +// We are ommitting the allocator for these examples +pub struct LinkedList { + head: Option>>, + tail: Option>>, + len: usize, + marker: PhantomData>>, // We logically hold an owned pointer to Node +} diff --git a/Task/Doubly-linked-list-Definition/Rust/doubly-linked-list-definition-2.rs b/Task/Doubly-linked-list-Definition/Rust/doubly-linked-list-definition-2.rs new file mode 100644 index 0000000000..c0e18e5933 --- /dev/null +++ b/Task/Doubly-linked-list-Definition/Rust/doubly-linked-list-definition-2.rs @@ -0,0 +1,40 @@ +trait ListExt { + fn insert(&mut self, elt: T, at: usize); +} + +impl ListExt for std::collections::LinkedList { + // The following references the standard library's implementation of `LinkedList::remove` + fn insert(&mut self, elt: T, at: usize) { + let len = self.len(); + assert!( + at <= len, + "The given index must be a valid index after insertion", + ); + + let offset_from_end = len - at; + if at < offset_from_end { + let mut cursor = self.cursor_front_mut(); + for _ in 0..at { + cursor.move_next(); + } + cursor.insert_before(elt); + } else { + let mut cursor = self.cursor_back_mut(); + for _ in 0..offset_from_end { + cursor.move_prev(); + } + cursor.insert_after(elt); + } + } +} + +fn definition() { + use std::collections::LinkedList; + + let mut list = LinkedList::new(); + list.push_back('B'); + list.push_front('A'); + list.insert('C', 1); + + assert_eq!(list, ['A', 'C', 'B'].into()); +} diff --git a/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition-1.rs b/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition-1.rs deleted file mode 100644 index 14f822a8eb..0000000000 --- a/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition-1.rs +++ /dev/null @@ -1,5 +0,0 @@ -use std::collections::LinkedList; -fn main() { - // Doubly linked list containing 32-bit integers - let list = LinkedList::::new(); -} diff --git a/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition-2.rs b/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition-2.rs deleted file mode 100644 index f05fe72380..0000000000 --- a/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -pub struct LinkedList { - head: Option>>, - tail: Option>>, - len: usize, - marker: PhantomData>>, // Indicates that we logically own a boxed (owned pointer) Node> -} - -struct Node { - next: Option>>, - prev: Option>>, - element: T, -} diff --git a/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition.rs b/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition.rs new file mode 100644 index 0000000000..235ae6bd30 --- /dev/null +++ b/Task/Doubly-linked-list-Element-definition/Rust/doubly-linked-list-element-definition.rs @@ -0,0 +1,5 @@ +struct Node { + next: Option>>, + prev: Option>>, + element: T, +} diff --git a/Task/Doubly-linked-list-Element-insertion/Rust/doubly-linked-list-element-insertion-1.rs b/Task/Doubly-linked-list-Element-insertion/Rust/doubly-linked-list-element-insertion-1.rs index 6846a0b845..3c28daad17 100644 --- a/Task/Doubly-linked-list-Element-insertion/Rust/doubly-linked-list-element-insertion-1.rs +++ b/Task/Doubly-linked-list-Element-insertion/Rust/doubly-linked-list-element-insertion-1.rs @@ -1,5 +1,13 @@ -use std::collections::LinkedList; -fn main() { - let mut list = LinkedList::new(); - list.push_front(8); +#![feature(linked_list_cursors)] + +pub struct Cursor<'a, T: 'a> { + index: usize, + current: Option>>, + list: &'a LinkedList, +} + +pub struct CursorMut<'a, T: 'a> { + index: usize, + current: Option>>, + list: &'a mut LinkedList, } diff --git a/Task/Doubly-linked-list-Element-insertion/Rust/doubly-linked-list-element-insertion-2.rs b/Task/Doubly-linked-list-Element-insertion/Rust/doubly-linked-list-element-insertion-2.rs index 3b478b7869..7f29f65ef6 100644 --- a/Task/Doubly-linked-list-Element-insertion/Rust/doubly-linked-list-element-insertion-2.rs +++ b/Task/Doubly-linked-list-Element-insertion/Rust/doubly-linked-list-element-insertion-2.rs @@ -1,52 +1,63 @@ -impl Node { - fn new(v: T) -> Node { - Node {value: v, next: None, prev: Rawlink::none()} - } +#![feature(linked_list_cursors)] + +trait CursorExt { + fn insert_between(&mut self, l: &T, elt: T, r: &T); + fn rinsert_between(&mut self, l: &T, elt: T, r: &T); } -impl Rawlink { - fn none() -> Self { - Rawlink {p: ptr::null_mut()} - } - - fn some(n: &mut T) -> Rawlink { - Rawlink{p: n} - } -} - -impl<'a, T> From<&'a mut Link> for Rawlink> { - fn from(node: &'a mut Link) -> Self { - match node.as_mut() { - None => Rawlink::none(), - Some(ptr) => Rawlink::some(ptr) +impl CursorExt for std::collections::linked_list::CursorMut<'_, T> { + fn insert_between(&mut self, l: &T, elt: T, r: &T) { + // Pointing at the sentinel, move to head + if self.current().is_none() { + self.move_next(); } - } -} + let next = |cursor: &mut Self| { + let left = cursor.current()? == a; + let right = cursor.peek_next()? == b; -fn link_no_prev(mut next: Box>) -> Link { - next.prev = Rawlink::none(); - Some(next) -} + Some(left && right) + }; -impl LinkedList { - #[inline] - fn push_front_node(&mut self, mut new_head: Box>) { - match self.list_head { - None => { - self.list_head = link_no_prev(new_head); - self.list_tail = Rawlink::from(&mut self.list_head); - } - Some(ref mut head) => { - new_head.prev = Rawlink::none(); - head.prev = Rawlink::some(&mut *new_head); - mem::swap(head, &mut new_head); - head.next = Some(new_head); + while let Some(found) = next(self) { + if found { + self.insert_after(elt); + + return; } } - self.length += 1; } - pub fn push_front(&mut self, elt: T) { - self.push_front_node(Box::new(Node::new(elt))); + + fn rinsert_between(&mut self, l: &T, elt: T, r: &T) { + // Pointing at the sentinel, move to tail + if self.current().is_none() { + self.move_prev(); + } + + let prev = |cursor: &mut Self| { + let left = cursor.peek_prev()? == a; + let right = cursor.current()? == b; + + Some(left && right) + }; + + while let Some(found) = prev(self) { + if found { + self.insert_before(elt); + + return; + } + } } } + +fn element_insertion() { + use std::collections::LinkedList; + + let mut list = LinkedList::from(['A', 'B']); + + list.cursor_front_mut().insert_between(&'A', 'C', &'B'); + // list.cursor_back_mut().rinsert_between(&'A', 'C', &'B'); + + assert_eq!(list, ['A', 'C', 'B'].into()); +} diff --git a/Task/Doubly-linked-list-Traversal/Rust/doubly-linked-list-traversal.rs b/Task/Doubly-linked-list-Traversal/Rust/doubly-linked-list-traversal.rs new file mode 100644 index 0000000000..05a8db2f1a --- /dev/null +++ b/Task/Doubly-linked-list-Traversal/Rust/doubly-linked-list-traversal.rs @@ -0,0 +1,15 @@ +fn traversal() { + use std::collections::LinkedList; + + let numbers = LinkedList::from([1, 5, 7, 0, 3, 2]); + + for i in &numbers { + print!("{i} "); + } + println!(); + + for i in numbers.iter().rev() { + print!("{i} "); + } + println!(); +} diff --git a/Task/Dragon-curve/EasyLang/dragon-curve.easy b/Task/Dragon-curve/EasyLang/dragon-curve.easy index 81f64de949..4228153a50 100644 --- a/Task/Dragon-curve/EasyLang/dragon-curve.easy +++ b/Task/Dragon-curve/EasyLang/dragon-curve.easy @@ -1,15 +1,16 @@ -color 050 -linewidth 0.5 +gcolor 050 +glinewidth 0.5 x = 25 y = 60 -move x y angle = 0 # -proc dragon size lev d . . +proc dragon size lev d . if lev = 0 + xp = x + yp = y x -= cos angle * size y += sin angle * size - line x y + gline xp yp x y else dragon size / sqrt 2 lev - 1 1 angle -= d * 90 diff --git a/Task/Draw-a-clock/EasyLang/draw-a-clock.easy b/Task/Draw-a-clock/EasyLang/draw-a-clock.easy index 6befc2a8d8..f53a4939f8 100644 --- a/Task/Draw-a-clock/EasyLang/draw-a-clock.easy +++ b/Task/Draw-a-clock/EasyLang/draw-a-clock.easy @@ -1,34 +1,32 @@ -proc draw hour min sec . . - color 333 - move 50 50 - circle 45 - color 797 - circle 44 - color 333 +proc draw hour min sec . + # dial + gcolor 333 + gcircle 50 50 45 + gcolor 797 + gcircle 50 50 44 + gcolor 333 for i range0 60 a = i * 6 - move 50 + sin a * 40 50 + cos a * 40 - circle 0.25 + if i mod 5 = 0 + gcircle 50 + sin a * 40 50 + cos a * 40 1 + else + gcircle 50 + sin a * 40 50 + cos a * 40 0.25 + . . - for i range0 12 - a = i * 30 - move 50 + sin a * 40 50 + cos a * 40 - circle 1 - . - linewidth 2 - color 000 + # hour + glinewidth 2 + gcolor 000 a = (hour * 60 + min) / 2 - move 50 50 - line 50 + sin a * 32 50 + cos a * 32 - linewidth 1.5 + gline 50 50 50 + sin a * 32 50 + cos a * 32 + # min + glinewidth 1.5 a = (sec + min * 60) / 10 - move 50 50 - line 50 + sin a * 40 50 + cos a * 40 - linewidth 1 - color 700 + gline 50 50 50 + sin a * 40 50 + cos a * 40 + # sec + glinewidth 1 + gcolor 700 a = sec * 6 - move 50 50 - line 50 + sin a * 40 50 + cos a * 40 + gline 50 50 50 + sin a * 40 50 + cos a * 40 . on timer if t <> floor systime diff --git a/Task/Draw-a-clock/OPL/draw-a-clock.opl b/Task/Draw-a-clock/OPL/draw-a-clock.opl new file mode 100644 index 0000000000..587002dc83 --- /dev/null +++ b/Task/Draw-a-clock/OPL/draw-a-clock.opl @@ -0,0 +1,4 @@ +PROC main: + gCLOCK ON,$29 + GET +ENDP diff --git a/Task/Draw-a-cuboid/EasyLang/draw-a-cuboid.easy b/Task/Draw-a-cuboid/EasyLang/draw-a-cuboid.easy index 7a8d34b01a..a7d65aaf04 100644 --- a/Task/Draw-a-cuboid/EasyLang/draw-a-cuboid.easy +++ b/Task/Draw-a-cuboid/EasyLang/draw-a-cuboid.easy @@ -1,14 +1,12 @@ node[][] = [ [ -1 -2 -2 ] [ -1 -2 1 ] [ -1 2 -2 ] [ -1 2 1 ] [ 1 -2 -2 ] [ 1 -2 1 ] [ 1 2 -2 ] [ 1 2 1 ] ] edge[][] = [ [ 1 2 ] [ 2 4 ] [ 4 3 ] [ 3 1 ] [ 5 6 ] [ 6 8 ] [ 8 7 ] [ 7 5 ] [ 1 5 ] [ 2 6 ] [ 3 7 ] [ 4 8 ] ] # -proc scale f . . - for i = 1 to len node[][] - for d = 1 to 3 - node[i][d] *= f - . +proc scale f . + for i = 1 to len node[][] : for d = 1 to 3 + node[i][d] *= f . . -proc rotate angx angy . . +proc rotate angx angy . sinx = sin angx cosx = cos angx siny = sin angy @@ -24,10 +22,9 @@ proc rotate angx angy . . . . len nd[] 3 -proc draw . . - clear - move 2 2 - text "Arrow keys to rotate" +proc draw . + gclear + gtext 2 2 "Arrow keys to rotate" m = 99999 mi = -1 for i = 1 to len node[][] @@ -46,20 +43,17 @@ proc draw . . ix += 1 . . - for ni = 1 to len nd[] - for i = 1 to len edge[][] - if edge[i][1] = nd[ni] or edge[i][2] = nd[ni] - x1 = node[edge[i][1]][1] - y1 = node[edge[i][1]][2] - x2 = node[edge[i][2]][1] - y2 = node[edge[i][2]][2] - move x1 + 50 y1 + 50 - line x2 + 50 y2 + 50 - . + for ni = 1 to len nd[] : for i = 1 to len edge[][] + if edge[i][1] = nd[ni] or edge[i][2] = nd[ni] + x1 = node[edge[i][1]][1] + y1 = node[edge[i][1]][2] + x2 = node[edge[i][2]][1] + y2 = node[edge[i][2]][2] + gline x1 + 50 y1 + 50 x2 + 50 y2 + 50 . . . -textsize 3 +gtextsize 3 scale 15 rotate 45 45 draw diff --git a/Task/Draw-a-cuboid/R/draw-a-cuboid.r b/Task/Draw-a-cuboid/R/draw-a-cuboid.r new file mode 100644 index 0000000000..ea0ab1b2f8 --- /dev/null +++ b/Task/Draw-a-cuboid/R/draw-a-cuboid.r @@ -0,0 +1,14 @@ +cuboid <- function(w, h, d){ + plot(x=NA, xlim=c(0,(w+d)*sqrt(3)/2), ylim=c(0,h+(w+d)/2), xlab=NA, ylab=NA, asp=1) + polygon(x=c(0, w*sqrt(3)/2, w*sqrt(3)/2, 0), + y=c(w/2, 0, h, h+w/2), + col="red") + polygon(x=c(0, w*sqrt(3)/2, (w+d)*sqrt(3)/2, d*sqrt(3)/2), + y=c(h+w/2, h, h+d/2, h+(w+d)/2), + col="blue") + polygon(x=c(w*sqrt(3)/2, (w+d)*sqrt(3)/2, (w+d)*sqrt(3)/2, w*sqrt(3)/2), + y=c(0, d/2, h+d/2, h), + col="yellow") +} + +cuboid(2, 3, 4) diff --git a/Task/Draw-a-pixel/EasyLang/draw-a-pixel.easy b/Task/Draw-a-pixel/EasyLang/draw-a-pixel.easy index cb12f03975..cba3accc14 100644 --- a/Task/Draw-a-pixel/EasyLang/draw-a-pixel.easy +++ b/Task/Draw-a-pixel/EasyLang/draw-a-pixel.easy @@ -1,3 +1,2 @@ -color 900 -move 50 50 -rect 0.5 0.5 +gcolor 900 +grect 50 50 0.5 0.5 diff --git a/Task/Draw-a-pixel/OPL/draw-a-pixel.opl b/Task/Draw-a-pixel/OPL/draw-a-pixel.opl new file mode 100644 index 0000000000..9e9a97f45d --- /dev/null +++ b/Task/Draw-a-pixel/OPL/draw-a-pixel.opl @@ -0,0 +1,8 @@ +PROC main: + LOCAL wndw% + wndw%=gCREATE(80,0,320,240,1,1) + gXBORDER 1,1 + gAT 100,100 + gLINEBY 0,0 + GET +ENDP diff --git a/Task/Draw-a-pixel/Uxntal/draw-a-pixel.uxnatl b/Task/Draw-a-pixel/Uxntal/draw-a-pixel.uxnatl deleted file mode 100644 index 26c8170b96..0000000000 --- a/Task/Draw-a-pixel/Uxntal/draw-a-pixel.uxnatl +++ /dev/null @@ -1,22 +0,0 @@ -( $ uxnasm draw-pixel.tal draw-pixel.rom && uxnemu draw-pixel.rom ) - -|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1 -|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 - -|0100 - ( set theme ) - #0f00 .System/r DEO2 - #0000 .System/g DEO2 - #0000 .System/b DEO2 - - ( set screen size ) - #0140 .Screen/width DEO2 - #00f0 .Screen/height DEO2 - - ( set position ) - #0064 .Screen/x DEO2 - #0064 .Screen/y DEO2 - - ( draw pixel ) - #01 .Screen/pixel DEO -BRK diff --git a/Task/Draw-a-rotating-cube/EasyLang/draw-a-rotating-cube.easy b/Task/Draw-a-rotating-cube/EasyLang/draw-a-rotating-cube.easy index 4b30030a05..09df71826d 100644 --- a/Task/Draw-a-rotating-cube/EasyLang/draw-a-rotating-cube.easy +++ b/Task/Draw-a-rotating-cube/EasyLang/draw-a-rotating-cube.easy @@ -1,14 +1,12 @@ node[][] = [ [ -1 -1 -1 ] [ -1 -1 1 ] [ -1 1 -1 ] [ -1 1 1 ] [ 1 -1 -1 ] [ 1 -1 1 ] [ 1 1 -1 ] [ 1 1 1 ] ] edge[][] = [ [ 1 2 ] [ 2 4 ] [ 4 3 ] [ 3 1 ] [ 5 6 ] [ 6 8 ] [ 8 7 ] [ 7 5 ] [ 1 5 ] [ 2 6 ] [ 3 7 ] [ 4 8 ] ] # -proc scale f . . - for i = 1 to len node[][] - for d = 1 to 3 - node[i][d] *= f - . +proc scale f . + for i = 1 to len node[][] : for d = 1 to 3 + node[i][d] *= f . . -proc rotate angx angy . . +proc rotate angx angy . sinx = sin angx cosx = cos angx siny = sin angy @@ -24,8 +22,8 @@ proc rotate angx angy . . . . len nd[] 3 -proc draw . . - clear +proc draw . + gclear m = 999 mi = -1 for i = 1 to len node[][] @@ -44,16 +42,13 @@ proc draw . . ix += 1 . . - for ni = 1 to len nd[] - for i = 1 to len edge[][] - if edge[i][1] = nd[ni] or edge[i][2] = nd[ni] - x1 = node[edge[i][1]][1] - y1 = node[edge[i][1]][2] - x2 = node[edge[i][2]][1] - y2 = node[edge[i][2]][2] - move x1 + 50 y1 + 50 - line x2 + 50 y2 + 50 - . + for ni = 1 to len nd[] : for i = 1 to len edge[][] + if edge[i][1] = nd[ni] or edge[i][2] = nd[ni] + x1 = node[edge[i][1]][1] + y1 = node[edge[i][1]][2] + x2 = node[edge[i][2]][1] + y2 = node[edge[i][2]][2] + gline x1 + 50 y1 + 50 x2 + 50 y2 + 50 . . . diff --git a/Task/Duffinian-numbers/EasyLang/duffinian-numbers.easy b/Task/Duffinian-numbers/EasyLang/duffinian-numbers.easy index 6cc97d01fb..b50d820e3d 100644 --- a/Task/Duffinian-numbers/EasyLang/duffinian-numbers.easy +++ b/Task/Duffinian-numbers/EasyLang/duffinian-numbers.easy @@ -1,9 +1,7 @@ fastfunc isprim num . i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 @@ -23,9 +21,7 @@ func sumdiv num . until d > quot if num mod d = 0 sum += d - if d <> quot - sum += quot - . + if d <> quot : sum += quot . d += 1 . @@ -37,7 +33,7 @@ func isduff n . . return 0 . -proc duffs . . +proc duffs . print "First 50 Duffinian numbers:" n = 4 repeat diff --git a/Task/Dutch-national-flag-problem/Crystal/dutch-national-flag-problem.cr b/Task/Dutch-national-flag-problem/Crystal/dutch-national-flag-problem.cr new file mode 100644 index 0000000000..3bbbfee1f8 --- /dev/null +++ b/Task/Dutch-national-flag-problem/Crystal/dutch-national-flag-problem.cr @@ -0,0 +1,34 @@ +enum FlagColor + Red + White + Blue + + def to_s + ["🔴", "⚪", "🔵"][value] + end +end + +module Indexable + def sorted? + (1...size).each do |i| + if self[i] < self[i-1] + return false + end + end + true + end +end + +balls = loop do + arr = Array.new(20) { FlagColor.values.sample } + break arr unless arr.sorted? +end + +puts balls.join +puts "Sorted: #{balls.sorted?}" +puts + +balls.sort! + +puts balls.join +puts "Sorted: #{balls.sorted?}" diff --git a/Task/Dutch-national-flag-problem/R/dutch-national-flag-problem.r b/Task/Dutch-national-flag-problem/R/dutch-national-flag-problem.r new file mode 100644 index 0000000000..bf63f230ae --- /dev/null +++ b/Task/Dutch-national-flag-problem/R/dutch-national-flag-problem.r @@ -0,0 +1,26 @@ +colours <- c("Red", "White", "Blue") + +rand_balls <- function(v, f){ + repeat{ + balls <- sample(v, sample(10:20, 1), replace=TRUE) + balls_sorted <- f(balls) + if(!identical(balls, balls_sorted)){ + print(list("Unsorted"=balls, "Sorted"=balls_sorted), quote=FALSE) + break + } + } +} + +#Method 1: converting the vector of colours to a factor and using the built-in sort() function + +colours_ordered <- factor(1:3, labels=colours) +rand_balls(colours_ordered, sort) + +#Method 2: simple counting sort (showcasing the conciseness of R's rep() function) + +counting_sort <- function(v){ + counts <- sapply(1:3, function(n) sum(v==colours[n])) + rep(colours, times=counts) +} + +rand_balls(colours, counting_sort) diff --git a/Task/Dynamic-variable-names/Ballerina/dynamic-variable-names.ballerina b/Task/Dynamic-variable-names/Ballerina/dynamic-variable-names.ballerina new file mode 100644 index 0000000000..6019bb031b --- /dev/null +++ b/Task/Dynamic-variable-names/Ballerina/dynamic-variable-names.ballerina @@ -0,0 +1,16 @@ +import ballerina/io; + +public function main() returns error? { + map nvs = {}; + io:println("Enter three variables:"); + foreach var _ in 0...2 { + string name = io:readln("\n name : "); + string value = io:readln(" value : "); + nvs[name] = check int:fromString(value); + } + + io:println("\nYour variables are:\n"); + foreach string name in nvs.keys() { + io:println(` ${name} = ${nvs[name]}`); + } +} diff --git a/Task/Eban-numbers/EasyLang/eban-numbers.easy b/Task/Eban-numbers/EasyLang/eban-numbers.easy index c01bcc7bee..031e5e69fd 100644 --- a/Task/Eban-numbers/EasyLang/eban-numbers.easy +++ b/Task/Eban-numbers/EasyLang/eban-numbers.easy @@ -1,9 +1,8 @@ func x n . - if n = 0 or n = 2 or n = 4 or n = 6 - return 1 - . + if n = 0 or n = 2 or n = 4 or n = 6 : return 1 + return 0 . -proc go start stop printable . . +proc go start stop printable . write start & " - " & stop & ":" for i = start step 2 to stop b = i div 1000000000 @@ -12,20 +11,12 @@ proc go start stop printable . . r = i mod 1000000 t = r div 1000 r = r mod 1000 - if m >= 30 and m <= 66 - m = m mod 10 - . - if t >= 30 and t <= 66 - t = t mod 10 - . - if r >= 30 and r <= 66 - r = r mod 10 - . + if m >= 30 and m <= 66 : m = m mod 10 + if t >= 30 and t <= 66 : t = t mod 10 + if r >= 30 and r <= 66 : r = r mod 10 if x b = 1 and x m = 1 and x t = 1 and x r = 1 count += 1 - if printable = 1 - write " " & i - . + if printable = 1 : write " " & i . . print " (count=" & count & ")" diff --git a/Task/Egyptian-division/EasyLang/egyptian-division.easy b/Task/Egyptian-division/EasyLang/egyptian-division.easy index a87ea0f34c..9a3a8de375 100644 --- a/Task/Egyptian-division/EasyLang/egyptian-division.easy +++ b/Task/Egyptian-division/EasyLang/egyptian-division.easy @@ -1,4 +1,4 @@ -proc egyptdiv a b . . +proc egyptdiv a b . p2 = 1 dbl = b while dbl <= a diff --git a/Task/Element-wise-operations/Arturo/element-wise-operations.arturo b/Task/Element-wise-operations/Arturo/element-wise-operations.arturo new file mode 100644 index 0000000000..350976ebd0 --- /dev/null +++ b/Task/Element-wise-operations/Arturo/element-wise-operations.arturo @@ -0,0 +1,41 @@ +scalar?: $[obj] -> in? type obj [:integer :floating :rational] + +; a function that creates new matrix functions +matrixOp: function [binOp][ + return function [ + a :block :integer :floating :rational + b :block :integer :floating :rational + ] with [binOp][ + when [ + and? block? a, block? b [ + map.with:'y a => [ + map.with:'x & => [ + call binOp @[a\[y]\[x] b\[y]\[x]] + ] + ] + ] + and? scalar? a, block? b -> + map b => [map & 'x -> call binOp @[a x]] + + and? block? a, scalar? b -> + map a => [map & 'x -> call binOp @[x b]] + + any -> throw "Expected at least one matrix." + ] + ] +] +madd: matrixOp 'add +msub: matrixOp 'sub +mmul: matrixOp 'mul +mfdiv: matrixOp 'fdiv +mpow: matrixOp 'pow! + +a: [[1 2] [3 4]] +b: [[5 6] [7 8]] + +print.lines [ + madd a b + msub a b + msub a 2 + msub 2 a +] diff --git a/Task/Element-wise-operations/EasyLang/element-wise-operations.easy b/Task/Element-wise-operations/EasyLang/element-wise-operations.easy new file mode 100644 index 0000000000..31c77deea7 --- /dev/null +++ b/Task/Element-wise-operations/EasyLang/element-wise-operations.easy @@ -0,0 +1,67 @@ +func[][] smul m[][] a . + for i to len m[][] : for j to len m[i][] + m[i][j] *= a + . + return m[][] +. +func[][] sdiv m[][] a . + return smul m[][] (1 / a) +. +func[][] sadd m[][] a . + for i to len m[][] : for j to len m[i][] + m[i][j] += a + . + return m[][] +. +func[][] ssub m[][] a . + return sadd m[][] -a +. +func[][] spow m[][] a . + for i to len m[][] : for j to len m[i][] + m[i][j] = pow m[i][j] a + . + return m[][] +. +func[][] mmul m[][] n[][] . + for i to len m[][] : for j to len m[i][] + m[i][j] *= n[i][j] + . + return m[][] +. +func[][] mdiv m[][] n[][] . + for i to len m[][] : for j to len m[i][] + m[i][j] /= n[i][j] + . + return m[][] +. +func[][] madd m[][] n[][] . + for i to len m[][] : for j to len m[i][] + m[i][j] += n[i][j] + . + return m[][] +. +func[][] msub m[][] n[][] . + for i to len m[][] : for j to len m[i][] + m[i][j] -= n[i][j] + . + return m[][] +. +func[][] mpow m[][] n[][] . + for i to len m[][] : for j to len m[i][] + m[i][j] = pow m[i][j] n[i][j] + . + return m[][] +. +m[][] = [ [ 5 3 ] [ 4 2 ] ] +n[][] = [ [ 1 2 ] [ 7 8 ] ] +# +print smul m[][] 2 +print sdiv m[][] 2 +print sadd m[][] 2 +print ssub m[][] 2 +print spow m[][] 2 +print mmul m[][] n[][] +print mdiv m[][] n[][] +print madd m[][] n[][] +print msub m[][] n[][] +print mpow m[][] n[][] diff --git a/Task/Element-wise-operations/K/element-wise-operations.k b/Task/Element-wise-operations/K/element-wise-operations-1.k similarity index 100% rename from Task/Element-wise-operations/K/element-wise-operations.k rename to Task/Element-wise-operations/K/element-wise-operations-1.k diff --git a/Task/Element-wise-operations/K/element-wise-operations-2.k b/Task/Element-wise-operations/K/element-wise-operations-2.k new file mode 100644 index 0000000000..c6dc27bae1 --- /dev/null +++ b/Task/Element-wise-operations/K/element-wise-operations-2.k @@ -0,0 +1,6 @@ +pow: {:[`f=@|/,//y; `exp y*`ln x / floating point exponent + |/,//s:y<0;o[(s+x*~s)%(~s)+x*s;y|-y] / negative exponent: reciprocate base + */(~b)+((-1+#b){x*x}\x)*b:|2\y]} / binary exponentiation +pow[matrix;matrix] / integer power of integer base +pow[0.0+matrix;matrix] / integer power of floating point base +pow[0.0+matrix;0.0+matrix] / floating point power of floating point base diff --git a/Task/Elementary-cellular-automaton/EasyLang/elementary-cellular-automaton.easy b/Task/Elementary-cellular-automaton/EasyLang/elementary-cellular-automaton.easy index 777a67e2ed..ebc10fe3e3 100644 --- a/Task/Elementary-cellular-automaton/EasyLang/elementary-cellular-automaton.easy +++ b/Task/Elementary-cellular-automaton/EasyLang/elementary-cellular-automaton.easy @@ -1,7 +1,7 @@ global celln[] cell[] . len map[] 8 # -proc evolve . . +proc evolve . for i = 1 to len cell[] ind = 0 for j = i + 1 downto i - 1 @@ -11,14 +11,12 @@ proc evolve . . . swap celln[] cell[] . -proc show . . +proc show . c$[] = [ "." "#" ] - for v in cell[] - write c$[v + 1] - . + for v in cell[] : write c$[v + 1] print "" . -proc run map count inp[] . . +proc run map count inp[] . for i to 8 map[i] = map mod 2 map = map div 2 diff --git a/Task/Elliptic-Curve-Digital-Signature-Algorithm/C-sharp/elliptic-curve-digital-signature-algorithm.cs b/Task/Elliptic-Curve-Digital-Signature-Algorithm/C-sharp/elliptic-curve-digital-signature-algorithm.cs new file mode 100644 index 0000000000..a6248faf23 --- /dev/null +++ b/Task/Elliptic-Curve-Digital-Signature-Algorithm/C-sharp/elliptic-curve-digital-signature-algorithm.cs @@ -0,0 +1,369 @@ +using System; +using System.Collections.Generic; + +public sealed class EllipticCurveDigitalSignatureAlgorithm +{ + public static void Main(string[] args) + { + // Test parameters for elliptic curve digital signature algorithm, + // using the short Weierstrass model: y^2 = x^3 + ax + b (mod N). + // + // Parameter: a, b, modulus N, base point G, order of G in the elliptic curve. + + List parameters = new List + { + new Parameter(355, 671, 1073741789, new Point(13693, 10088), 1073807281), + new Parameter(0, 7, 67096021, new Point(6580, 779), 16769911), + new Parameter(-3, 1, 877073, new Point(0, 1), 878159), + new Parameter(0, 14, 22651, new Point(63, 30), 151), + new Parameter(3, 2, 5, new Point(2, 1), 5) + }; + + // Parameters which cause failure of the algorithm for the given reasons + // the base point is of composite order + // new Parameter(0, 7, 67096021, new Point(2402, 6067), 33539822), + // the given order is of composite order + // new Parameter(0, 7, 67096021, new Point(6580, 779), 67079644), + // the modulus is not prime (deceptive example) + // new Parameter(0, 7, 877069, new Point(3, 97123), 877069), + // fails if the modulus divides the discriminant + // new Parameter(39, 387, 22651, new Point(95, 27), 22651) + + const long f = 0x789abcde; // The message's digital signature hash which is to be verified + const int d = 0; // Set d > 0 to simulate corrupted data + + foreach (Parameter parameter in parameters) + { + EllipticCurve ellipticCurve = new EllipticCurve(parameter); + Ecdsa(ellipticCurve, f, d); + } + } + + // Build the digital signature for a message using the hash aF with error bit aD + private static void Ecdsa(EllipticCurve aCurve, long aF, int aD) + { + Point point = aCurve.Multiply(aCurve.G, aCurve.R); + + if (aCurve.Discriminant() == 0 || aCurve.G.IsZero() || !point.IsZero() || !aCurve.Contains(aCurve.G)) + { + throw new InvalidOperationException("Invalid parameter in method ecdsa"); + } + + Console.WriteLine(Environment.NewLine + "key generation"); + long s = 1 + (long)(Random() * (double)(aCurve.R - 1)); + point = aCurve.Multiply(aCurve.G, s); + Console.WriteLine("private key s = " + s); + aCurve.PrintPointWithPrefix(point, "public key W = sG"); + + // Find the next highest power of two minus one. + long t = aCurve.R; + long i = 1; + while (i < 64) + { + t |= t >> (int)i; + i <<= 1; + } + long f = aF; + while (f > t) + { + f >>= 1; + } + Console.WriteLine(Environment.NewLine + "aligned hash " + $"{f:x8}"); + + Pair signature = Signature(aCurve, s, f); + Console.WriteLine("signature c, d = " + signature.A + ", " + signature.B); + + long d = aD; + if (d > 0) + { + while (d > t) + { + d >>= 1; + } + f ^= d; + Console.WriteLine(Environment.NewLine + "corrupted hash " + $"{f:x8}"); + } + + Console.WriteLine(Verify(aCurve, point, f, signature) ? "Valid" : "Invalid"); + Console.WriteLine("-----------------"); + } + + private static bool Verify(EllipticCurve aCurve, Point aPoint, long aF, Pair aSignature) + { + if (aSignature.A < 1 || aSignature.A >= aCurve.R || aSignature.B < 1 || aSignature.B >= aCurve.R) + { + return false; + } + + Console.WriteLine(Environment.NewLine + "signature verification"); + long h = ExtendedGCD(aSignature.B, aCurve.R); + long h1 = FloorMod(aF * h, aCurve.R); + long h2 = FloorMod(aSignature.A * h, aCurve.R); + Console.WriteLine("h1, h2 = " + h1 + ", " + h2); + Point v = aCurve.Multiply(aCurve.G, h1); + Point v2 = aCurve.Multiply(aPoint, h2); + aCurve.PrintPointWithPrefix(v, "h1G"); + aCurve.PrintPointWithPrefix(v2, "h2W"); + v = aCurve.Add(v, v2); + aCurve.PrintPointWithPrefix(v, "+ ="); + + if (v.IsZero()) + { + return false; + } + long c1 = FloorMod(v.X, aCurve.R); + Console.WriteLine("c' = " + c1); + return c1 == aSignature.A; + } + + private static Pair Signature(EllipticCurve aCurve, long aS, long aF) + { + long c = 0; + long d = 0; + long u; + Point v; + Console.WriteLine("Signature computation"); + + while (true) + { + while (true) + { + u = 1 + (long)(Random() * (double)(aCurve.R - 1)); + v = aCurve.Multiply(aCurve.G, u); + c = FloorMod(v.X, aCurve.R); + if (c != 0) + { + break; + } + } + + d = FloorMod(ExtendedGCD(u, aCurve.R) * FloorMod(aF + aS * c, aCurve.R), aCurve.R); + if (d != 0) + { + break; + } + } + + Console.WriteLine("one-time u = " + u); + aCurve.PrintPointWithPrefix(v, "V = uG"); + return new Pair(c, d); + } + + // Return 1 / aV modulus aU + private static long ExtendedGCD(long aV, long aU) + { + if (aV < 0) + { + aV += aU; + } + + long result = 0; + long s = 1; + while (aV != 0) + { + long quotient = FloorDiv(aU, aV); + aU = FloorMod(aU, aV); + long temp = aU; aU = aV; aV = temp; + result -= quotient * s; + temp = result; result = s; s = temp; + } + + if (aU != 1) + { + throw new InvalidOperationException("Cannot inverse modulo N, gcd = " + aU); + } + return result; + } + + private static double Random() + { + return _random.NextDouble(); + } + + // C# implementation of Java's Math.floorMod + private static long FloorMod(long x, long y) + { + return ((x % y) + y) % y; + } + + // C# implementation of Java's Math.floorDiv + private static long FloorDiv(long x, long y) + { + long r = x / y; + if ((x ^ y) < 0 && (r * y != x)) + { + r--; + } + return r; + } + + private class EllipticCurve + { + public long A { get; } + public long B { get; } + public long N { get; } + public long R { get; } + public Point G { get; } + + public EllipticCurve(Parameter aParameter) + { + N = aParameter.N; + if (N < 5 || N > MAX_MODULUS) + { + throw new InvalidOperationException("Invalid value for modulus: " + N); + } + + A = FloorMod(aParameter.A, N); + B = FloorMod(aParameter.B, N); + G = aParameter.G; + R = aParameter.R; + + if (R < 5 || R > MAX_ORDER_G) + { + throw new InvalidOperationException("Invalid value for the order of g: " + R); + } + + Console.WriteLine(); + Console.WriteLine("Elliptic curve: y^2 = x^3 + " + A + "x + " + B + " (mod " + N + ")"); + PrintPointWithPrefix(G, "base point G"); + Console.WriteLine("order(G, E) = " + R); + } + + public Point Add(Point aP, Point aQ) + { + if (aP.IsZero()) + { + return aQ; + } + if (aQ.IsZero()) + { + return aP; + } + + long la; + if (aP.X != aQ.X) + { + la = FloorMod((aP.Y - aQ.Y) * ExtendedGCD(aP.X - aQ.X, N), N); + } + else if (aP.Y == aQ.Y && aP.Y != 0) + { + la = FloorMod(FloorMod(FloorMod( + aP.X * aP.X, N) * 3 + A, N) * ExtendedGCD(2 * aP.Y, N), N); + } + else + { + return Point.ZERO; + } + + long xCoordinate = FloorMod(la * la - aP.X - aQ.X, N); + long yCoordinate = FloorMod(la * (aP.X - xCoordinate) - aP.Y, N); + return new Point(xCoordinate, yCoordinate); + } + + public Point Multiply(Point aPoint, long aK) + { + Point result = Point.ZERO; + + while (aK != 0) + { + if ((aK & 1) == 1) + { + result = Add(result, aPoint); + } + aPoint = Add(aPoint, aPoint); + aK >>= 1; + } + return result; + } + + public bool Contains(Point aPoint) + { + if (aPoint.IsZero()) + { + return true; + } + + long r = FloorMod(FloorMod(A + aPoint.X * aPoint.X, N) * aPoint.X + B, N); + long s = FloorMod(aPoint.Y * aPoint.Y, N); + return r == s; + } + + public long Discriminant() + { + long constant = 4 * FloorMod(A * A, N) * FloorMod(A, N); + return FloorMod(-16 * (FloorMod(B * B, N) * 27 + constant), N); + } + + public void PrintPointWithPrefix(Point aPoint, string aPrefix) + { + long y = aPoint.Y; + if (aPoint.IsZero()) + { + Console.WriteLine(aPrefix + " (0)"); + } + else + { + if (y > N - y) + { + y -= N; + } + Console.WriteLine(aPrefix + " (" + aPoint.X + ", " + y + ")"); + } + } + } + + private class Point + { + public long X { get; } + public long Y { get; } + + public Point(long aX, long aY) + { + X = aX; + Y = aY; + } + + public bool IsZero() + { + return X == INFINITY && Y == 0; + } + + private const long INFINITY = long.MaxValue; + public static readonly Point ZERO = new Point(INFINITY, 0); + } + + private class Pair + { + public long A { get; } + public long B { get; } + + public Pair(long a, long b) + { + A = a; + B = b; + } + } + + private class Parameter + { + public long A { get; } + public long B { get; } + public long N { get; } + public Point G { get; } + public long R { get; } + + public Parameter(long a, long b, long n, Point g, long r) + { + A = a; + B = b; + N = n; + G = g; + R = r; + } + } + + private const int MAX_MODULUS = 1073741789; + private const int MAX_ORDER_G = MAX_MODULUS + 65536; + + private static readonly Random _random = new Random(); +} diff --git a/Task/Elliptic-Curve-Digital-Signature-Algorithm/JavaScript/elliptic-curve-digital-signature-algorithm.js b/Task/Elliptic-Curve-Digital-Signature-Algorithm/JavaScript/elliptic-curve-digital-signature-algorithm.js new file mode 100644 index 0000000000..2641d7ad34 --- /dev/null +++ b/Task/Elliptic-Curve-Digital-Signature-Algorithm/JavaScript/elliptic-curve-digital-signature-algorithm.js @@ -0,0 +1,356 @@ +class EllipticCurveDigitalSignatureAlgorithm { + static main() { + // Test parameters for elliptic curve digital signature algorithm, + // using the short Weierstrass model: y^2 = x^3 + ax + b (mod N). + // + // Parameter: a, b, modulus N, base point G, order of G in the elliptic curve. + + const parameters = [ + new Parameter(355, 671, 1073741789, new Point(13693, 10088), 1073807281), + new Parameter(0, 7, 67096021, new Point(6580, 779), 16769911), + new Parameter(-3, 1, 877073, new Point(0, 1), 878159), + new Parameter(0, 14, 22651, new Point(63, 30), 151), + new Parameter(3, 2, 5, new Point(2, 1), 5), + ]; + + // Parameters which cause failure of the algorithm for the given reasons + // the base point is of composite order + // new Parameter( 0, 7, 67096021, new Point( 2402, 6067), 33539822 ), + // the given order is of composite order + // new Parameter( 0, 7, 67096021, new Point( 6580, 779), 67079644 ), + // the modulus is not prime (deceptive example) + // new Parameter( 0, 7, 877069, new Point( 3, 97123), 877069 ), + // fails if the modulus divides the discriminant + // new Parameter( 39, 387, 22651, new Point( 95, 27), 22651 ) ); + + const f = 0x789abcde; // The message's digital signature hash which is to be verified + const d = 0; // Set d > 0 to simulate corrupted data + + for (const parameter of parameters) { + const ellipticCurve = new EllipticCurve(parameter); + EllipticCurveDigitalSignatureAlgorithm.ecdsa(ellipticCurve, f, d); + } + } + + // Build the digital signature for a message using the hash aF with error bit aD + static ecdsa(aCurve, aF, aD) { + let point = aCurve.multiply(aCurve.g, aCurve.r); + + if ( + aCurve.discriminant() == 0 || + aCurve.g.isZero() || + !point.isZero() || + !aCurve.contains(aCurve.g) + ) { + //throw new Error("Invalid parameter in method ecdsa"); + } + + console.log("\nkey generation"); + const s = 1 + Math.floor(Math.random() * (aCurve.r - 1)); + point = aCurve.multiply(aCurve.g, s); + console.log("private key s = " + s); + aCurve.printPointWithPrefix(point, "public key W = sG"); + + // Find the next highest power of two minus one. + let t = aCurve.r; + let i = 1; + while (i < 64) { + t |= t >> i; + i <<= 1; + } + let f = aF; + while (f > t) { + f >>= 1; + } + console.log("\naligned hash " + f.toString(16).padStart(8, '0')); + + const signature = EllipticCurveDigitalSignatureAlgorithm.signature( + aCurve, + s, + f + ); + console.log("signature c, d = " + signature.a + ", " + signature.b); + + let d = aD; + if (d > 0) { + while (d > t) { + d >>= 1; + } + f ^= d; + console.log("\ncorrupted hash " + f.toString(16).padStart(8, '0')); + } + + console.log( + EllipticCurveDigitalSignatureAlgorithm.verify(aCurve, point, f, signature) + ? "Valid" + : "Invalid" + ); + console.log("-----------------"); + } + + static verify(aCurve, aPoint, aF, aSignature) { + if ( + aSignature.a < 1 || + aSignature.a >= aCurve.r || + aSignature.b < 1 || + aSignature.b >= aCurve.r + ) { + return false; + } + + console.log("\nsignature verification"); + const h = EllipticCurveDigitalSignatureAlgorithm.extendedGCD( + aSignature.b, + aCurve.r + ); + const h1 = EllipticCurveDigitalSignatureAlgorithm.floorMod(aF * h, aCurve.r); + const h2 = EllipticCurveDigitalSignatureAlgorithm.floorMod(aSignature.a * h, aCurve.r); + console.log("h1, h2 = " + h1 + ", " + h2); + let v = aCurve.multiply(aCurve.g, h1); + let v2 = aCurve.multiply(aPoint, h2); + aCurve.printPointWithPrefix(v, "h1G"); + aCurve.printPointWithPrefix(v2, "h2W"); + v = aCurve.add(v, v2); + aCurve.printPointWithPrefix(v, "+ ="); + + if (v.isZero()) { + return false; + } + const c1 = EllipticCurveDigitalSignatureAlgorithm.floorMod(v.x, aCurve.r); + console.log("c' = " + c1); + return c1 == aSignature.a; + } + + static signature(aCurve, aS, aF) { + let c = 0; + let d = 0; + let u; + let v; + console.log("Signature computation"); + + while (true) { + while (true) { + u = 1 + Math.floor(Math.random() * (aCurve.r - 1)); + v = aCurve.multiply(aCurve.g, u); + c = EllipticCurveDigitalSignatureAlgorithm.floorMod(v.x, aCurve.r); + if (c != 0) { + break; + } + } + + d = EllipticCurveDigitalSignatureAlgorithm.floorMod( + EllipticCurveDigitalSignatureAlgorithm.extendedGCD(u, aCurve.r) * + EllipticCurveDigitalSignatureAlgorithm.floorMod(aF + aS * c, aCurve.r), + aCurve.r + ); + if (d != 0) { + break; + } + } + + console.log("one-time u = " + u); + aCurve.printPointWithPrefix(v, "V = uG"); + return new Pair(c, d); + } + + // Return 1 / aV modulus aU + static extendedGCD(aV, aU) { + if (aV < 0) { + aV += aU; + } + + let result = 0; + let s = 1; + while (aV != 0) { + const quotient = Math.floor(aU / aV); + aU = EllipticCurveDigitalSignatureAlgorithm.floorMod(aU, aV); + let temp = aU; + aU = aV; + aV = temp; + result -= quotient * s; + temp = result; + result = s; + s = temp; + } + + if (aU != 1) { + throw new Error("Cannot inverse modulo N, gcd = " + aU); + } + return result; + } + + static floorMod(x, y) { + return ((x % y) + y) % y; + } + + // static random() { + // return Math.random(); + // } +} + +class EllipticCurve { + constructor(aParameter) { + this.n = aParameter.n; + if (this.n < 5 || this.n > EllipticCurveDigitalSignatureAlgorithm.MAX_MODULUS) { + throw new Error("Invalid value for modulus: " + this.n); + } + + this.a = EllipticCurveDigitalSignatureAlgorithm.floorMod(aParameter.a, this.n); + this.b = EllipticCurveDigitalSignatureAlgorithm.floorMod(aParameter.b, this.n); + this.g = aParameter.g; + this.r = aParameter.r; + + if (this.r < 5 || this.r > EllipticCurveDigitalSignatureAlgorithm.MAX_ORDER_G) { + throw new Error("Invalid value for the order of g: " + this.r); + } + + console.log(); + console.log( + "Elliptic curve: y^2 = x^3 + " + + this.a + + "x + " + + this.b + + " (mod " + + this.n + + ")" + ); + this.printPointWithPrefix(this.g, "base point G"); + console.log("order(G, E) = " + this.r); + } + + add(aP, aQ) { + if (aP.isZero()) { + return aQ; + } + if (aQ.isZero()) { + return aP; + } + + let la; + if (aP.x != aQ.x) { + la = EllipticCurveDigitalSignatureAlgorithm.floorMod( + (aP.y - aQ.y) * + EllipticCurveDigitalSignatureAlgorithm.extendedGCD(aP.x - aQ.x, this.n), + this.n + ); + } else if (aP.y == aQ.y && aP.y != 0) { + la = EllipticCurveDigitalSignatureAlgorithm.floorMod( + EllipticCurveDigitalSignatureAlgorithm.floorMod( + EllipticCurveDigitalSignatureAlgorithm.floorMod(aP.x * aP.x, this.n) * 3 + + this.a, + this.n + ) * EllipticCurveDigitalSignatureAlgorithm.extendedGCD(2 * aP.y, this.n), + this.n + ); + } else { + return Point.ZERO; + } + + const xCoordinate = EllipticCurveDigitalSignatureAlgorithm.floorMod( + la * la - aP.x - aQ.x, + this.n + ); + const yCoordinate = EllipticCurveDigitalSignatureAlgorithm.floorMod( + la * (aP.x - xCoordinate) - aP.y, + this.n + ); + return new Point(xCoordinate, yCoordinate); + } + + multiply(aPoint, aK) { + let result = Point.ZERO; + + while (aK != 0) { + if ((aK & 1) == 1) { + result = this.add(result, aPoint); + } + aPoint = this.add(aPoint, aPoint); + aK >>= 1; + } + return result; + } + + contains(aPoint) { + if (aPoint.isZero()) { + return true; + } + + const r = EllipticCurveDigitalSignatureAlgorithm.floorMod( + EllipticCurveDigitalSignatureAlgorithm.floorMod( + this.a + aPoint.x * aPoint.x, + this.n + ) * aPoint.x + this.b, + this.n + ); + const s = EllipticCurveDigitalSignatureAlgorithm.floorMod(aPoint.y * aPoint.y, this.n); + return r == s; + } + + discriminant() { + const constant = + 4 * + EllipticCurveDigitalSignatureAlgorithm.floorMod( + this.a * this.a, + this.n + ) * + EllipticCurveDigitalSignatureAlgorithm.floorMod(this.a, this.n); + return EllipticCurveDigitalSignatureAlgorithm.floorMod( + -16 * + (EllipticCurveDigitalSignatureAlgorithm.floorMod(this.b * this.b, this.n) * + 27 + + constant), + this.n + ); + } + + printPointWithPrefix(aPoint, aPrefix) { + let y = aPoint.y; + if (aPoint.isZero()) { + console.log(aPrefix + " (0)"); + } else { + if (y > this.n - y) { + y -= this.n; + } + console.log(aPrefix + " (" + aPoint.x + ", " + y + ")"); + } + } +} + +class Point { + constructor(aX, aY) { + this.x = aX; + this.y = aY; + } + + isZero() { + return this.x == Point.INFINITY && this.y == 0; + } +} + +class Pair { + constructor(a, b) { + this.a = a; + this.b = b; + } +} + +class Parameter { + constructor(a, b, n, g, r) { + this.a = a; + this.b = b; + this.n = n; + this.g = g; + this.r = r; + } +} + +Point.INFINITY = Number.MAX_SAFE_INTEGER; +Point.ZERO = new Point(Point.INFINITY, 0); + +EllipticCurveDigitalSignatureAlgorithm.MAX_MODULUS = 1073741789; +EllipticCurveDigitalSignatureAlgorithm.MAX_ORDER_G = + EllipticCurveDigitalSignatureAlgorithm.MAX_MODULUS + 65536; + +// EllipticCurveDigitalSignatureAlgorithm.RANDOM = Math.random(); + +EllipticCurveDigitalSignatureAlgorithm.main(); diff --git a/Task/Elliptic-Curve-Digital-Signature-Algorithm/Rust/elliptic-curve-digital-signature-algorithm.rs b/Task/Elliptic-Curve-Digital-Signature-Algorithm/Rust/elliptic-curve-digital-signature-algorithm.rs new file mode 100644 index 0000000000..2d6010e4d8 --- /dev/null +++ b/Task/Elliptic-Curve-Digital-Signature-Algorithm/Rust/elliptic-curve-digital-signature-algorithm.rs @@ -0,0 +1,507 @@ +use rand::Rng; +use std::{cmp::Ordering, mem}; + +// --- Constants --- +const MAX_MODULUS: i64 = 1_073_741_789; +const MAX_ORDER_G: i64 = MAX_MODULUS + 65536; + +// --- Structures --- + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +struct Point { + x: i64, + y: i64, +} + +impl Point { + // Represents the point at infinity (identity element) + const ZERO: Point = Point { x: i64::MAX, y: 0 }; + + fn new(x: i64, y: i64) -> Self { + Point { x, y } + } + + fn is_zero(&self) -> bool { + *self == Point::ZERO + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +struct Pair { + // Often represents (c, d) in ECDSA signature + c: i64, // Renamed 'a' to 'c' for clarity in ECDSA context + d: i64, // Renamed 'b' to 'd' for clarity in ECDSA context +} + +impl Pair { + fn new(c: i64, d: i64) -> Self { + Pair { c, d } + } +} + +#[derive(Debug, Copy, Clone)] +struct Parameter { + a: i64, + b: i64, + n: i64, // Modulus + g: Point, // Base point + r: i64, // Order of G +} + +impl Parameter { + fn new(a: i64, b: i64, n: i64, g: Point, r: i64) -> Self { + Parameter { a, b, n, g, r } + } +} + +// --- Helper Functions --- + +// Consistent floor modulus (handles negative numbers) +fn floor_mod(num: i64, modulus: i64) -> i64 { + // Assumes modulus > 0, which is true for elliptic curve 'n' and 'r' + // If modulus can be negative, more complex logic is needed like in the C++ version. + // For ECDSA n and r are positive. + if modulus <= 0 { + panic!("Modulus must be positive for floor_mod in this context."); + } + // ((num % modulus) + modulus) % modulus + let rem = num % modulus; + if rem < 0 { + rem + modulus + } else { + rem + } +} + +// Extended Euclidean Algorithm to find modular multiplicative inverse. +// Returns `x` such that `(a * x) % m == 1`. +// Returns Err if gcd(a, m) != 1 (no inverse exists). +fn extended_gcd(a: i64, m: i64) -> Result { + if m <= 0 { + return Err("Modulus must be positive for extended_gcd".to_string()); + } + let mut v = floor_mod(a, m); // Ensure v is in [0, m-1] + let mut u = m; + let mut result: i64 = 0; + let mut s: i64 = 1; + + while v != 0 { + // Using standard Euclidean algorithm division, not floor_div, as 'v' and 'u' are non-negative + let quotient = u / v; + u = u % v; + mem::swap(&mut u, &mut v); // Swap u and v + + // Update Bezout coefficients + let next_result = result.wrapping_sub(quotient.wrapping_mul(s)); + result = s; + s = next_result; + + // Keep result and s within i64 range reasonably + // (Technically full modular arithmetic on coefficients is better, + // but for typical crypto sizes i64 is usually sufficient) + } + + if u != 1 { + Err(format!( + "Cannot inverse modulo N={}, gcd({}, {}) = {}", + m, a, m, u + )) + } else { + // Ensure the result is positive + Ok(floor_mod(result, m)) + } +} + +// --- Elliptic Curve Logic --- + +#[derive(Debug, Clone)] // Cannot Copy as methods take &self +struct EllipticCurve { + a: i64, + b: i64, + n: i64, // Modulus + r: i64, // Order of G + g: Point, // Base point +} + +impl EllipticCurve { + // Constructor with validation + fn new(param: Parameter) -> Result { + if param.n < 5 || param.n > MAX_MODULUS { + return Err(format!("Invalid value for modulus: {}", param.n)); + } + if param.r < 5 || param.r > MAX_ORDER_G { + return Err(format!( + "Invalid value for the order of g: {}", + param.r + )); + } + + let a = floor_mod(param.a, param.n); + let b = floor_mod(param.b, param.n); + + let curve = EllipticCurve { + a, + b, + n: param.n, + r: param.r, + g: param.g, + }; + + println!("\nElliptic curve: y^2 = x^3 + {}x + {} (mod {})", a, b, param.n); + curve.print_point_with_prefix(curve.g, "base point G"); + println!("order(G, E) = {}", curve.r); + + // Basic check: Base point must be on the curve + if !param.g.is_zero() && !curve.contains(param.g) { + return Err(format!("Base point G {:?} is not on the curve", param.g)); + } + // Basic check: Order * G should be Zero + let order_check = curve.multiply(curve.g, curve.r); + // Check if multiplication failed or result is not Zero + match order_check { + Ok(p) if !p.is_zero() => return Err(format!("Order r={} is invalid for G: r*G is not Zero", curve.r)), + Err(e) => return Err(format!("Failed order check multiplication: {}", e)), + _ => {} // Ok and point is Zero, proceed + } + // Basic check: Discriminant non-zero (for non-singular curve) + let disc = curve.discriminant()?; + if disc == 0 { + return Err("Curve discriminant is zero (singular curve)".to_string()); + } + + Ok(curve) + } + + // Point addition (P + Q) + fn add(&self, p: Point, q: Point) -> Result { + if p.is_zero() { + return Ok(q); + } + if q.is_zero() { + return Ok(p); + } + + let lambda: i64; + if p.x != q.x { + // P != Q + let dy = p.y.wrapping_sub(q.y); + let dx = p.x.wrapping_sub(q.x); + let dx_inv = extended_gcd(dx, self.n)?; + lambda = floor_mod(dy.wrapping_mul(dx_inv), self.n); + } else if p.y == q.y && p.y != 0 { + // P == Q (Point doubling) + // lambda = (3*x^2 + a) / (2*y) mod n + let x_sq = floor_mod(p.x.wrapping_mul(p.x), self.n); + let numerator = floor_mod(x_sq.wrapping_mul(3).wrapping_add(self.a), self.n); + let denominator = floor_mod(p.y.wrapping_mul(2), self.n); + let denominator_inv = extended_gcd(denominator, self.n)?; + lambda = floor_mod(numerator.wrapping_mul(denominator_inv), self.n); + } else { + // P == -Q (p.x == q.x but p.y == -q.y mod n) or P == Q == (x, 0) + return Ok(Point::ZERO); + } + + // x_r = lambda^2 - x_p - x_q mod n + let lambda_sq = floor_mod(lambda.wrapping_mul(lambda), self.n); + let x_r = floor_mod( + lambda_sq.wrapping_sub(p.x).wrapping_sub(q.x), + self.n, + ); + + // y_r = lambda * (x_p - x_r) - y_p mod n + let x_p_sub_x_r = p.x.wrapping_sub(x_r); + let term1 = floor_mod(lambda.wrapping_mul(x_p_sub_x_r), self.n); + let y_r = floor_mod(term1.wrapping_sub(p.y), self.n); + + Ok(Point::new(x_r, y_r)) + } + + // Scalar multiplication (k * P) using double-and-add + fn multiply(&self, mut point: Point, mut k: i64) -> Result { + let mut result = Point::ZERO; + if k < 0 { + // This basic implementation doesn't handle negative k easily. + // Standard ECDSA uses positive scalars (private key, random nonce). + // If needed, one could compute k = k mod r, or compute point negation. + return Err("Negative scalar multiplication not directly supported".to_string()); + } + if k == 0 { + return Ok(Point::ZERO); + } + + // Ensure k is positive and reduced modulo r if necessary, though ECDSA usually handles this before calling. + // k = floor_mod(k, self.r); // Optional: Reduce k modulo order, requires r > 0 + + while k > 0 { + if (k & 1) == 1 { + result = self.add(result, point)?; + } + point = self.add(point, point)?; // Double the point + k >>= 1; // Halve the scalar + } + Ok(result) + } + + // Check if a point lies on the curve y^2 = x^3 + ax + b (mod n) + fn contains(&self, point: Point) -> bool { + if point.is_zero() { + return true; // Point at infinity is always on the curve + } + + // y^2 mod n + let lhs = floor_mod(point.y.wrapping_mul(point.y), self.n); + + // x^3 + ax + b mod n + let x_sq = floor_mod(point.x.wrapping_mul(point.x), self.n); + let x_cubed = floor_mod(x_sq.wrapping_mul(point.x), self.n); + let ax = floor_mod(self.a.wrapping_mul(point.x), self.n); + let rhs = floor_mod(x_cubed.wrapping_add(ax).wrapping_add(self.b), self.n); + + lhs == rhs + } + + // Calculate discriminant: -16 * (4a^3 + 27b^2) mod n + fn discriminant(&self) -> Result { + // Need intermediate results, use wrapping arithmetic carefully + let a_sq = floor_mod(self.a.wrapping_mul(self.a), self.n); + let a_cubed = floor_mod(a_sq.wrapping_mul(self.a), self.n); + let term1 = floor_mod(a_cubed.wrapping_mul(4), self.n); // 4a^3 + + let b_sq = floor_mod(self.b.wrapping_mul(self.b), self.n); + let term2 = floor_mod(b_sq.wrapping_mul(27), self.n); // 27b^2 + + let inner_sum = floor_mod(term1.wrapping_add(term2), self.n); // 4a^3 + 27b^2 + let result = floor_mod(inner_sum.wrapping_mul(-16), self.n); + + Ok(result) + } + + // Helper to print points + fn print_point_with_prefix(&self, point: Point, prefix: &str) { + if point.is_zero() { + println!("{} (0 - Point at Infinity)", prefix); + } else { + // Optionally represent y with the smaller absolute value coordinate + let mut y_repr = point.y; + if y_repr > self.n / 2 { // Simplified check assuming n > 0 + y_repr = y_repr.wrapping_sub(self.n); + } + println!("{} ({}, {})", prefix, point.x, y_repr); + } + } +} + +// --- ECDSA Functions --- + +// Generate a random number 0.0 <= x < 1.0 +fn random_f64() -> f64 { + let mut rng = rand::thread_rng(); + rng.gen::() +} + +// Generate a random integer 1 <= x < limit +fn random_i64_in_range(limit: i64) -> i64 { + if limit <= 1 { + // Avoid panic in gen_range(1..limit) if limit is 1 or less. + // In ECDSA, the limit (order r) should be > 1. + // If r was 1 or less, curve setup should have failed. + panic!("Range limit must be greater than 1 for random generation"); + } + let mut rng = rand::thread_rng(); + rng.gen_range(1..limit) // Exclusive upper bound +} + + +// Create ECDSA signature (c, d) for message hash f +// s: private key +fn signature(curve: &EllipticCurve, s: i64, f: i64) -> Result { + if curve.r <= 1 { + return Err("Curve order 'r' must be greater than 1 for signing.".to_string()); + } + + loop { + // 1. Generate random nonce 'u' (called 'k' in many texts) in [1, r-1] + let u = random_i64_in_range(curve.r); + + // 2. Calculate curve point V = u * G + let v = curve.multiply(curve.g, u)?; + if v.is_zero() { continue; } // Should technically not happen if u in [1, r-1] + + // 3. Calculate c = V.x mod r + let c = floor_mod(v.x, curve.r); + if c == 0 { continue; } // Retry if c is 0 + + // 4. Calculate d = u^-1 * (f + s*c) mod r + let u_inv = extended_gcd(u, curve.r)?; // u^-1 mod r + let s_times_c = floor_mod(s.wrapping_mul(c), curve.r); + let hash_plus_sc = floor_mod(f.wrapping_add(s_times_c), curve.r); + let d = floor_mod(u_inv.wrapping_mul(hash_plus_sc), curve.r); + + if d == 0 { continue; } // Retry if d is 0 + + println!("one-time u = {}", u); + curve.print_point_with_prefix(v, "V = uG"); + return Ok(Pair::new(c, d)); + } +} + +// Verify ECDSA signature +// point W: public key (W = s*G) +// f: message hash (same as used for signing) +// signature (c, d): the signature to verify +fn verify(curve: &EllipticCurve, public_key_w: Point, f: i64, signature: Pair) -> Result { + let (c, d) = (signature.c, signature.d); + + // 1. Check if c and d are in the valid range [1, r-1] + if !(1..curve.r).contains(&c) || !(1..curve.r).contains(&d) { + println!("Verification fail: c or d out of range [1, r-1]"); + return Ok(false); + } + + println!("\nSignature verification"); + + // 2. Calculate h = d^-1 mod r + let h = extended_gcd(d, curve.r)?; + + // 3. Calculate h1 = f * h mod r + // 4. Calculate h2 = c * h mod r + let h1 = floor_mod(f.wrapping_mul(h), curve.r); + let h2 = floor_mod(c.wrapping_mul(h), curve.r); + println!("h = d^-1 = {}", h); + println!("h1 = f*h = {}", h1); + println!("h2 = c*h = {}", h2); + + // 5. Calculate point V' = h1*G + h2*W + let v1 = curve.multiply(curve.g, h1)?; + let v2 = curve.multiply(public_key_w, h2)?; + curve.print_point_with_prefix(v1, "h1*G"); + curve.print_point_with_prefix(v2, "h2*W"); + + let v_prime = curve.add(v1, v2)?; + curve.print_point_with_prefix(v_prime, "+ = V'"); + + // 6. Check if V' is the point at infinity + if v_prime.is_zero() { + println!("Verification fail: V' is point at infinity"); + return Ok(false); + } + + // 7. Calculate c' = V'.x mod r + let c_prime = floor_mod(v_prime.x, curve.r); + println!("c' = V'.x mod r = {}", c_prime); + + // 8. Signature is valid if c' == c + Ok(c_prime == c) +} + +// Main ECDSA process: keygen, sign, verify +fn ecdsa(curve: &EllipticCurve, f_original: i64, d_error: i32) -> Result<(), String> { + // Initial curve/parameter checks (already done in EllipticCurve::new, but re-stated here) + // if curve.discriminant()? == 0 { return Err("Invalid parameter: discriminant is 0".to_string()); } + // if curve.g.is_zero() { return Err("Invalid parameter: base point G is zero".to_string()); } + // let point_check = curve.multiply(curve.g, curve.r)?; + // if !point_check.is_zero() { return Err("Invalid parameter: r*G is not zero".to_string()); } + // if !curve.contains(curve.g) { return Err("Invalid parameter: G is not on the curve".to_string()); } + + println!("\nKey generation"); + // 1. Generate private key 's' in [1, r-1] + let s = random_i64_in_range(curve.r); + // 2. Calculate public key W = s * G + let public_key_w = curve.multiply(curve.g, s)?; + println!("private key s = {}", s); + curve.print_point_with_prefix(public_key_w, "public key W = sG"); + + + // Align hash f to be within the bit range related to r + let mut f = f_original; + // Find the next highest power of two minus one for r (rough bit mask) + let mut t = curve.r; + if t > 0 { // Avoid infinite loop if r is 0 or negative (shouldn't happen) + // Efficient way to get next power of 2 minus 1 (all lower bits set) + t |= t >> 1; + t |= t >> 2; + t |= t >> 4; + t |= t >> 8; + t |= t >> 16; + t |= t >> 32; // For i64 + + // Reduce f if it's larger than the bit mask t + // This step isn't standard ECDSA but mimics the C++ example's behavior. + // Standard ECDSA typically takes the leftmost min(N, L) bits of the hash, + // where N is bit length of r, L is bit length of hash output. + while f > 0 && t > 0 && f > t { + println!("Warning: Hash {} > bitmask {}. Right-shifting hash (non-standard).", f, t); + f >>= 1; + } + } else { + println!("Warning: Curve order r ({}) is not positive. Hash alignment skipped.", curve.r); + t = i64::MAX; // Allow any hash if r is invalid + } + + println!("\nAligned hash f = 0x{:08x} ({})", f, f); + + // Sign the hash + let signature_pair = signature(curve, s, f)?; + println!("Signature (c, d) = ({}, {})", signature_pair.c, signature_pair.d); + + // Simulate data corruption if d_error > 0 + let mut f_verify = f; + if d_error > 0 { + let mut error_val = d_error as i64; + // Align the error like the hash was aligned (mimicking C++ again) + while error_val > 0 && t > 0 && error_val > t { + error_val >>= 1; + } + f_verify ^= error_val; // Apply error using XOR + println!( + "\nCorrupted hash f' = 0x{:08x} ({}) (error=0x{:x})", + f_verify, f_verify, d_error + ); + } + + // Verify the signature + let is_valid = verify(curve, public_key_w, f_verify, signature_pair)?; + println!("{}", if is_valid { "Valid" } else { "Invalid" }); + println!("-----------------"); + + Ok(()) +} + +fn main() { + // Test parameters for elliptic curve digital signature algorithm, + // using the short Weierstrass model: y^2 = x^3 + ax + b (mod N). + // Parameter: a, b, modulus N, base point G(x, y), order of G. + let parameters = vec![ + Parameter::new(355, 671, 1_073_741_789, Point::new(13693, 10088), 1_073_807_281), + Parameter::new(0, 7, 67_096_021, Point::new(6580, 779), 16_769_911), + Parameter::new(-3, 1, 877_073, Point::new(0, 1), 878_159), // SECp256k1 shape (a=0, b=7) is common, this is a=-3 + Parameter::new(0, 14, 22_651, Point::new(63, 30), 151), + Parameter::new(3, 2, 5, Point::new(2, 1), 5), // Very small curve example + ]; + + // Parameters which cause failure (commented out like C++) + // Parameter::new(0, 7, 67096021, Point::new(2402, 6067), 33539822), // G has composite order + // Parameter::new(0, 7, 67096021, Point::new(6580, 779), 67079644), // r is composite (multiple of true order) + // Parameter::new(0, 7, 877069, Point::new(3, 97123), 877069), // N not prime (877069 = 877 * 1000 + 69, maybe 7*125295 + 4?) Let's check: 877069 / 7 = 125295.5; 877069 / 11.. nope. 877069 is prime. The comment might be wrong, or the point/order pair fails for other reasons. + // Parameter::new(39, 387, 22651, Point::new(95, 27), 22651) // N divides discriminant? disc = -16*(4*39^3+27*387^2) mod 22651. Let's check: 4*39^3+27*387^2 = 4*59319 + 27*149769 = 237276 + 4043763 = 4281039. 4281039 mod 22651 = 0. Yes, N divides discriminant -> singular curve. + + // The message hash (often SHA-256 output truncated/converted to integer) + let f_hash: i64 = 0x789a_bcde; + // Set d_error > 0 to simulate corrupted data before verification + let d_error: i32 = 0; // 0 means no error + + for param in parameters { + match EllipticCurve::new(param) { + Ok(curve) => { + if let Err(e) = ecdsa(&curve, f_hash, d_error) { + eprintln!("ECDSA Error for curve {:?}: {}", param, e); + println!("-----------------"); + } + } + Err(e) => { + eprintln!("Failed to create curve with parameters {:?}: {}", param, e); + println!("-----------------"); + } + } + } +} diff --git a/Task/Elliptic-curve-arithmetic/ALGOL-68/elliptic-curve-arithmetic.alg b/Task/Elliptic-curve-arithmetic/ALGOL-68/elliptic-curve-arithmetic.alg new file mode 100644 index 0000000000..a4d2aa99b0 --- /dev/null +++ b/Task/Elliptic-curve-arithmetic/ALGOL-68/elliptic-curve-arithmetic.alg @@ -0,0 +1,81 @@ +BEGIN # elliptic curve arithmetic - translation of the C sample # + + INT bx0 = 7; + MODE PT = STRUCT( REAL x, y ); + + # using max real for INIFINTY # + PROC zero = PT: ( max real, max real ); + + OP ISZERO = ( PT p )BOOL: x OF p > 1e20 OR x OF p < -1e20; + OP - = ( PT p )PT: ( x OF p, - y OF p ); + + OP DBL = ( PT p )PT: + IF ISZERO p + THEN p + ELSE REAL l = ( 3 * x OF p * x OF p ) / ( 2 * y OF p ); + REAL rx = l * l - 2 * x OF p; + ( rx, l * ( x OF p - rx ) - y OF p ) + FI # DBL # ; + OP = = ( PT p, q )BOOL: x OF p = x OF q AND y OF p = y OF q; + OP + = ( PT p, q )PT: + IF p = q + THEN DBL p + ELIF ISZERO p + THEN q + ELIF ISZERO q + THEN p + ELIF x OF q = x OF p + THEN zero + ELSE REAL l = ( y OF q - y OF p ) / ( x OF q - x OF p ); + REAL rx = l * l - x OF p - x OF q; + ( rx, l * ( x OF p - rx ) - y OF p ) + FI # ~ # ; + OP +:= = ( REF PT p, PT q )REF PT: p := p + q; + OP * = ( PT p in, INT n )PT: + BEGIN + PT p := p in, r := zero; + INT i := 1; + WHILE i <= n DO + IF ABS ( BIN i AND BIN n ) /= 0 THEN r +:= p FI; + p := DBL p; + i *:= 2 + OD; + r + END # * # ; + + OP TOPT = ( REAL y )PT: + IF REAL v = y * y - bx0; v = 0 + THEN zero + ELSE ( SIGN v * ABS v ^ ( 1 / 3 ), y ) + FI # TOPT # ; + OP TOPT = ( INT y )PT: TOPT REAL( y ); + OP FMT = ( REAL v )STRING: + BEGIN + STRING result := fixed( v, -18, 3 ); + INT s pos := 1; + WHILE result[ s pos ] = " " DO s pos +:= 1 OD; + result[ s pos : ] + END # FMT # ; + PROC show = ( STRING s, PT p )VOID: + print( ( s + , IF ISZERO p + THEN "Zero" + ELSE ( "(" + FMT x OF p + ", " + FMT y OF p + ")" ) + FI + , newline + ) + ) # show # ; + + BEGIN # task # + PT a = TOPT 1, b = TOPT 2; + PT c = a + b; + PT d = -c; + show( "a = ", a ); + show( "b = ", b ); + show( "c = a + b = ", c ); + show( "d = -c = ", d ); + show( "c + d = ", c + d ); + show( "a + b + d = ", a + ( b + d ) ); + show( "a * 12345 = ", a * 12345 ) + END +END diff --git a/Task/Elliptic-curve-arithmetic/FreeBASIC/elliptic-curve-arithmetic.basic b/Task/Elliptic-curve-arithmetic/FreeBASIC/elliptic-curve-arithmetic.basic new file mode 100644 index 0000000000..37da585f1a --- /dev/null +++ b/Task/Elliptic-curve-arithmetic/FreeBASIC/elliptic-curve-arithmetic.basic @@ -0,0 +1,98 @@ +Const As Double INF = 1e30 + +Type Punto + As Double x, y + Declare Constructor (x As Double = INF, y As Double = INF) + Declare Function copy() As Punto + Declare Function isZero() As Integer + Declare Function neg() As Punto + Declare Function dbl() As Punto + Declare Function sum(q As Punto) As Punto + Declare Function mul(n As Integer) As Punto + Declare Function ToString() As String +End Type + +Dim Shared As Integer bCoeff = 7 ' Coeficiente de la curva elíptica + +Constructor Punto(x As Double, y As Double) + This.x = Iif(Abs(x) > 1e20, INF, x) + This.y = Iif(Abs(y) > 1e20, INF, y) +End Constructor + +Function Punto.copy() As Punto + Return Type(This.x, This.y) +End Function + +Function Punto.isZero() As Integer + Return This.x >= 1e20 Or This.x <= -1e20 Or This.x = INF +End Function + +Function Punto.neg() As Punto + Return Type(This.x, -This.y) +End Function + +Function Punto.dbl() As Punto + If This.isZero() Then Return This.copy() + + If Abs(This.y) < 1e-15 Then Return Punto() + + Dim As Double L = (3 * This.x * This.x) / (2 * This.y) + Dim As Double x3 = L * L - 2 * This.x + Return Type(x3, L * (This.x - x3) - This.y) +End Function + +Function Punto.sum(q As Punto) As Punto + If This.x = q.x And This.y = q.y Then Return This.dbl() + If This.isZero() Then Return q.copy() + If q.isZero() Then Return This.copy() + + If Abs(q.x - This.x) < 1e-15 Then Return Punto() + + Dim As Double L = (q.y - This.y) / (q.x - This.x) + Dim As Double x3 = L * L - This.x - q.x + Return Type(x3, L * (This.x - x3) - This.y) +End Function + +Function Punto.mul(n As Integer) As Punto + Dim As Punto r = Punto(), p = This.copy() + + While n > 0 + If (n And 1) Then r = r.sum(p) + p = p.dbl() + n = n Shr 1 + Wend + Return r +End Function + +Function Punto.ToString() As String + If This.isZero() Then Return "Zero" + Return "(" & Str(Int(This.x * 1000) / 1000) & ", " & Str(Int(This.y * 1000) / 1000) & ")" +End Function + +Sub show(s As String, p As Punto) + Print s & " " & p.ToString() +End Sub + +Function from_y(y As Double) As Punto + Dim As Double n = y * y - bCoeff + Dim As Double x = Sgn(n) * Abs(n)^(1.0/3.0) + Return Type(x, y) +End Function + +' Demonstrate +Dim As Punto a = from_y(1) +Dim As Punto b = from_y(2) +show("a =", a) +show("b =", b) + +Dim As Punto c = a.sum(b) +show("c = a + b =", c) + +Dim As Punto d = c.neg() +show("d = -c =", d) + +show("c + d =", c.sum(d)) +show("a + b + d =", a.sum(b.sum(d))) +show("a * 12345 =", a.mul(12345)) + +Sleep diff --git a/Task/Elliptic-curve-arithmetic/JavaScript/elliptic-curve-arithmetic.js b/Task/Elliptic-curve-arithmetic/JavaScript/elliptic-curve-arithmetic.js new file mode 100644 index 0000000000..931179415c --- /dev/null +++ b/Task/Elliptic-curve-arithmetic/JavaScript/elliptic-curve-arithmetic.js @@ -0,0 +1,90 @@ +class Pt { + static bCoeff = 7; + + constructor(x, y) { + this.x = x; + this.y = y; + } + + static zero() { + return new Pt(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); + } + + isZero() { + // same threshold logic as Java version + return this.x > 1e20 || this.x < -1e20; + } + + static fromY(y) { + // cbrt(pow(y,2) - bCoeff) + return new Pt(Math.cbrt(Math.pow(y, 2) - Pt.bCoeff), y); + } + + dbl() { + if (this.isZero()) { + return this; + } + const L = (3 * this.x * this.x) / (2 * this.y); + const x2 = Math.pow(L, 2) - 2 * this.x; + const y2 = L * (this.x - x2) - this.y; + return new Pt(x2, y2); + } + + neg() { + return new Pt(this.x, -this.y); + } + + plus(q) { + // point doubling? + if (this.x === q.x && this.y === q.y) { + return this.dbl(); + } + // handle "point at infinity" + if (this.isZero()) { + return q; + } + if (q.isZero()) { + return this; + } + const L = (q.y - this.y) / (q.x - this.x); + const xx = Math.pow(L, 2) - this.x - q.x; + const yy = L * (this.x - xx) - this.y; + return new Pt(xx, yy); + } + + mult(n) { + let r = Pt.zero(); + let p = this; + // binary double-and-add + for (let i = 1; i <= n; i <<= 1) { + if (i & n) { + r = r.plus(p); + } + p = p.dbl(); + } + return r; + } + + toString() { + if (this.isZero()) { + return "Zero"; + } + // format with 3 decimal places, dot as decimal separator + return `(${this.x.toFixed(3)},${this.y.toFixed(3)})`; + } +} + +// Equivalent of the Java `main` method +(function main() { + const a = Pt.fromY(1); + const b = Pt.fromY(2); + console.log(`a = ${a}`); + console.log(`b = ${b}`); + const c = a.plus(b); + console.log(`c = a + b = ${c}`); + const d = c.neg(); + console.log(`d = -c = ${d}`); + console.log(`c + d = ${c.plus(d)}`); + console.log(`a + b + d = ${a.plus(b).plus(d)}`); + console.log(`a * 12345 = ${a.mult(12345)}`); +})(); diff --git a/Task/Emirp-primes/REXX/emirp-primes-1.rexx b/Task/Emirp-primes/REXX/emirp-primes-1.rexx index 435a1e4aa4..02e4b4da27 100644 --- a/Task/Emirp-primes/REXX/emirp-primes-1.rexx +++ b/Task/Emirp-primes/REXX/emirp-primes-1.rexx @@ -1,36 +1,127 @@ -/*REXX program finds emirp primes (base 10): when a prime reversed, is another prime.*/ -parse arg x y . /*obtain optional arguments from the CL*/ -if x=='' | x=="," then do; x=1; y=20; end /*Not specified? Then use the default.*/ -if y=='' then y=x /* " " " " " " */ -r=y<0; y=abs(y) /*display a range of emirp primes ? */ -rly=length(y) + \r /*adjusted length of the Y value. */ -!.=0; c=0; _=2 3 5 7 11 13 17; $= /*isP; emirp count; low primes; emirps.*/ - do #=1 for words(_); p=word(_,#); @.#=p; !.p=1; end /*#*/ -#=#-1; ip=#; s.#=@.#**2 /*adjust # (for the DO loop); last P².*/ - /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒ [↓] generate more primes within range. */ - do j=@.#+2 by 2 /*only find odd primes from here on. */ - if length(#)>rly then leave /*have we enough primes for emirps? */ - if j//3 ==0 then iterate /*is J divisible by three? */ - if right(j,1)==5 then iterate /*is the right-most digit a "5" ? */ - if j//7 ==0 then iterate /*is J divisible by seven? */ - if j//11 ==0 then iterate /*is J divisible by eleven? */ - if j//13 ==0 then iterate /*is J divisible by thirteen? */ - /*[↑] the above five lines saves time.*/ - do k=ip while s.k<=j /*divide by the known odd primes. */ - if j//@.k==0 then iterate j /*J divisible by X? Then ¬prime. ___*/ - end /*k*/ /* [↑] divide by odd primes up to √ j */ - #=#+1 /*bump the number of primes found. */ - @.#=j; s.#=j*j; !.j=1 /*assign to sparse array; prime²; prime*/ - end /*j*/ /* [↑] keep generating until enough. */ - /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒ [↓] filter emirps for the display. */ - do j=6 to @.#; _=@.j /*traipse through the regular primes. */ - if (r&_>y) | (\r&c==y) then leave /*is the prime not within the range? */ - __=reverse(_) /*reverse (digits) of the regular prime*/ - if \!.__ | _==__ then iterate /*is the reverse a different prime ? */ - c=c+1 /*bump the emirp prime counter. */ - if (r&_r Then Do /* not a palindromic prime */ + If is_prime(r) Then Do /* reversed p is a prime */ + nn=nn+1 /* increment number of hits */ + Select + When run<='1' Then Do + If nn<21 Then Call show 1,'the first 20 emirps:',4 + If nn=20 Then + Leave + End + When(run='2') Then Do + If hp<8000 Then + Call cprimes 1,8000,'C' + If 7700

8000 Then + Leave + End + When(run='3') Then Do + If nn=10000 Then Do + Call show 3,'the 10.000th emirp:',6 + Leave + End + End + When(run='4') Then Do + Call cprimes 1,999999 /* dirty trick to speed thins up */ + If nn=10000 Then Do + Call show 4,'the 10.000th emirp (alternate version):',6 + Leave + End + End + Otherwise Do + Say 'Invoke as ptx 1/2/3' + Exit + End + End + End + End + End + Call oo + Say 'largest prime:' hp + Exit + + show: + Parse Arg task,header,nl + If first.task Then Do + Call o header||lb + first.task=0 + End + Call o right(p,nl) + If nn=10 Then + Call o lb + Return + +cprimes: Procedure Expose primes. psquare. is_prime. nprimes hp +/********************************************************************* +* adapted for my needs from REXX's Extensible prime generation +* Fill the array primes with prime numbers +* so that it contains at least num primes and all primes<=mp +*********************************************************************/ + Parse Arg num,mp + If symbol('primes.0')=='LIT' Then Do /* 1st time here? Initialize */ + primes.=0 /* prime numbers */ + is_prime.=0 /* is_prime.x -> x is prime */ + psquare.=0 /* psquare.x = square of */ + plist='2 3 5 7 11 13 17 19 23' /* knows low primes. */ + Do i=1 For words(plist) + p=word(plist,i) + primes.i=p + is_prime.p=1 + End + nprimes=i-1 + primes.0=nprimes+1 + psquare.nprimes=primes.nprimes**2 /* square of this prime */ + End /* [?] done with building low Ps */ + Do j=primes.nprimes+2 By 2 While nprimeshp Then + Call cprimes 1,x + Return is_prime.x + +o: ol=ol||arg(1) + Return +oo: Do While ol<>'' + Parse Var ol l (lb) ol + Say l + End + Return diff --git a/Task/Emirp-primes/REXX/emirp-primes-2.rexx b/Task/Emirp-primes/REXX/emirp-primes-2.rexx index 02e4b4da27..b202baa3e4 100644 --- a/Task/Emirp-primes/REXX/emirp-primes-2.rexx +++ b/Task/Emirp-primes/REXX/emirp-primes-2.rexx @@ -1,127 +1,95 @@ - /********************************************************************* - * 27.03.2014 Walter Pachl - *********************************************************************/ - Parse Arg run - first.=1 - nn=0 - ol='' - lb='00'x - If run='' Then run=1 - call cprimes 20,20,'A' - main_loop: - Do ip=1 To 1000000 /* loop over all primes */ - p=primes.ip /* candidate */ - If p=0 Then - call cprimes 20,hp+1,'B' - p=primes.ip /* candidate */ - r=reverse(p) /* reversed candidate */ - If p<>r Then Do /* not a palindromic prime */ - If is_prime(r) Then Do /* reversed p is a prime */ - nn=nn+1 /* increment number of hits */ - Select - When run<='1' Then Do - If nn<21 Then Call show 1,'the first 20 emirps:',4 - If nn=20 Then - Leave - End - When(run='2') Then Do - If hp<8000 Then - Call cprimes 1,8000,'C' - If 7700

8000 Then - Leave - End - When(run='3') Then Do - If nn=10000 Then Do - Call show 3,'the 10.000th emirp:',6 - Leave - End - End - When(run='4') Then Do - Call cprimes 1,999999 /* dirty trick to speed thins up */ - If nn=10000 Then Do - Call show 4,'the 10.000th emirp (alternate version):',6 - Leave - End - End - Otherwise Do - Say 'Invoke as ptx 1/2/3' - Exit - End - End - End - End - End - Call oo - Say 'largest prime:' hp - Exit +-- 22 Mar 2025 +include Settings - show: - Parse Arg task,header,nl - If first.task Then Do - Call o header||lb - first.task=0 - End - Call o right(p,nl) - If nn=10 Then - Call o lb - Return +say 'EMIRP PRIMES' +say version +say +call Time('r'); numeric digits 7 +call Primes 1e6 +call Task1 +call Task2 +call Task3 +say; say Format(Time('e'),,3) 'seconds'; say +call Time('r'); numeric digits 9 +call Primes 1e8 +call Stress +say; say Format(Time('e'),,3) 'seconds'; say +exit -cprimes: Procedure Expose primes. psquare. is_prime. nprimes hp -/********************************************************************* -* adapted for my needs from REXX's Extensible prime generation -* Fill the array primes with prime numbers -* so that it contains at least num primes and all primes<=mp -*********************************************************************/ - Parse Arg num,mp - If symbol('primes.0')=='LIT' Then Do /* 1st time here? Initialize */ - primes.=0 /* prime numbers */ - is_prime.=0 /* is_prime.x -> x is prime */ - psquare.=0 /* psquare.x = square of */ - plist='2 3 5 7 11 13 17 19 23' /* knows low primes. */ - Do i=1 For words(plist) - p=word(plist,i) - primes.i=p - is_prime.p=1 - End - nprimes=i-1 - primes.0=nprimes+1 - psquare.nprimes=primes.nprimes**2 /* square of this prime */ - End /* [?] done with building low Ps */ - Do j=primes.nprimes+2 By 2 While nprimes 20 then + leave i + call Charout ,a' ' +end +say; say +return - is_prime: Procedure Expose primes. psquare. is_prime. nprimes hp - /********************************************************************* - * check if x is a prime number - *********************************************************************/ - Parse Arg x - If x>hp Then - Call cprimes 1,x - Return is_prime.x +Task2: +procedure expose prim. flag. +say 'All emirps > 7700 and < 8000:' +n = 0 +do i = 1 + a = prim.i + if a < 7700 then + iterate + if a > 8000 then + leave i + b = Reverse(a) + if a = b then + iterate i + if \ flag.b then + iterate i + n = n+1 + call Charout ,a' ' +end +say; say +return -o: ol=ol||arg(1) - Return -oo: Do While ol<>'' - Parse Var ol l (lb) ol - Say l - End - Return +Task3: +procedure expose prim. flag. +say 'The 10000th emirp:' +n = 0 +do i = 1 + a = prim.i; b = Reverse(a) + if a = b then + iterate i + if \ flag.b then + iterate i + n = n+1 + if n = 10000 then do + say a + leave i + end +end +return + +Stress: +procedure expose prim. flag. +say 'Number of emirps < 100 million:' +p = prim.0; n = 0 +do i = 1 to p + a = prim.i; b = Reverse(a) + if a = b then + iterate i + if \ flag.b then + iterate i + n = n+1 +end +say n +say: say 'The last emirp:' +say prim.p +return + +include Functions +include Sequences +include Abend diff --git a/Task/Emirp-primes/REXX/emirp-primes-3.rexx b/Task/Emirp-primes/REXX/emirp-primes-3.rexx deleted file mode 100644 index 61b8d22be0..0000000000 --- a/Task/Emirp-primes/REXX/emirp-primes-3.rexx +++ /dev/null @@ -1,92 +0,0 @@ -say 'Emirp primes - Using REXX libraries' -parse version version; say version; say - -call Time('r'); numeric digits 7 -call Primes 1e6 -call Task1 -call Task2 -call Task3 -say; say Format(Time('e'),,3) 'seconds'; say - -call Time('r'); numeric digits 9 -call Primes 1e8 -call Stress -say; say Format(Time('e'),,3) 'seconds'; say -exit - -Task1: -procedure expose prim. -say 'The first 20 emirps:' -n = 0 -do i = 1 - a = prim.prime.i; b = Reverse(a) - if a = b then - iterate i - if \ prim.flag.b then - iterate i - n = n+1 - if n > 20 then - leave i - call Charout ,a' ' -end -say; say -return - -Task2: -procedure expose prim. -say 'All emirps > 7700 and < 8000:' -n = 0 -do i = 1 - a = prim.prime.i - if a < 7700 then - iterate - if a > 8000 then - leave i - if a = b then - iterate i - b = Reverse(a) - if \ prim.flag.b then - iterate i - n = n+1 - call Charout ,a' ' -end -say; say -return - -Task3: -procedure expose prim. -say 'The 10000th emirp:' -n = 0 -do i = 1 - a = prim.prime.i; b = Reverse(a) - if a = b then - iterate i - if \ prim.flag.b then - iterate i - n = n+1 - if n = 10000 then do - say a - leave i - end -end -return - -Stress: -procedure expose prim. -say 'Number of emirps < 100 million:' -p = prim.0; n = 0 -do i = 1 to p - a = prim.prime.i; b = Reverse(a) - if a = b then - iterate i - if \ prim.flag.b then - iterate i - n = n+1 -end -say n -say: say 'The last emirp:' -say prim.prime.p -return - -include Functions -include Sequences diff --git a/Task/Empty-string/Ballerina/empty-string.ballerina b/Task/Empty-string/Ballerina/empty-string.ballerina new file mode 100644 index 0000000000..98ffc1a0c9 --- /dev/null +++ b/Task/Empty-string/Ballerina/empty-string.ballerina @@ -0,0 +1,12 @@ +import ballerina/io; + +function isEmpty(string s) returns boolean { + return s.length() == 0; +} + +public function main() { + string s = ""; + string t = "0"; + io:println("'s' is empty? ", isEmpty(s)); + io:println("'t' is empty? ", isEmpty(t)); +} diff --git a/Task/Entropy-Narcissist/Arturo/entropy-narcissist.arturo b/Task/Entropy-Narcissist/Arturo/entropy-narcissist.arturo new file mode 100644 index 0000000000..0e4a22d5a6 --- /dev/null +++ b/Task/Entropy-Narcissist/Arturo/entropy-narcissist.arturo @@ -0,0 +1,7 @@ +entropy: function [s][ + fold values tally s [acc x] -> + acc - (x // size s) * log x // size s 2 +] + +; assumes file name +print entropy read.file ./"entropy - narcissist.art" diff --git a/Task/Equal-prime-and-composite-sums/EasyLang/equal-prime-and-composite-sums.easy b/Task/Equal-prime-and-composite-sums/EasyLang/equal-prime-and-composite-sums.easy index cd34636414..f1bf096818 100644 --- a/Task/Equal-prime-and-composite-sums/EasyLang/equal-prime-and-composite-sums.easy +++ b/Task/Equal-prime-and-composite-sums/EasyLang/equal-prime-and-composite-sums.easy @@ -1,21 +1,20 @@ fastfunc isprim num . - if num mod 2 = 0 and num > 2 - return 0 - . + if num mod 2 = 0 and num > 2 : return 0 i = 3 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 . return 1 . -indN = 1 ; indM = 2 -numP = 2 ; numC = 4 -sumP = 2 ; sumC = 4 +indN = 1 +indM = 2 +numP = 2 +numC = 4 +sumP = 2 +sumC = 4 # -numfmt 0 11 +numfmt 11 0 print " sum primes composites" repeat if sumC > sumP diff --git a/Task/Ethiopian-multiplication/Uiua/ethiopian-multiplication.uiua b/Task/Ethiopian-multiplication/Uiua/ethiopian-multiplication.uiua new file mode 100644 index 0000000000..8f809a29aa --- /dev/null +++ b/Task/Ethiopian-multiplication/Uiua/ethiopian-multiplication.uiua @@ -0,0 +1,10 @@ +Halve ← ⌊÷2 +Double ← ×2 +Odd ← ◿2 +EMul ← ◌◌⍢(⊓Halve Double⍥⊙⟜+⊸Odd)±⊙⊙0 + +┌─╴test + ⍤⤙≍ 578 EMul 17 34 + ⍤⤙≍ 0 EMul 17 0 + ⍤⤙≍ 6 EMul 2 3 +└─╴ diff --git a/Task/Euclid-Mullin-sequence/REXX/euclid-mullin-sequence.rexx b/Task/Euclid-Mullin-sequence/REXX/euclid-mullin-sequence.rexx index f8449bad85..9d280b2f13 100644 --- a/Task/Euclid-Mullin-sequence/REXX/euclid-mullin-sequence.rexx +++ b/Task/Euclid-Mullin-sequence/REXX/euclid-mullin-sequence.rexx @@ -1,58 +1,25 @@ +-- 8 May 2025 include Settings -say version; say 'Euclid-Mullin sequence'; say +say 'EUCLID-MULLIN SEQUENCE' +say version +say numeric digits 100 +call Euclids 16 call Task 16 say Format(Time('e'),,3) 'seconds' exit Task: -procedure expose eucl. -arg x -say 'The first' x 'Euclid-Mullin numbers are:' -eucl. = 0; eucl.euclid.1 = 2; eucl.0 = 1 -p = 2 -do i = 2 to x - z = p+1; t = Ffactor(z); eucl.euclid.i = t; p = p*t -end -eucl.0 = x -do i = 1 to x - call charout ,eucl.euclid.i' ' +arg xx +say 'The first' xx 'Euclid-Mullin numbers are:' +do i = 1 to xx + call Charout ,eucl.i' ' end say -return x - -Ffactor: -/* First prime factor */ -procedure -arg x -/* Fast values */ -if x < 4 then - return x -/* Check low factors */ -n = 0 -pr = '2 3 5 7 11 13 17 19 23' -do i = 1 to Words(pr) - p = Word(pr,i) - if x//p = 0 then - return p -end -/* Check higher factors */ -do j = 29 by 6 while j*j <= x - p = Right(j,1) - if p <> 5 then - if x//j = 0 then - return j - if p = 3 then - iterate - y = j+2 - if x//y = 0 then - return y -end -/* Last factor */ -if x > 1 then - return x -return 0 +return include Functions +include Sequences +include Numbers include Abend diff --git a/Task/Euler-method/EasyLang/euler-method.easy b/Task/Euler-method/EasyLang/euler-method.easy index 2103cb54ff..e861194cda 100644 --- a/Task/Euler-method/EasyLang/euler-method.easy +++ b/Task/Euler-method/EasyLang/euler-method.easy @@ -4,34 +4,34 @@ func analytic T0 t . return TR + (T0 - TR) * pow 2.71828 (K * t) . ytxt = 95 -proc draw_analytic a b . . - color 009 - move 80 ytxt +proc draw_analytic a b . + gcolor 009 + gtext 80 ytxt "analytic" ytxt -= 5 - text "analytic" for t = a to b - line t analytic 100 t + yp = y + y = analytic 100 t + if t > a : gline t - 1 yp t y . . drawgrid -linewidth 0.3 -textsize 3 +glinewidth 0.3 +gtextsize 3 draw_analytic 0 100 # func newton_cooling temp . return K * (temp - TR) . -proc draw_euler y0 a b step col . . - color col - move 80 ytxt +proc draw_euler y t t2 step col . + gcolor col + gtext 80 ytxt "step: " & step ytxt -= 5 - text "step: " & step - t = a - y = y0 - while t < b - line t y + repeat t += step + yp = y y += step * newton_cooling y + gline t - step yp t y + until t >= t2 . . draw_euler 100 0 100 10 900 diff --git a/Task/Euler-method/K/euler-method.k b/Task/Euler-method/K/euler-method.k new file mode 100644 index 0000000000..1bb3a2cd8c --- /dev/null +++ b/Task/Euler-method/K/euler-method.k @@ -0,0 +1,15 @@ +// make global variables with :: because while is only locally scoped +tn1::100 +tn::100 +// to store solution +sol::() +// these are constant, so only local scope +k:-0.07 +time:100 +steps:10 +h:time%steps +tr:20 +// applying x+h to 0 outside to end while loop +// bind to a variable to surpress output +var: {x<100}{tn1::tn+h*k*(tn-tr);sol::sol,tn;tn::tn1;x+h}\0 +sol diff --git a/Task/Euler-method/Odin/euler-method.odin b/Task/Euler-method/Odin/euler-method.odin new file mode 100644 index 0000000000..9a856cbba8 --- /dev/null +++ b/Task/Euler-method/Odin/euler-method.odin @@ -0,0 +1,36 @@ +package main + +import "core:fmt" +import "core:math" + +ivp_euler ::proc(y:f32,step:i32,end:i32){ + + y:=y + t:=i32(0) + + for ;t<=end;t+=step{ + if(t%10==0){fmt.printfln("%.3f", y)} + y+=f32(step)*cooling(f32(t),y) + } +} + +cooling :: proc(t:f32,temp:f32)-> f32{ + return -0.07* (temp-20.0) +} + +analytic :: proc(){ + for t := 0; t <= 100; t += 10{ + fmt.printfln("%.3f",20+80*math.exp_f32(f32(-0.07)*f32(t))) + } +} + +main :: proc() { + fmt.println("Step: 2 Seconds") + ivp_euler(100.0, 2,100) + fmt.println("Step: 5 Seconds") + ivp_euler(100.0, 5, 100) + fmt.println("Step: 10 Seconds") + ivp_euler(100.0, 10, 100) + fmt.println("Analytic") + analytic() +} diff --git a/Task/Euler-method/Q/euler-method.q b/Task/Euler-method/Q/euler-method.q new file mode 100644 index 0000000000..a788e246d6 --- /dev/null +++ b/Task/Euler-method/Q/euler-method.q @@ -0,0 +1,10 @@ +t:0 +time:100 +k:-0.07 +tr:20 +sol:() +steps:10 +h:time%steps +tn:100 +while [t 9) stop + n = 10 + h = 1.0_16 + do k = 2, n + h = h + 1.0_16 / k + end do + write(*, '(a, f18.16)') "Hn ", h + h = h - log(real(n, 16)) + write(*, '(a, f18.16)') " -ln ", h + a = -1.0_16 / (2.0_16 * n) + n2 = real(n, 16) * n + r = 1.0_16 + do k = 1, m + r = r * n2 + a = a + B2(k) / (2.0_16 * k * r) + end do + write(*, '(a, f18.16, /, a, f18.16, /, a, i0)') & + "err ", a, "gamma ", h + a, "k = ", n + m + write(*, '(a, f18.16, /)') "error ", abs(h + a - EULER_GAMMA) + + ! Reference value + write(*, '(a, f18.16, /)') "C = ", EULER_GAMMA +end program euler_constant diff --git a/Task/Eulers-constant-0.5772.../REXX/eulers-constant-0.5772....rexx b/Task/Eulers-constant-0.5772.../REXX/eulers-constant-0.5772....rexx index f40eab14c9..8a64b5282b 100644 --- a/Task/Eulers-constant-0.5772.../REXX/eulers-constant-0.5772....rexx +++ b/Task/Eulers-constant-0.5772.../REXX/eulers-constant-0.5772....rexx @@ -1,8 +1,11 @@ -arg n; if n = '' then n = 100; numeric digits n -parse version version; say version; glob. = ''; fact. = 0 -say 'Euler-Mascheroni constant to' n 'decimal places' +-- 10 Jun 2025 +include Settings + +say 'EULER-MASCHERONI CONSTANT' say 'Method Brent-McMillan' +say version say +arg n; if n = '' then n = 100; numeric digits n call time('r'); a = Brent(); e = format(time('e'),,3) say 'Brent ' a '('e 'seconds)' call time('r'); a = TrueValue(); e = format(time('e'),,3) @@ -12,7 +15,7 @@ exit Brent: procedure expose fact. glob. work. numeric digits Digits()+2 -/* Brent McMillan */ +-- Brent McMillan n = Ceil((Digits()*Ln(10)+Ln(Pi()))*0.25); m = Ceil(2.07*Digits()) n2 = n*n; ak = -Ln(n); bk = 1; s = ak; v = 1 do k = 1 to m @@ -29,4 +32,6 @@ return 0.57721566490153286060651209008240243104215933593992359880576723488486772 include Constants include Functions +include Special include Numbers +include Abend diff --git a/Task/Evaluate-binomial-coefficients/Asymptote/evaluate-binomial-coefficients.asymptote b/Task/Evaluate-binomial-coefficients/Asymptote/evaluate-binomial-coefficients.asymptote new file mode 100644 index 0000000000..abe1786fe5 --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/Asymptote/evaluate-binomial-coefficients.asymptote @@ -0,0 +1,34 @@ +int factorial(int n) { + if (n < 1) return 1; + + int product = 1; + for (int i = 2; i <= n; ++i) { + product = product * i; + } + + return product; +} + +int binomial(int n, int k) { + // Special cases + if (k == 0 || k == n) return 1; + if (k < 0 || k > n) return 0; + + // For efficiency, we use the smallest value of k or (n-k) + if (k > n - k) k = n - k; + + real product = 1; + for (int i = 1; i <= k; ++i) { + product = product * (n - k + i) / i; + } + + return round(product); +} + +for (int n = 0; n <= 14; ++n) { + for (int k = 0; k <= n; ++k) { + string num = format("%5d", binomial(n, k)); + write(stdout, num); + } + write(""); +} diff --git a/Task/Evaluate-binomial-coefficients/BASIC256/evaluate-binomial-coefficients.basic b/Task/Evaluate-binomial-coefficients/BASIC256/evaluate-binomial-coefficients.basic new file mode 100644 index 0000000000..376d5fac1e --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/BASIC256/evaluate-binomial-coefficients.basic @@ -0,0 +1,29 @@ +for n = 0 to 14 + for k = 0 to n + print rjust(binomial(n, k), 5); + next k + print +next n +end + +function factorial(n) + if n < 1 then return 1 + + product = 1 + for i = 2 to n + product *= i + next + + return product +end function + +function binomial(n, k) + if n < 0 or k < 0 or n <= k then return 1 + + product = 1 + for i = n - k + 1 to n + product *= i + next + + return int(product / factorial(k)) +end function diff --git a/Task/Evaluate-binomial-coefficients/Chipmunk-Basic/evaluate-binomial-coefficients.basic b/Task/Evaluate-binomial-coefficients/Chipmunk-Basic/evaluate-binomial-coefficients.basic new file mode 100644 index 0000000000..3a5261c3b0 --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/Chipmunk-Basic/evaluate-binomial-coefficients.basic @@ -0,0 +1,23 @@ +100 sub factorial(n) +110 if n < 1 then factorial = 1 +120 product = 1 +130 for i = 2 to n +140 product = product*i +150 next +160 factorial = product +170 end sub +180 sub binomial(n,k) +190 if n < 0 or k < 0 or n <= k then binomial = 1 +200 product = 1 +210 for i = n-k+1 to n +220 product = product*i +230 next +240 binomial = int(product/factorial(k)) +250 end sub +260 for n = 0 to 14 +270 for k = 0 to n +280 print using " ####"; binomial(n,k); +290 next k +300 print +310 next n +320 end diff --git a/Task/Evaluate-binomial-coefficients/Gambas/evaluate-binomial-coefficients.gambas b/Task/Evaluate-binomial-coefficients/Gambas/evaluate-binomial-coefficients.gambas new file mode 100644 index 0000000000..40dc3b7207 --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/Gambas/evaluate-binomial-coefficients.gambas @@ -0,0 +1,36 @@ +Public Sub Main() + + For n As Integer = 0 To 14 + For k As Integer = 0 To n + Print Format(binomial(n, k), " ####"); + Next + Print + Next + +End + +Function factorial(n As Integer) As Integer + + If n < 1 Then Return 1 + + Dim product As Float = 1 ' Float to avoid overflow + For i As Integer = 2 To n + product *= i + Next + + Return product + +End Function + +Function binomial(n As Integer, k As Integer) As Integer + + If n < 0 Or k < 0 Or n <= k Then Return 1 + + Dim product As Float = 1 ' Float to avoid overflow + For i As Integer = n - k + 1 To n + product *= i + Next + + Return Int(product / factorial(k)) + +End Function diff --git a/Task/Evaluate-binomial-coefficients/MSX-Basic/evaluate-binomial-coefficients.basic b/Task/Evaluate-binomial-coefficients/MSX-Basic/evaluate-binomial-coefficients.basic new file mode 100644 index 0000000000..a4c79b8cfc --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/MSX-Basic/evaluate-binomial-coefficients.basic @@ -0,0 +1,22 @@ +110 FOR N = 0 TO 14 +120 FOR K = 0 TO N +130 GOSUB 500 ' Call to binomial +140 PRINT USING " ####"; B; +150 NEXT K +160 PRINT +170 NEXT N +180 END + +500 ' Binomial subroutine +510 ' Input: N, K +520 ' Output: B (result of binomial) +530 IF K = 0 OR K = N THEN B = 1: RETURN +540 IF K < 0 OR K > N THEN B = 0: RETURN +550 ' For efficiency, we use the lowest value of K or (N-K) +560 IF K > N-K THEN K1=N-K ELSE K1=K +570 PR = 1 +580 FOR I = 1 TO K1 +590 PR = PR * (N-K1+I)/I +600 NEXT I +610 B = INT(PR + 0.5) +620 RETURN diff --git a/Task/Evaluate-binomial-coefficients/Minimal-BASIC/evaluate-binomial-coefficients.basic b/Task/Evaluate-binomial-coefficients/Minimal-BASIC/evaluate-binomial-coefficients.basic new file mode 100644 index 0000000000..f6664d5153 --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/Minimal-BASIC/evaluate-binomial-coefficients.basic @@ -0,0 +1,25 @@ +10 REM MAIN PROGRAM +20 FOR N = 0 TO 14 +30 FOR K = 0 TO N +40 GOSUB 100 +50 PRINT B +60 NEXT K +70 PRINT +80 NEXT N +90 GOTO 999 +100 REM SUB BINOMIAL +110 IF K = 0 THEN 180 +120 IF K = N THEN 180 +130 IF K < 0 THEN 190 +140 IF K > N THEN 190 +150 LET P = 1 +160 FOR I = 1 TO K +170 LET P = P * (N-K+I)/I +175 NEXT I +177 LET B = P +178 RETURN +180 LET B = 1 +185 RETURN +190 LET B = 0 +195 RETURN +999 END diff --git a/Task/Evaluate-binomial-coefficients/OxygenBasic/evaluate-binomial-coefficients.basic b/Task/Evaluate-binomial-coefficients/OxygenBasic/evaluate-binomial-coefficients.basic new file mode 100644 index 0000000000..0a2abc64de --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/OxygenBasic/evaluate-binomial-coefficients.basic @@ -0,0 +1,38 @@ +uses console + +function factorial(n as integer) as integer + if n < 1 then return 1 + + single product = 1 + + int i + for i = 2 to n + product *= i + next + + return product +end function + +function binomial(n as integer, k as integer) as integer + if n < 0 or k < 0 or n <= k then return 1 + + single product = 1 + + int i + for i = n - k + 1 to n + product *= i + next + + return product \ factorial(k) +end function + +int n, k +for n = 0 to 14 + for k = 0 to n + print binomial(n, k) " "; + next k + printl +next n + +printl cr "Enter ..." +waitkey diff --git a/Task/Evaluate-binomial-coefficients/Prolog/evaluate-binomial-coefficients.pro b/Task/Evaluate-binomial-coefficients/Prolog/evaluate-binomial-coefficients.pro new file mode 100644 index 0000000000..e232790eb4 --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/Prolog/evaluate-binomial-coefficients.pro @@ -0,0 +1,10 @@ +binomial(N, K, 0) :- K > N. +binomial(N, K, X) :- binomial_helper(1, 1, K, N, X). + +binomial_helper(R, D, K, _, R) :- D > K, !. +binomial_helper(R, D, K, N, X) :- + D =< K, + R1 is R * N / D, + D1 is D + 1, + N1 is N - 1, + binomial_helper(R1, D1, K, N1, X). diff --git a/Task/Evaluate-binomial-coefficients/QBasic/evaluate-binomial-coefficients.basic b/Task/Evaluate-binomial-coefficients/QBasic/evaluate-binomial-coefficients.basic new file mode 100644 index 0000000000..dc28d503de --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/QBasic/evaluate-binomial-coefficients.basic @@ -0,0 +1,45 @@ +DECLARE FUNCTION factorial! (n AS INTEGER) +DECLARE FUNCTION binomial! (n AS INTEGER, k AS INTEGER) + +DIM n AS INTEGER, k AS INTEGER + +FOR n = 0 TO 14 + FOR k = 0 TO n + PRINT USING " ####"; binomial(n, k); + NEXT k + PRINT +NEXT n +END + +FUNCTION binomial! (n AS INTEGER, k AS INTEGER) + ' Special cases + IF k = 0 OR k = n THEN binomial = 1 + IF k < 0 OR k > n THEN binomial = 0 + + ' For efficiency, we use the smallest value of k or (n-k) + DIM tmp AS INTEGER + tmp = k + IF tmp > n - tmp THEN tmp = n - tmp + + DIM product AS DOUBLE ' Double to avoid overflow + product = 1 + + FOR i = 1 TO tmp + product = product * (n - tmp + i) / i + NEXT i + + binomial = product +END FUNCTION + +FUNCTION factorial (n AS INTEGER) + IF n <= 1 THEN factorial = 1 + + DIM product AS DOUBLE ' Double to avoid overflow + product = 1 + + FOR i = 2 TO n + product = product * i + NEXT i + + factorial = product +END FUNCTION diff --git a/Task/Evaluate-binomial-coefficients/True-BASIC/evaluate-binomial-coefficients-1.basic b/Task/Evaluate-binomial-coefficients/True-BASIC/evaluate-binomial-coefficients-1.basic new file mode 100644 index 0000000000..1e8fe03440 --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/True-BASIC/evaluate-binomial-coefficients-1.basic @@ -0,0 +1,35 @@ +FUNCTION factorial(n) + IF n < 1 THEN LET factorial = 1 + + LET product = 1 + FOR i = 2 TO n + LET product = product*i + NEXT i + + LET factorial = product +END FUNCTION + +FUNCTION binomial(n, k) + ! Special cases + IF k = 0 OR k = n THEN LET binomial = 1 + IF k < 0 OR k > n THEN LET binomial = 0 + + ! For efficiency, we use the smallest value of k or (n-k) + IF k > n-k THEN LET k = n-k + LET product = 1 + + FOR i = 1 TO k + LET product = product*(n-k+i)/i + NEXT i + + LET binomial = INT(product+0.5) +END FUNCTION + +FOR n = 0 TO 14 + FOR k = 0 TO n + PRINT USING " ####": binomial(n,k); + NEXT k + PRINT +NEXT n + +END diff --git a/Task/Evaluate-binomial-coefficients/True-BASIC/evaluate-binomial-coefficients-2.basic b/Task/Evaluate-binomial-coefficients/True-BASIC/evaluate-binomial-coefficients-2.basic new file mode 100644 index 0000000000..f3d149d7c5 --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/True-BASIC/evaluate-binomial-coefficients-2.basic @@ -0,0 +1,25 @@ + REM PASCAL'S TRIANGLE + LET N=0 + 10 LET K=0 + 20 GOSUB 30 + PRINT B," " + LET K=K+1 + IF K<=N THEN GOTO 20 + PRINT "" + LET N=N+1 + IF N<=10 THEN GOTO 10 + END + 30 REM BINOMIAL + IF K=0 THEN GOTO 50 + IF K=N THEN GOTO 50 + LET P=1 + LET I=1 + 40 LET T=N-K+I + LET P=P*T/I + LET I=I+1 + IF I<=K THEN GOTO 40 + LET B=P + RETURN + 50 LET B=1 + RETURN + diff --git a/Task/Evaluate-binomial-coefficients/Yabasic/evaluate-binomial-coefficients.basic b/Task/Evaluate-binomial-coefficients/Yabasic/evaluate-binomial-coefficients.basic new file mode 100644 index 0000000000..b4066edf86 --- /dev/null +++ b/Task/Evaluate-binomial-coefficients/Yabasic/evaluate-binomial-coefficients.basic @@ -0,0 +1,33 @@ +for n = 0 to 14 + for k = 0 to n + print binomial(n, k) using "####"; + next k + print +next n +end + +sub factorial(n) + local product, i + + if n < 1 return 1 + + product = 1 + for i = 2 to n + product = product * i + next + + return product +end sub + +sub binomial(n, k) + local product, i + + if n < 0 or k < 0 or n <= k return 1 + + product = 1 + for i = n - k + 1 to n + product = product * i + next + + return int(product / factorial(k)) +end sub diff --git a/Task/Events/EasyLang/events.easy b/Task/Events/EasyLang/events.easy index 0206f41f44..18092d262e 100644 --- a/Task/Events/EasyLang/events.easy +++ b/Task/Events/EasyLang/events.easy @@ -1,10 +1,8 @@ on timer - move randomf * 100 randomf * 100 - circle 2 + gcircle randomf * 100 randomf * 100 2 timer 1 . on mouse_down - move mouse_x mouse_y - circle 2 + gcircle mouse_x mouse_y 2 . timer 0 diff --git a/Task/Execute-Brain-/Crystal/execute-brain-.cr b/Task/Execute-Brain-/Crystal/execute-brain-.cr new file mode 100644 index 0000000000..355443e3a0 --- /dev/null +++ b/Task/Execute-Brain-/Crystal/execute-brain-.cr @@ -0,0 +1,33 @@ +def bfrun (code) + code = code.chars + data = Hash(Int32, Int32).new(0) + dp = ip = 0 + jump_to_matching = ->(dir : Int32) { + nest = 0 + while 0 <= ip < code.size + case code[ip] + when '[' then nest += dir + when ']' then nest -= dir + end + break if nest == 0 + ip += dir + end + } + while 0 <= ip < code.size + case code[ip] + when '>' then dp += 1 + when '<' then dp -= 1 + when '+' then data[dp] += 1 + when '-' then data[dp] -= 1 + when '.' then print(data[dp].chr) + when ',' then data[dp] = STDIN.read_char.not_nil!.ord + when '[' then jump_to_matching.call(1) if data[dp] == 0 + when ']' then jump_to_matching.call(-1) if data[dp] != 0 + end + ip += 1 + end +end + +hello = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++." + +bfrun(hello) diff --git a/Task/Execute-Brain-/EasyLang/execute-brain-.easy b/Task/Execute-Brain-/EasyLang/execute-brain-.easy index 9888328243..35eabaabb8 100644 --- a/Task/Execute-Brain-/EasyLang/execute-brain-.easy +++ b/Task/Execute-Brain-/EasyLang/execute-brain-.easy @@ -1,4 +1,4 @@ -proc exec code$ . . +proc exec code$ . len mem[] 100 dp = 1 code$[] = strchars code$ @@ -54,9 +54,7 @@ func syntax code$ . elif h$ = "]" br -= 1 . - if br < 0 - return 0 - . + if br < 0 : return 0 . return if br = 0 . diff --git a/Task/Execute-Brain-/Odin/execute-brain-.odin b/Task/Execute-Brain-/Odin/execute-brain-.odin new file mode 100644 index 0000000000..e2898826a1 --- /dev/null +++ b/Task/Execute-Brain-/Odin/execute-brain-.odin @@ -0,0 +1,126 @@ +package bf + +import "core:fmt" +import "core:c/libc" +import "core:os" + +cells_size :: 2000 +getinp : i32 +inp : u8 +main :: proc() { + + // comment out to give a file from command line + // data, ok := os.read_entire_file(os.args[1]) + // assert(ok, "Could not open file") + // defer delete(data) + // input := string(data) + + input := ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-] <.>+++++++++++[<++++++++>-]<-.--------.+++.------.--------.[-]>++++++++[<++++>- ]<+.[-]++++++++++." + size_input := len(input) + cells : [cells_size]i32 + pointer:=0 + i:=0 + direction := 1 + // moving past non matching [ ] + depth:= 0 + // loop i over input + mainloop: for ; (i <= (size_input - 1) && i >=0); { + inp = input[i] + //fmt.println(i) + switch inp{ + // move pointer right + case '>': + pointer +=1 + if (pointer>cells_size-1){ + pointer=cells_size-1 + } + i += 1 + // move pointer left + case '<': + pointer -=1 + if (pointer<0){ + pointer=0 + } + i += 1 + // increase cells at pointer + case '+': + cells[pointer] = (cells[pointer] + 1) % 256 + i += 1 + // decrease cell at pointer + case '-': + cells[pointer] = (cells[pointer] - 1) % 256 + i += 1 + // output value from cell at pointer + case '.': + res := cells[pointer] + libc.putchar(res) + i += 1 + // input value in cell at pointer + case ',': + getinp= libc.getchar() + fmt.println("input:") + cells[pointer] = getinp + i += 1 + // Jump past the matching ] if the cell at the pointer is 0 + case '[': + // if cell at pointer = 0 + if cells[pointer] == 0 { + // loop until ] + + loop1: for (inp != ']' && depth == 0) { + i +=1 + inp = input[i] + if (i > (size_input-1)){ + // if i > size input [ is unbalanced + fmt.printf("unbalanced loop ") + break mainloop + } + else if (inp == '[') { + depth += 1 + } + else if (inp == ']' && depth != 0) { + depth -= 1 + } + + fmt.println(i) + } + + } // else ignore + else { + i +=1 + } + + case ']': + // Jump back to the matching [ if the cell at the pointer is nonzero + if cells[pointer] != 0 { + + loop2: for (inp!= '[' && depth == 0) { + i -= 1 + inp = input[i] + if (i < 0) + { + fmt.printf("unbalanced loop ") + break mainloop + } + else if (inp == ']') { + depth += 1 + } + else if (inp == '[' && depth != 0) { + depth -= 1 + } + //fmt.println(input[i]) + } + + } + else { + i+=1 + } + // default: move pointer + case : + i +=1 + + } + + } + +} diff --git a/Task/Execute-Computer-Zero/EasyLang/execute-computer-zero.easy b/Task/Execute-Computer-Zero/EasyLang/execute-computer-zero.easy index 1349a41c80..213c407e4a 100644 --- a/Task/Execute-Computer-Zero/EasyLang/execute-computer-zero.easy +++ b/Task/Execute-Computer-Zero/EasyLang/execute-computer-zero.easy @@ -1,4 +1,4 @@ -proc run name$ mem[] . . +proc run name$ mem[] . write name$ & ": " pc = 1 len mem[] 32 diff --git a/Task/Execute-Computer-Zero/Perl/execute-computer-zero.pl b/Task/Execute-Computer-Zero/Perl/execute-computer-zero.pl new file mode 100644 index 0000000000..a03710fef7 --- /dev/null +++ b/Task/Execute-Computer-Zero/Perl/execute-computer-zero.pl @@ -0,0 +1,154 @@ +#!/usr/bin/perl + +use strict; # https://rosettacode.org/wiki/Execute_Computer/Zero +use warnings; +$SIG{__WARN__} = sub { die @_ }; + +my ($pc, $acc, $op, $addr, $mem, %ops, @memory, $program); +@ops{qw( NOP LDA STA ADD SUB BRZ JMP STP )} = map $_ << 5, 0 .. 7; +my $codes = qr/(?:@{[join '|', keys %ops ]})/; +my @inst = (sub {}, map eval "sub {$_}", split /\n/, <<'END' =~ s/#.*//gr); +$acc = $memory[$addr] # LDA +$memory[$addr] = $acc # STA +$acc = $acc + $memory[$addr] & 0xff # ADD +$acc = $acc - $memory[$addr] & 0xff # SUB +$acc or $pc = $addr # BRZ +$pc = $addr # JMP +END + +sub assemble + { + local $_ = join '', @_; # pass in array of lines or one multi-line string + $program = /;(.*)/ ? " $1" : ''; + my %labels; + @memory = (0) x 32; + s/^([a-z]\w*):/ $labels{$1} = $` =~ tr~\n~~; '' /igem; + $memory[$` =~ tr/\n//] = $1 + ? $ops{$1} | ($labels{$2 // ''} // $2 // 0) & 0b00011111 + : ($labels{$2 // ''} // $2 // 0) & 0xff + while /^\h*($codes)?(?:\h*(\b\w+))?/gm; + } + +sub run + { + $pc = $acc = 0; + $inst[$op]() while $mem = $memory[$pc], + ($op, $addr, $pc) = ($mem >> 5, $mem & 0x1f, $pc + 1 & 0b00011111), + $op < 7; + return $acc; + } + +for ( map s/\s+\z/\n/r, do { local $/ = ''; } ) + { +# print; + assemble( $_ ); + print '*' x 20," STP with acc = ", run(), "$program\n\n"; + } + +__DATA__ + LDA x ; first example program 2 + 2 + ADD y + STP +x: 2 +y: 2 + +loop: LDA a ; second example program 7 * 8 + BRZ end + SUB one + STA a + LDA prod + ADD b + STA prod + JMP loop +end: LDA prod + STP +a: 7 +b: 8 +prod: 0 +one: 1 + +loop: LDA count ; Fibonacci + BRZ end + SUB one + STA count + LDA a + ADD b + STA temp + LDA b + STA a + LDA temp + STA b + JMP loop +end: LDA b + STP +one: 1 +a: 1 +b: 1 +temp: 0 +count: 8 + +start: LDA load ; linked list + ADD car ; head of list + STA ldcar + ADD one + STA ldcdr ; next CONS cell +ldcar: NOP + STA value +ldcdr: NOP + BRZ done ; 0 stands for NIL + STA car + JMP start +done: LDA value ; CAR of last CONS + STP +load: LDA 0 +value: 0 +car: begin +one: 1 + ; order of CONS cells + ; in memory + ; does not matter + 6 + 0 ; 0 stands for NIL + 2 ; (CADR ls) + 26 ; (CDDR ls) -- etc. + 5 + 20 + 3 + 30 +begin: 1 ; value of (CAR ls) + 22 ; points to (CDR ls) + 4 + 24 + +p: 0 ; NOP in first round Prisoner's Dilemma +c: 0 +start: STP ; wait for p's move +pmove: NOP + LDA pmove + SUB cmove + BRZ same + LDA pmove + STA cmove ; tit for tat + BRZ cdeft + LDA c ; p defected, c did not + ADD three + STA c + JMP start +cdeft: LDA p + ADD three + STA p + JMP start +same: LDA pmove + STA cmove ; tit for tat + LDA p + ADD one + ADD pmove + STA p + LDA c + ADD one + ADD pmove + STA c + JMP start +cmove: 0 ; co-operate initially +one: 1 +three: 3 diff --git a/Task/Execute-HQ9+/EasyLang/execute-hq9+.easy b/Task/Execute-HQ9+/EasyLang/execute-hq9+.easy index 73ac035a1f..95fb45691e 100644 --- a/Task/Execute-HQ9+/EasyLang/execute-hq9+.easy +++ b/Task/Execute-HQ9+/EasyLang/execute-hq9+.easy @@ -1,4 +1,4 @@ -proc run code$ . . +proc run code$ . for c$ in strchars code$ if c$ = "Q" print code$ diff --git a/Task/Execute-SNUSP/EasyLang/execute-snusp.easy b/Task/Execute-SNUSP/EasyLang/execute-snusp.easy index dde98b1d48..05ac014346 100644 --- a/Task/Execute-SNUSP/EasyLang/execute-snusp.easy +++ b/Task/Execute-SNUSP/EasyLang/execute-snusp.easy @@ -1,4 +1,4 @@ -proc snusp dlen raw$ . . +proc snusp dlen raw$ . len ds[] dlen is$[] = strsplit raw$ "\n" for s$ in is$[] @@ -6,9 +6,7 @@ proc snusp dlen raw$ . . . for ipr to len is$[][] for ipc to len is$[ipr][] - if is$[ipr][ipc] = "$" - break 2 - . + if is$[ipr][ipc] = "$" : break 2 . . dp = 1 @@ -42,9 +40,7 @@ proc snusp dlen raw$ . . elif c$ = "!" step elif c$ = "?" - if ds[dp] = 0 - step - . + if ds[dp] = 0 : step . step . diff --git a/Task/Execute-a-Markov-algorithm/C-sharp/execute-a-markov-algorithm.cs b/Task/Execute-a-Markov-algorithm/C-sharp/execute-a-markov-algorithm.cs new file mode 100644 index 0000000000..6d3499bb58 --- /dev/null +++ b/Task/Execute-a-Markov-algorithm/C-sharp/execute-a-markov-algorithm.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public class Markov +{ + ///

+ /// Take a ruleset and return a function which takes a string to which the rules + /// should be applied. + /// + /// String containing the rules + /// A function that takes a string and applies the rules + public static Func CreateMarkovProcessor(string ruleSet) + { + // Convert a ruleset string into a dictionary + Dictionary MakeRuleMap(string ruleset) + { + return ruleset.Split('\n') + .Where(e => !e.StartsWith("#")) + .Select(e => e.Split(new[] { " -> " }, StringSplitOptions.None)) + .ToDictionary(e => e[0], e => e[1]); + } + + // Split a string at an index + Tuple SplitAt(string s, int i) + { + return new Tuple(s.Substring(0, i), s.Substring(i)); + } + + // Strip a leading number of chars from a string. + string StripLeading(string s, string strip) + { + return s.Substring(strip.Length); + } + + // Replace the substring in the string. + string Replace(string s, string find, string rep) + { + string result = s; + if (s.IndexOf(find) >= 0) + { + var a = SplitAt(s, s.IndexOf(find)); + result = a.Item1 + rep + StripLeading(a.Item2, find); + } + return result; + } + + // Recursively apply the ruleset to the string. + string Parse(Dictionary rules, string s) + { + string o = s; + foreach (var rule in rules) + { + string k = rule.Key; + string v = rule.Value; + + if (v.StartsWith(".")) + { + s = Replace(s, k, StripLeading(v, ".")); + break; + } + else + { + s = Replace(s, k, v); + if (s != o) { break; } + } + } + return o == s ? s : Parse(rules, s); + } + + var ruleMap = MakeRuleMap(ruleSet); + return str => Parse(ruleMap, str); + } + + public static void Main() + { + string ruleset1 = @"# This rules file is extracted from Wikipedia: +# http://en.wikipedia.org/wiki/Markov_Algorithm +A -> apple +B -> bag +S -> shop +T -> the +the shop -> my brother +a never used -> .terminating rule"; + + string ruleset2 = @"# Slightly modified from the rules on Wikipedia +A -> apple +B -> bag +S -> .shop +T -> the +the shop -> my brother +a never used -> .terminating rule"; + + string ruleset3 = @"# BNF Syntax testing rules +A -> apple +WWWW -> with +Bgage -> ->.* +B -> bag +->.* -> money +W -> WW +S -> .shop +T -> the +the shop -> my brother +a never used -> .terminating rule"; + + string ruleset4 = @"### Unary Multiplication Engine, for testing Markov Algorithm implementations +### By Donal Fellows. +# Unary addition engine +_+1 -> _1+ +1+1 -> 11+ +# Pass for converting from the splitting of multiplication into ordinary +# addition +1! -> !1 +,! -> !+ +_! -> _ +# Unary multiplication by duplicating left side, right side times +1*1 -> x,@y +1x -> xX +X, -> 1,1 +X1 -> 1X +_x -> _X +,x -> ,X +y1 -> 1y +y_ -> _ +# Next phase of applying +1@1 -> x,@y +1@_ -> @_ +,@_ -> !_ +++ -> + +# Termination cleanup for addition +_1 -> 1 +1+_ -> 1 +_+_ -> "; + + string ruleset5 = @"# Turing machine: three-state busy beaver +# +# state A, symbol 0 => write 1, move right, new state B +A0 -> 1B +# state A, symbol 1 => write 1, move left, new state C +0A1 -> C01 +1A1 -> C11 +# state B, symbol 0 => write 1, move left, new state A +0B0 -> A01 +1B0 -> A11 +# state B, symbol 1 => write 1, move right, new state B +B1 -> 1B +# state C, symbol 0 => write 1, move left, new state B +0C0 -> B01 +1C0 -> B11 +# state C, symbol 1 => write 1, move left, halt +0C1 -> H01 +1C1 -> H11"; + + Console.WriteLine(CreateMarkovProcessor(ruleset1)("I bought a B of As from T S.")); + Console.WriteLine(CreateMarkovProcessor(ruleset2)("I bought a B of As from T S.")); + Console.WriteLine(CreateMarkovProcessor(ruleset3)("I bought a B of As W my Bgage from T S.")); + Console.WriteLine(CreateMarkovProcessor(ruleset4)("_1111*11111_")); + Console.WriteLine(CreateMarkovProcessor(ruleset5)("000000A000000")); + } +} diff --git a/Task/Execute-a-Markov-algorithm/Zig/execute-a-markov-algorithm.zig b/Task/Execute-a-Markov-algorithm/Zig/execute-a-markov-algorithm.zig new file mode 100644 index 0000000000..ec8bb8934d --- /dev/null +++ b/Task/Execute-a-Markov-algorithm/Zig/execute-a-markov-algorithm.zig @@ -0,0 +1,278 @@ +const std = @import("std"); +const testing = std.testing; +const mem = std.mem; +const Allocator = std.mem.Allocator; + +// Add a main function for Zig playground to compile +pub fn main() !void { + // Empty main function to satisfy the compiler + std.debug.print("Markov Algorithm library\n", .{}); +} + +pub const Rule = struct { + pat: []const u8, + rep: []const u8, + terminal: bool, + + pub fn init(allocator: Allocator, pat: []const u8, rep: []const u8, terminal: bool) !Rule { + const pat_owned = try allocator.dupe(u8, pat); + const rep_owned = try allocator.dupe(u8, rep); + return Rule{ + .pat = pat_owned, + .rep = rep_owned, + .terminal = terminal, + }; + } + + pub fn deinit(self: *Rule, allocator: Allocator) void { + allocator.free(self.pat); + allocator.free(self.rep); + } + + pub fn clone(self: Rule, allocator: Allocator) !Rule { + return try Rule.init(allocator, self.pat, self.rep, self.terminal); + } + + pub fn applicableRange(self: *const Rule, input: []const u8) ?struct { start: usize, end: usize } { + if (mem.indexOf(u8, input, self.pat)) |start| { + return .{ .start = start, .end = start + self.pat.len }; + } + return null; + } + + pub fn apply(self: *const Rule, s: *std.ArrayList(u8)) !bool { + if (self.applicableRange(s.items)) |range| { + try s.replaceRange(range.start, range.end - range.start, self.rep); + return true; + } + return false; + } + + pub fn fromString(allocator: Allocator, s: []const u8) !Rule { + var parts = mem.splitSequence(u8, s, " -> "); + const pat = parts.first(); + const rep_opt = parts.next(); + if (rep_opt == null) { + return error.InvalidFormat; + } + const rep = rep_opt.?; + + if (rep.len > 0 and rep[0] == '.') { + return Rule.init(allocator, pat, rep[1..], true); + } else { + return Rule.init(allocator, pat, rep, false); + } + } +}; + +pub const Rules = struct { + rules: std.ArrayList(Rule), + allocator: Allocator, + + pub fn init(allocator: Allocator) Rules { + return Rules{ + .rules = std.ArrayList(Rule).init(allocator), + .allocator = allocator, + }; + } + + pub fn deinit(self: *Rules) void { + for (self.rules.items) |*rule| { + rule.deinit(self.allocator); + } + self.rules.deinit(); + } + + pub fn clone(self: Rules) !Rules { + var new_rules = Rules.init(self.allocator); + for (self.rules.items) |rule| { + try new_rules.rules.append(try rule.clone(self.allocator)); + } + return new_rules; + } + + pub fn apply(self: *const Rules, s: *std.ArrayList(u8)) !?*const Rule { + for (self.rules.items) |*rule| { + if (try rule.apply(s)) { + return rule; + } + } + return null; + } + + pub fn execute(self: *const Rules, buffer: []const u8) ![]u8 { + var result = try std.ArrayList(u8).initCapacity(self.allocator, buffer.len); + try result.appendSlice(buffer); + + while (try self.apply(&result)) |rule| { + if (rule.terminal) { + break; + } + } + + return result.toOwnedSlice(); + } + + pub fn fromString(allocator: Allocator, s: []const u8) !Rules { + var result = Rules.init(allocator); + var lines = mem.splitScalar(u8, s, '\n'); + + while (lines.next()) |line| { + const trimmed = mem.trim(u8, line, &std.ascii.whitespace); + if (trimmed.len == 0 or trimmed[0] == '#') { + continue; + } + const rule = try Rule.fromString(allocator, trimmed); + try result.rules.append(rule); + } + + return result; + } +}; + +test "case_01" { + const allocator = std.testing.allocator; + const input = "I bought a B of As from T S."; + const rules_str = + \\# This rules file is extracted from Wikipedia: + \\# http://en.wikipedia.org/wiki/Markov_Algorithm + \\A -> apple + \\B -> bag + \\S -> shop + \\T -> the + \\the shop -> my brother + \\a never used -> .terminating rule + ; + + var rules = try Rules.fromString(allocator, rules_str); + defer rules.deinit(); + + const result = try rules.execute(input); + defer allocator.free(result); + + try testing.expectEqualStrings("I bought a bag of apples from my brother.", result); +} + +test "case_02" { + const allocator = std.testing.allocator; + const input = "I bought a B of As from T S."; + const rules_str = + \\# Slightly modified from the rules on Wikipedia + \\A -> apple + \\B -> bag + \\S -> .shop + \\T -> the + \\the shop -> my brother + \\a never used -> .terminating rule + ; + + var rules = try Rules.fromString(allocator, rules_str); + defer rules.deinit(); + + const result = try rules.execute(input); + defer allocator.free(result); + + try testing.expectEqualStrings("I bought a bag of apples from T shop.", result); +} + +test "case_03" { + const allocator = std.testing.allocator; + const input = "I bought a B of As W my Bgage from T S."; + const rules_str = + \\# BNF Syntax testing rules + \\A -> apple + \\WWWW -> with + \\Bgage -> ->.* + \\B -> bag + \\->.* -> money + \\W -> WW + \\S -> .shop + \\T -> the + \\the shop -> my brother + \\a never used -> .terminating rule + ; + + var rules = try Rules.fromString(allocator, rules_str); + defer rules.deinit(); + + const result = try rules.execute(input); + defer allocator.free(result); + + try testing.expectEqualStrings("I bought a bag of apples with my money from T shop.", result); +} + +test "case_04" { + const allocator = std.testing.allocator; + const input = "_1111*11111_"; + const rules_str = + \\### Unary Multiplication Engine, for testing Markov Algorithm implementations + \\### By Donal Fellows. + \\# Unary addition engine + \\_+1 -> _1+ + \\1+1 -> 11+ + \\# Pass for converting from the splitting of multiplication into ordinary + \\# addition + \\1! -> !1 + \\,! -> !+ + \\_! -> _ + \\# Unary multiplication by duplicating left side, right side times + \\1*1 -> x,@y + \\1x -> xX + \\X, -> 1,1 + \\X1 -> 1X + \\_x -> _X + \\,x -> ,X + \\y1 -> 1y + \\y_ -> _ + \\# Next phase of applying + \\1@1 -> x,@y + \\1@_ -> @_ + \\,@_ -> !_ + \\++ -> + + \\# Termination cleanup for addition + \\_1 -> 1 + \\1+_ -> 1 + \\_+_ -> + ; + + var rules = try Rules.fromString(allocator, rules_str); + defer rules.deinit(); + + const result = try rules.execute(input); + defer allocator.free(result); + + try testing.expectEqualStrings("11111111111111111111", result); +} + +test "case_05" { + const allocator = std.testing.allocator; + const input = "000000A000000"; + const rules_str = + \\# Turing machine: three-state busy beaver + \\# + \\# state A, symbol 0 => write 1, move right, new state B + \\A0 -> 1B + \\# state A, symbol 1 => write 1, move left, new state C + \\0A1 -> C01 + \\1A1 -> C11 + \\# state B, symbol 0 => write 1, move left, new state A + \\0B0 -> A01 + \\1B0 -> A11 + \\# state B, symbol 1 => write 1, move right, new state B + \\B1 -> 1B + \\# state C, symbol 0 => write 1, move left, new state B + \\0C0 -> B01 + \\1C0 -> B11 + \\# state C, symbol 1 => write 1, move left, halt + \\0C1 -> H01 + \\1C1 -> H11 + ; + + var rules = try Rules.fromString(allocator, rules_str); + defer rules.deinit(); + + const result = try rules.execute(input); + defer allocator.free(result); + + try testing.expectEqualStrings("00011H1111000", result); +} diff --git a/Task/Extensible-prime-generator/C-sharp/extensible-prime-generator.cs b/Task/Extensible-prime-generator/C-sharp/extensible-prime-generator.cs new file mode 100644 index 0000000000..62d8a7b3cb --- /dev/null +++ b/Task/Extensible-prime-generator/C-sharp/extensible-prime-generator.cs @@ -0,0 +1,88 @@ +using System.Collections; + +IEnumerable StartSieve(int length) +{ + yield return 2; + BitArray sieve = new(length); + var i = 3; + + while (i < length) + { + if (!sieve[i]) + { + yield return i; + var j = i * i; + + while (j < length) + { + sieve[j] = true; + j += i; + } + } + + i += 2; + } +} + +IEnumerable AllPrimes() +{ + + foreach (var prime in StartSieve(1000)) + { + yield return prime; + } + + var start = 1000; + + while (true) + { + foreach (var prime in Sieve(start, 1000)) + { + yield return prime; + } + + start += 1000; + } +} + +IEnumerable Sieve(int start, int length) +{ + var sieve = new BitArray(length); + + foreach (var p in AllPrimes().Skip(1).TakeWhile(n => n * n < start + length)) + { + var j = p * ((start + p - 1) / p); + + while (j < start + length) + { + sieve[j - start] = true; + j += p; + } + } + + for (var j = 1 - (start % 2); j < length; j += 2) + { + if (!sieve[j]) + yield return start + j; + } +} + +Console.Write("First 20 primes:"); + +foreach (var p in AllPrimes().Take(20)) + Console.Write($" {p}"); + +Console.WriteLine(); +Console.Write("Primes between 100 and 150:"); + +foreach (var p in Sieve(100, 50)) + Console.Write($" {p}"); + +Console.WriteLine(); +Console.Write("Number of primes between 7700 and 8000:"); +var n = Sieve(7700, 300).Count(); +Console.WriteLine($" {n}"); + +Console.Write("10000th prime:"); +var t = AllPrimes().Skip(9999).First(); +Console.WriteLine($" {t}"); diff --git a/Task/Extensible-prime-generator/EasyLang/extensible-prime-generator.easy b/Task/Extensible-prime-generator/EasyLang/extensible-prime-generator.easy index caccaacfce..4bce905441 100644 --- a/Task/Extensible-prime-generator/EasyLang/extensible-prime-generator.easy +++ b/Task/Extensible-prime-generator/EasyLang/extensible-prime-generator.easy @@ -11,7 +11,7 @@ fastfunc nprim num . . prim = 2 primcnt = 1 -proc nextprim . . +proc nextprim . prim = nprim (prim + 1) primcnt += 1 . diff --git a/Task/Extensible-prime-generator/REXX/extensible-prime-generator-1.rexx b/Task/Extensible-prime-generator/REXX/extensible-prime-generator-1.rexx deleted file mode 100644 index 84d7cc6aa0..0000000000 --- a/Task/Extensible-prime-generator/REXX/extensible-prime-generator-1.rexx +++ /dev/null @@ -1,50 +0,0 @@ -/*REXX program calculates and displays primes using an extendible prime number generator*/ -parse arg f .; if f=='' then f= 20 /*allow specifying number for 1 ──► F.*/ -_i= ' (inclusive) '; _b= 'between '; _tnp= 'the number of primes' _b; _tn= 'the primes' -call primes f; do j=1 for f; $= $ @.j; end /*j*/ - say 'the first ' f " primes are: " $ - say -call primes -150; do j=100 to 150; if !.j==1 then $= $ j; end /*j*/ - say _tn _b '100 to 150' _i "are: " $ - say -call primes -8000; do j=7700 to 8000; if !.j==1 then $= $ j; end /*j*/ - say _tnp '7,700 and 8,000' _i "is: " words($) - say -call primes 10000 - say 'the 10,000th prime is: ' @.10000 -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -primes: procedure expose !. @. $ #; parse arg H,,$; Hneg= H<0; H= abs(H) - if symbol('#')=="LIT" then call .primI /*1st time here? Then initialize stuff*/ - if Hneg then if H<=@.# then return /*do we have a high enough P already?*/ - else nop /*this is used to match the above THEN.*/ - else if H<=# then return /*are there enough primes currently ? */ - /* [↓] gen more primes within range. */ - do j=@.#+2 by 2; parse var j '' -1 _ /*find primes until have H Primes. */ - if _==5 then iterate /*is the right─most digit a 5 (five)? */ - if j// 3==0 then iterate /*is J divisible by three? (& etc.)*/ - if j// 7==0 then iterate; if j//11==0 then iterate; if j//13==0 then iterate - if j//17==0 then iterate; if j//19==0 then iterate; if j//23==0 then iterate - if j//29==0 then iterate; if j//31==0 then iterate; if j//37==0 then iterate - if j//41==0 then iterate; if j//43==0 then iterate; if j//47==0 then iterate - if j//53==0 then iterate; if j//59==0 then iterate; if j//61==0 then iterate - if j//67==0 then iterate; if j//71==0 then iterate; if j//73==0 then iterate - if j//79==0 then iterate; if j//83==0 then iterate; if j//89==0 then iterate - if j//97==0 then iterate; if j//101==0 then iterate; if j//103==0 then iterate - x= j; r= 0; q= 1; do while q<=x; q= q*4; end /*R: the sqrt(J).*/ - do while q>1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end - do k=@.lowP while @.k<=r /*÷ by the known odd primes (hardcoded)*/ - if j//@.k==0 then iterate j /*J ÷ by a prime? Then not prime. ___*/ - end /*k*/ /* [↑] divide by odd primes up to √ J */ - #= # + 1 /*bump the number of primes found. */ - @.#= j; !.j= 1 /*assign to sparse array; prime²; P#.*/ - if Hneg then if H<=@.# then leave /*is this a high enough prime? */ - else nop /*used to match the above THEN. */ - else if H<=# then leave /*have enough primes been generated? */ - end /*j*/ /* [↑] keep generating until enough. */ - return /*return to invoker with more primes. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -.primI: !.=0; @.=0; /*!.x= a prime or not; @.n= Nth prime.*/ - L= 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 - do #=1 for words(L); p= word(L, #); @.#= p; !.p=1; end /*#*/ - #= # - 1; @.lowP= #; return /*#: # primes; @.lowP: start of ÷ */ diff --git a/Task/Extensible-prime-generator/REXX/extensible-prime-generator-3.rexx b/Task/Extensible-prime-generator/REXX/extensible-prime-generator-3.rexx deleted file mode 100644 index 03683ffe5d..0000000000 --- a/Task/Extensible-prime-generator/REXX/extensible-prime-generator-3.rexx +++ /dev/null @@ -1,9 +0,0 @@ -... -/* call Primes 105e3 */ -/* call First20 */ -/* call Between100and150 */ -/* call Between7700and8000 */ -/* call Number10000 */ -call Primes 1e8 -call Extended -... diff --git a/Task/Extensible-prime-generator/REXX/extensible-prime-generator-2.rexx b/Task/Extensible-prime-generator/REXX/extensible-prime-generator.rexx similarity index 54% rename from Task/Extensible-prime-generator/REXX/extensible-prime-generator-2.rexx rename to Task/Extensible-prime-generator/REXX/extensible-prime-generator.rexx index 77be2fa9f0..9ca2e91f50 100644 --- a/Task/Extensible-prime-generator/REXX/extensible-prime-generator-2.rexx +++ b/Task/Extensible-prime-generator/REXX/extensible-prime-generator.rexx @@ -1,50 +1,25 @@ +-- 22 Mar 2025 include Settings -say version; say 'Extensible prime generator'; say +say 'EXTENSIBLE PRIME GENERATOR' +say version +say numeric digits 9 call Primes 105e3 call First20 call Between100and150 call Between7700and8000 call Number10000 -/* call Primes 1e8 */ -/* call Extended */ +call Primes 1e8 +call Extended say Format(Time('e'),,3) 'seconds' exit -Primes: -/* Prime numbers */ -procedure expose prim. work. -arg x -/* Init */ -prim. = 0 -/* Fast values */ -if x = 1 then - return 0 -/* Sieve of Eratosthenes */ -work. = 1 -do i = 3 by 2 to x while i*i <= x - if work.prime.i then do - do j = i*i by i+i to x - work.prime.j = 0 - end - end -end -/* Save results */ -n = 1; prim.prime.1 = 2; prim.flag.2 = 1 -do i = 3 by 2 to x - if work.prime.i then do - n = n+1; prim.prime.n = i; prim.flag.i = 1 - end -end -prim.0 = n -return n - First20: procedure expose prim. say 'The first 20 prime numbers are:' do i = 1 to 20 - call charout ,right(prim.prime.i,3) + call charout ,right(prim.i,3) if i//10 = 0 then say end @@ -56,7 +31,7 @@ procedure expose prim. say 'Prime numbers between 100 and 150 are:' n = 0 do i = 1 - a = prim.prime.i + a = prim.i if a < 100 then iterate i if a > 150 then @@ -71,10 +46,10 @@ return Between7700and8000: procedure expose prim. -say 'Prime numbers between 7700 and 8000:' +say 'Prime numbers between 77022 Mar 2025:' n = 0 do i = 1 - a = prim.prime.i + a = prim.i if a < 7700 then iterate i if a > 8000 then @@ -87,7 +62,7 @@ return Number10000: procedure expose prim. say 'The 10000th prime number is:' -say prim.prime.10000 +say prim.10000 say return @@ -95,12 +70,13 @@ Extended: procedure expose prim. do i = 1 to 6 j = 10**i - say 'The' j'th prime is' prim.prime.j + say 'The' j'th prime is' prim.j end -say 'The 5500000th prime is' prim.prime.5500000 +say 'The 5500000th prime is' prim.5500000 say return include Functions +include Sequences include Numbers include Abend diff --git a/Task/Extreme-floating-point-values/Ballerina/extreme-floating-point-values.ballerina b/Task/Extreme-floating-point-values/Ballerina/extreme-floating-point-values.ballerina new file mode 100644 index 0000000000..8e2a51d86b --- /dev/null +++ b/Task/Extreme-floating-point-values/Ballerina/extreme-floating-point-values.ballerina @@ -0,0 +1,34 @@ +import ballerina/io; + +public function main() { + // using pre-defined constants + final float inf = float:Infinity; + final float negInf = -inf; + final float nan = float:NaN; + final float negZero = -0.0; + io:println([inf, negInf, nan, negZero]); + io:println([inf + inf, negInf + inf, nan * nan, negZero == 0.0]); + io:println([inf/inf, negInf/2, nan + inf, negZero/0]); + io:println(); + + // using values computed from other 'normal' values + float inf2 = 1.0 / 0.0; + float negInf2 = -1.0 / 0.0; + float nan2 = 0.0 / 0.0; + float nan3 = (-2.0).sqrt(); + + // using value equality + io:println(inf2 == inf); + io:println(negInf == negInf2); + io:println(nan == nan); + io:println(nan == nan2); + io:println(nan == nan3); + io:println(0.0 == negZero); // true + io:println(); + + // using storage equality + io:println(nan === nan); + io:println(nan === nan2); + io:println(nan === nan3); + io:println(0.0 === negZero); // false +} diff --git a/Task/Factorial/EasyLang/factorial.easy b/Task/Factorial/EasyLang/factorial.easy index 1ad66bdb70..697c8807fd 100644 --- a/Task/Factorial/EasyLang/factorial.easy +++ b/Task/Factorial/EasyLang/factorial.easy @@ -1,8 +1,6 @@ func factorial n . r = 1 - for i = 2 to n - r *= i - . + for i = 2 to n : r *= i return r . print factorial 7 diff --git a/Task/Factorial/Java/factorial-4.java b/Task/Factorial/Java/factorial-4.java new file mode 100644 index 0000000000..7194a10356 --- /dev/null +++ b/Task/Factorial/Java/factorial-4.java @@ -0,0 +1,27 @@ +import java.math.BigInteger; +import java.util.function.Function; +import java.util.stream.LongStream; +import java.util.stream.Stream; + +public final class Factorial { + + public static void main(String[] args) { + // Valid only for integer arguments 1, 2, ... , 20 + Function factorialPositive = n -> LongStream.rangeClosed(2, n).reduce(1, (a, b) -> a * b); + + // Valid for integer arguments <= 20 + Function factorial = n -> { + if ( n < 0 || n > 20 ) { + throw new AssertionError("Argument is out of range: " + n); + } + + return factorialPositive.apply(n); + }; + + // Return a BigInteger value + Function factorialBig = n -> Stream.iterate(BigInteger.ONE, i -> i.add(BigInteger.ONE)) + .limit(n) + .reduce(BigInteger.ONE, BigInteger::multiply); + } + +} diff --git a/Task/Factorial/M2000-Interpreter/factorial-2.m2000 b/Task/Factorial/M2000-Interpreter/factorial-2.m2000 index dc7940cef8..43a5d9ca37 100644 --- a/Task/Factorial/M2000-Interpreter/factorial-2.m2000 +++ b/Task/Factorial/M2000-Interpreter/factorial-2.m2000 @@ -9,19 +9,16 @@ Report { } Cls, row ' now we preserve some lines (as row number return here) Module CheckIt { - m=bigInteger("1") - with m, "tostring" as m.toString - k=width-tab - For i=1 to 1000 - if pos>tab then print - Print @(0), format$("{0::-4} :", i) ; - method m,"multiply", biginteger(i+"") as m - Report m.toString, k - ' Report stop at 2/3 of display lines, and wait mouse button or spacebar - ' we can flush the keyboard buffer and press space, so we get non stop display - ' Report didn't stop if we use the printer's layer. - while inkey$<>"": wait 1:end while - keyboard " " - Next i + m=1u ' 1u is biginteger + k=width-tab + For i=1 to 1000 + if pos>tab then print + m*=i + Print @(0), format$("{0::-4} :", i); + Report str$(m), k + ' Report accumulate lines and stop at 3/4 of the screen (but not on printer) + ' so we can break this using this line: + while inkey$<>"": wait 1:end while: keyboard " " + Next i } Checkit diff --git a/Task/Factorial/Pascal/factorial-2.pas b/Task/Factorial/Pascal/factorial-2.pas index 991914c559..6b44f23124 100644 --- a/Task/Factorial/Pascal/factorial-2.pas +++ b/Task/Factorial/Pascal/factorial-2.pas @@ -1,32 +1,45 @@ {$mode objFPC}{R+} -FUNCTION Factorial ( n : qword ) : qword; +FUNCTION Fact(n: qword): qword; - (*) - Update for version 3.2.0 - Factorial works until 20! , which is good enough for me for now - replace qword with dword and rax,rcx with eax, ecx for 32-bit - for Factorial until 12! - (*) +VAR + F: qword; - VAR - - F: qword; - - BEGIN +BEGIN + if n > 20 then + begin + WriteLn('This function is only accurate up to 20!'); + exit(0); + end; - asm - - mov $1, %rax - mov n, %rcx - - .Lloop1: - imul %rcx, %rax - loopnz .Lloop1 - - mov %rax, F + asm + (*) Initialize result = 1 (0! = 1 case handled automatically) (*) - end; + mov $1, %rax (*) RAX = 1 (initial result) (*) + mov n, %rcx (*) RCX = input number (counter) (*) - Result := F ; - - END; + test %rcx, %rcx (*) Check if n=0 (*) + jz .Lstore_result (*) Skip loop if n=0 (*) + + .Lloop1: + imul %rcx, %rax (*) RAX = RAX * RCX (signed mul) (*) + dec %rcx (*) Decrement RCX (*) + jnz .Lloop1 (*) Loop while RCX != 0 (*) + + .Lstore_result: + mov %rax, F (*) Store result in F (*) + end ['rax', 'rcx']; (*) Tell compiler register change (*) + + Result := F; + +END; + + +var + N : integer = 20 ; + +begin + + writeln; + writeln( BasicFact(N)); + +end. (*) Function Fact (*) diff --git a/Task/Factorial/Pascal/factorial-3.pas b/Task/Factorial/Pascal/factorial-3.pas index 64c4eabff6..137d0f6b28 100644 --- a/Task/Factorial/Pascal/factorial-3.pas +++ b/Task/Factorial/Pascal/factorial-3.pas @@ -1,92 +1,33 @@ -PROGRAM EXBigFac ; +program GMPfact; -{$IFDEF FPC} - {$mode objfpc}{$H+}{$J-}{R+} -{$ELSE} - {$APPTYPE CONSOLE} -{$ENDIF} +{$mode objfpc} -(*) +uses - Free Pascal Compiler version 3.2.0 [2020/06/14] for x86_64 - The free and readable alternative at C/C++ speeds - compiles natively to almost any platform, including raspberry PI * - Can run independently from DELPHI / Lazarus + gmp + ; - For debian Linux: apt -y install fpc - It contains a text IDE called fp + function Factorial(n: qword): string; + var + ResultMPZ: mpz_t; + i: qword; + begin + mpz_init_set_ui(ResultMPZ, 1); + for i := 2 to n do + mpz_mul_ui(ResultMPZ, ResultMPZ, i); + Result := mpz_get_str(nil, 10, ResultMPZ); + mpz_clear(ResultMPZ); + end; - https://www.freepascal.org/advantage.var +var + N : integer = 101 ; + Fact : string ; -(*) +begin + Fact := Factorial(101); + writeln( N ,'! = ', Fact); +end. (*) GMPfact (*) -USES - - gmp; - - FUNCTION WriteBigNum ( c: pchar ) : ansistring ; - - CONST - - CrLf = #13 + #10 ; - - VAR - i: longint; - len: longint; - preview: integer; - ret: ansistring = ''; - threshold: integer; - - BEGIN - - len := length ( c ) ; - WriteLn ( 'Digits: ', len ) ; - threshold := 12 ; - preview := len div threshold ; - - IF ( len < 91 ) THEN - BEGIN - FOR i := 0 TO len DO - ret:= ret + c [ i ] ; - END - ELSE - BEGIN - FOR i := 0 TO preview DO - ret:= ret + c [ i ] ; - ret:= ret + '...' ; - FOR i := len - preview -1 TO len DO - ret:= ret + c [ i ] ; - END; - ret:= ret + CrLf ; - WriteBigNum := ret; - END; - - FUNCTION BigFactorial ( n : qword ) : ansistring ; - - (*) - See https://gmplib.org/#DOC - (*) - - VAR - S: mpz_t; - c: pchar; - - BEGIN - - mpz_init_set_ui ( S, 1 ) ; - mpz_fac_ui ( S, n ) ; - c := mpz_get_str ( NIL, 10, S ) ; - BigFactorial := WriteBigNum ( c ) ; - - END; - -BEGIN - - WriteLn ( BigFactorial ( 99 ) ) ; - -END. - Output: -Digits: 156 -93326215443944...00000000000000 +101! = 9425947759838359420851623124482936749562312794702543768327889353416977599316221476503087861591808346911623490003549599583369706302603264000000000000000000000000 diff --git a/Task/Factorial/REXX/factorial-1.rexx b/Task/Factorial/REXX/factorial-1.rexx index b02528c706..4ab115dc32 100644 --- a/Task/Factorial/REXX/factorial-1.rexx +++ b/Task/Factorial/REXX/factorial-1.rexx @@ -1,18 +1,4 @@ -/*REXX pgm computes & shows the factorial of a non─negative integer, and also its length*/ -numeric digits 100000 /*100k digits: handles N up to 25k.*/ -parse arg n /*obtain optional argument from the CL.*/ -if n='' then call er 'no argument specified.' -if arg()>1 | words(n)>1 then call er 'too many arguments specified.' -if \datatype(n,'N') then call er "argument isn't numeric: " n -if \datatype(n,'W') then call er "argument isn't a whole number: " n -if n<0 then call er "argument can't be negative: " n -!= 1 /*define the factorial product (so far)*/ - do j=2 to n; !=!*j /*compute the factorial the hard way. */ - end /*j*/ /* [↑] where da rubber meets da road. */ - -say n'! is ['length(!) "digits]:" /*display number of digits in factorial*/ -say /*add some whitespace to the output. */ -say ! /*display the factorial product──►term.*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -er: say; say '***error***'; say; say arg(1); say; exit 13 +call time('r') +numeric digits 999999999 +a = 10/3 +say length(a) time('e') diff --git a/Task/Factorial/REXX/factorial-2.rexx b/Task/Factorial/REXX/factorial-2.rexx index 0ce1aa0e4d..01e564d9d2 100644 --- a/Task/Factorial/REXX/factorial-2.rexx +++ b/Task/Factorial/REXX/factorial-2.rexx @@ -1,22 +1,69 @@ -/*REXX program computes the factorial of a non─negative integer, and it automatically */ -/*────────────────────── adjusts the number of decimal digits to accommodate the answer.*/ -numeric digits 99 /*99 digits initially, then expanded. */ -parse arg n /*obtain optional argument from the CL.*/ -if n='' then call er 'no argument specified' -if arg()>1 | words(n)>1 then call er 'too many arguments specified.' -if \datatype(n,'N') then call er "argument isn't numeric: " n -if \datatype(n,'W') then call er "argument isn't a whole number: " n -if n<0 then call er "argument can't be negative: " n -!= 1 /*define the factorial product (so far)*/ - do j=2 to n; !=!*j /*compute the factorial the hard way. */ - if pos(.,!)==0 then iterate /*is the ! in exponential notation? */ - parse var ! 'E' digs /*extract exponent of the factorial, */ - numeric digits digs + digs % 10 /* ··· and increase it by ten percent.*/ - end /*j*/ /* [↑] where da rubber meets da road. */ -!= !/1 /*normalize the factorial product. */ -say n'! is ['length(!) "digits]:" /*display number of digits in factorial*/ -say /*add some whitespace to the output. */ -say ! /*display the factorial product ──►term*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -er: say; say '***error!***'; say; say arg(1); say; exit 13 +-- 8 May 2025 +include Settings + +say 'FACTORIAL' +say version +say +call First20 +call Imp 10,'1 10 100 1000 10000 100000 1000000 10000000 100000000 130202808' +call Rec 10,'1 10 100 1000 10000 100000 200000' +call Imp 100,'69' +call Imp 1000,'449' +call Imp 10000,'3248' +call Imp 100000,'25205' +exit + +First20: +say 'First 20 factorials...' +numeric digits 30 +do n = 1 to 20 + say n'! =' Fact(n) +end +say +return + +Imp: +glob. = '' +call Time('r') +arg d,p +numeric digits d; fact. = 0 +say 'Imperative in' d 'digits precision...' +do i = 1 to Words(p) + call Time('r'); f = Word(p,i); h = Fact(f) + parse var h 'E' e + if e = '' then + say right(f'!',10) 'has exact' right(Length(h),9) 'digits' '('Format(Time('e'),,3)'s)' + else + say right(f'!',10) 'has about' right(e+1,9) 'digits' '('Format(Time('e'),,3)'s)' +end +say +return + +Rec: +glob. = '' +call Time('r') +arg d,p +numeric digits d; fact. = 0 +say 'Recursive in' d 'digits precision...' +do i = 1 to Words(p) + call Time('r'); f = Word(p,i); h = Recursive(f) + parse var h 'E' e + if e = '' then + say right(f'!',10) 'has exact' right(Length(h),9) 'digits' '('Format(Time('e'),,3)'s)' + else + say right(f'!',10) 'has about' right(e+1,9) 'digits' '('Format(Time('e'),,3)'s)' +end +say +return + +Recursive: +procedure +arg xx +if xx = 0 then + return 1 +else + return xx*Recursive(xx-1) + +include Functions +include Special +include Abend diff --git a/Task/Factorial/REXX/factorial-3.rexx b/Task/Factorial/REXX/factorial-3.rexx deleted file mode 100644 index f9f6da4455..0000000000 --- a/Task/Factorial/REXX/factorial-3.rexx +++ /dev/null @@ -1,27 +0,0 @@ -/*REXX program computes & shows the factorial of an integer, striping trailing zeroes. */ -numeric digits 200 /*start with two hundred digits. */ -parse arg N . /*obtain an optional argument from CL. */ -if N=='' | N=="," then N= 0 /*Not specified? Then use the default.*/ -!= 1 /*define the factorial product so far. */ - do j=2 to N /*compute factorial the hard way. */ - old!= ! /*save old product in case of overflow.*/ - != ! * j /*multiple the old factorial with J. */ - if pos(.,!) \==0 then do /*is the ! in exponential notation?*/ - d= digits() /*D temporarily stores number digits.*/ - numeric digits d+d%10 /*add 10% to the decimal digits. */ - != old! * j /*re─calculate for the "lost" digits.*/ - end /*IFF ≡ if and only if. [↓] */ - parse var ! '' -1 _ /*obtain the right-most digit of ! */ - if _==0 then != strip(!, , 0) /*strip trailing zeroes IFF the ... */ - end /*j*/ /* [↑] ... right-most digit is zero. */ -z= 0 /*the number of trailing zeroes in ! */ - do v=5 by 0 while v<=N /*calculate number of trailing zeroes. */ - z= z + N % v /*bump Z if multiple power of five.*/ - v= v * 5 /*calculate the next power of five. */ - end /*v*/ /* [↑] we only advance V by ourself.*/ - /*stick a fork in it, we're all done. */ -!= ! || copies(0, z) /*add water to rehydrate the product. */ -if z==0 then z= 'no' /*use gooder English for the message. */ -say N'! is ['length(!) " digits with " z ' trailing zeroes]:' -say /*display blank line (for whitespace).*/ -say ! /*display the factorial product. */ diff --git a/Task/Factorial/REXX/factorial-4.rexx b/Task/Factorial/REXX/factorial-4.rexx deleted file mode 100644 index 4ab115dc32..0000000000 --- a/Task/Factorial/REXX/factorial-4.rexx +++ /dev/null @@ -1,4 +0,0 @@ -call time('r') -numeric digits 999999999 -a = 10/3 -say length(a) time('e') diff --git a/Task/Factorial/REXX/factorial-5.rexx b/Task/Factorial/REXX/factorial-5.rexx deleted file mode 100644 index 239ba782bb..0000000000 --- a/Task/Factorial/REXX/factorial-5.rexx +++ /dev/null @@ -1,67 +0,0 @@ -include Settings - -say version; say 'Factorial'; say -p = '10 20 52 104 208 416 1e3 1e4 1e5 1e6 1e7 1e8' -call Val 100 -p = '10 20 52 104 208 416 1e3 1e4 1e5 1e6' -call Dig 100 -call Dig 1000 -call Dig 3000 -p = '10 20 52 104 208 416 1e3 1e4 1e5' -call Dig 40000 -call Dig 500000 -p = '10 20 52 104 208 416 1e3 1e4' -call Dig 5000000 -exit - -Val: -call Time('r') -arg d -numeric digits d; fact. = 0 -say 'Precision is' d 'digits' -do i = 1 to Words(p) - call Time('r');f = Word(p,i); say f'!' '=' Fact(f) '('Format(Time('e'),,3)'s)' -end -say -return - -Dig: -call Time('r') -arg d -numeric digits d; fact. = 0 -say 'Precision is' d 'digits' -do i = 1 to Words(p) - call Time('r'); f = Word(p,i); h = Fact(f) - parse var h 'E' e - if e = '' then - say f'!' 'has exact' Length(h) 'digits' '('Format(Time('e'),,3)'s)' - else - say f'!' 'has about' e+1 'digits' '('Format(Time('e'),,3)'s)' -end -say -return - -Fact: -/* Factorial = n! */ -procedure expose fact. -arg x -/* Current in memory? */ -if fact.factorial.x <> 0 then - return fact.factorial.x -/* Previous in memory? */ -w = x-1 -if fact.factorial.w = 0 then do -/* Loop cf definition */ - y = 1 - do n = 2 to x - y = y*n - end - fact.factorial.x = y -end -else -/* Multiply */ - fact.factorial.x = fact.factorial.w*x -return fact.factorial.x - -include Functions -include Abend diff --git a/Task/Factorial/SQL/factorial.sql b/Task/Factorial/SQL/factorial.sql new file mode 100644 index 0000000000..c0b412e4a3 --- /dev/null +++ b/Task/Factorial/SQL/factorial.sql @@ -0,0 +1,6 @@ +WITH RECURSIVE f(a, b) AS ( + VALUES(1, 1) + UNION ALL + SELECT a * b, b + 1 FROM f WHERE b <= 9 +) +SELECT MAX(a) FROM f diff --git a/Task/Factorial/Tcl/factorial-1.tcl b/Task/Factorial/Tcl/factorial-1.tcl index 8220088fdf..a204184466 100644 --- a/Task/Factorial/Tcl/factorial-1.tcl +++ b/Task/Factorial/Tcl/factorial-1.tcl @@ -1,6 +1,12 @@ -proc ifact n { - for {set i $n; set sum 1} {$i >= 2} {incr i -1} { - set sum [expr {$sum * $i}] +# tailcall optimization is standard in tcl8.6 +proc fact { n { result 1. } } { + if { $n <= 1 } { + return $result + } else { + tailcall fact [expr {$n-1}] [expr {$n*$result}] } - return $sum } + +set f [fact 10] + +puts $f diff --git a/Task/Factorial/Tcl/factorial-2.tcl b/Task/Factorial/Tcl/factorial-2.tcl index 40cc360692..8220088fdf 100644 --- a/Task/Factorial/Tcl/factorial-2.tcl +++ b/Task/Factorial/Tcl/factorial-2.tcl @@ -1,3 +1,6 @@ -proc rfact n { - expr {$n < 2 ? 1 : $n * [rfact [incr n -1]]} +proc ifact n { + for {set i $n; set sum 1} {$i >= 2} {incr i -1} { + set sum [expr {$sum * $i}] + } + return $sum } diff --git a/Task/Factorial/Tcl/factorial-3.tcl b/Task/Factorial/Tcl/factorial-3.tcl index e25b3f18c7..40cc360692 100644 --- a/Task/Factorial/Tcl/factorial-3.tcl +++ b/Task/Factorial/Tcl/factorial-3.tcl @@ -1 +1,3 @@ -proc tcl::mathfunc::fact n {expr {$n < 2? 1: $n*fact($n-1)}} +proc rfact n { + expr {$n < 2 ? 1 : $n * [rfact [incr n -1]]} +} diff --git a/Task/Factorial/Tcl/factorial-4.tcl b/Task/Factorial/Tcl/factorial-4.tcl index 9a9a02de85..e25b3f18c7 100644 --- a/Task/Factorial/Tcl/factorial-4.tcl +++ b/Task/Factorial/Tcl/factorial-4.tcl @@ -1,17 +1 @@ -proc ifact_caching n { - global fact_cache - if { ! [info exists fact_cache]} { - set fact_cache {1 1} - } - if {$n < [llength $fact_cache]} { - return [lindex $fact_cache $n] - } - set i [expr {[llength $fact_cache] - 1}] - set sum [lindex $fact_cache $i] - while {$i < $n} { - incr i - set sum [expr {$sum * $i}] - lappend fact_cache $sum - } - return $sum -} +proc tcl::mathfunc::fact n {expr {$n < 2? 1: $n*fact($n-1)}} diff --git a/Task/Factorial/Tcl/factorial-5.tcl b/Task/Factorial/Tcl/factorial-5.tcl index ecdfbe5752..9a9a02de85 100644 --- a/Task/Factorial/Tcl/factorial-5.tcl +++ b/Task/Factorial/Tcl/factorial-5.tcl @@ -1,11 +1,17 @@ -puts [ifact 30] -puts [rfact 30] -puts [ifact_caching 30] - -set n 400 -set iterations 10000 -puts "calculate $n factorial $iterations times" -puts "ifact: [time {ifact $n} $iterations]" -puts "rfact: [time {rfact $n} $iterations]" -# for the caching proc, reset the cache between each iteration so as not to skew the results -puts "ifact_caching: [time {ifact_caching $n; unset -nocomplain fact_cache} $iterations]" +proc ifact_caching n { + global fact_cache + if { ! [info exists fact_cache]} { + set fact_cache {1 1} + } + if {$n < [llength $fact_cache]} { + return [lindex $fact_cache $n] + } + set i [expr {[llength $fact_cache] - 1}] + set sum [lindex $fact_cache $i] + while {$i < $n} { + incr i + set sum [expr {$sum * $i}] + lappend fact_cache $sum + } + return $sum +} diff --git a/Task/Factorial/Tcl/factorial-6.tcl b/Task/Factorial/Tcl/factorial-6.tcl index 46e5e0fcab..ecdfbe5752 100644 --- a/Task/Factorial/Tcl/factorial-6.tcl +++ b/Task/Factorial/Tcl/factorial-6.tcl @@ -1,5 +1,11 @@ -package require math::special +puts [ifact 30] +puts [rfact 30] +puts [ifact_caching 30] -proc gfact n { - expr {round([::math::special::Gamma [expr {$n+1}]])} -} +set n 400 +set iterations 10000 +puts "calculate $n factorial $iterations times" +puts "ifact: [time {ifact $n} $iterations]" +puts "rfact: [time {rfact $n} $iterations]" +# for the caching proc, reset the cache between each iteration so as not to skew the results +puts "ifact_caching: [time {ifact_caching $n; unset -nocomplain fact_cache} $iterations]" diff --git a/Task/Factorial/Tcl/factorial-7.tcl b/Task/Factorial/Tcl/factorial-7.tcl new file mode 100644 index 0000000000..46e5e0fcab --- /dev/null +++ b/Task/Factorial/Tcl/factorial-7.tcl @@ -0,0 +1,5 @@ +package require math::special + +proc gfact n { + expr {round([::math::special::Gamma [expr {$n+1}]])} +} diff --git a/Task/Factorial/Uxntal/factorial.uxnatl b/Task/Factorial/Uxntal/factorial.uxnatl index 6ce1360a76..f936013ac4 100644 --- a/Task/Factorial/Uxntal/factorial.uxnatl +++ b/Task/Factorial/Uxntal/factorial.uxnatl @@ -1,4 +1,28 @@ -@factorial ( n* -: fact* ) +%newline { [ LIT2 0a -Console/write ] DEO } + +|18 @Console/write + +|100 + +#0900 +&loop + DUP #00 SWP factorial print/dec newline + INC GTHk ?&loop +POP2 + +BRK + +@factorial ( n* -- n!* ) ORAk ?{ POP2 #0001 JMP2r } DUP2 #0001 SUB2 factorial MUL2 -JMP2r + JMP2r + +@print/dec ( short* -- ) + #000a SWP2 [ LITr ff ] + &get ( -- ) + SWP2k DIV2k MUL2 SUB2 STH + POP OVR2 DIV2 ORAk ?&get + POP2 POP2 + &put ( -- ) + STHr INCk ?{ POP JMP2r } + [ LIT "0 ] ADD .Console/write DEO !&put diff --git a/Task/Factorions/EasyLang/factorions.easy b/Task/Factorions/EasyLang/factorions.easy new file mode 100644 index 0000000000..0e6f41446e --- /dev/null +++ b/Task/Factorions/EasyLang/factorions.easy @@ -0,0 +1,21 @@ +len fact[] 12 +arrbase fact[] 0 +# +fact[0] = 1 +for n = 1 to 11 + fact[n] = fact[n - 1] * n +. +for b = 9 to 12 + write "base " & b & " factorions:" + for i = 1 to 1500000 - 1 + sum = 0 + j = i + while j > 0 + d = j mod b + sum += fact[d] + j = j div b + . + if sum = i : write " " & i + . + print "" +. diff --git a/Task/Factorions/R/factorions.r b/Task/Factorions/R/factorions.r new file mode 100644 index 0000000000..7922c0c7b6 --- /dev/null +++ b/Task/Factorions/R/factorions.r @@ -0,0 +1,15 @@ +fact_digsum <- function(n, b){ + if(n>b-1){ + return(factorial(n%%b)+fact_digsum(n%/%b, b)) + } + else return(factorial(n)) +} + +for(i in 9:12){ + cat("Factorions in base",i,"\n") + for(j in 1:1499999){ + if(j==fact_digsum(j, i)){ + print(j) + } + } +} diff --git a/Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number-1.rexx b/Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number-1.rexx deleted file mode 100644 index d575fd9097..0000000000 --- a/Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number-1.rexx +++ /dev/null @@ -1,53 +0,0 @@ -/*REXX program uses exponent─and─mod operator to test possible Mersenne numbers. */ -numeric digits 20 /*this will be increased if necessary. */ -parse arg N spec /*obtain optional arguments from the CL*/ -if N=='' | N=="," then N= 88 /*Not specified? Then use the default.*/ -if spec=='' | spec=="," then spec= 920 970 /* " " " " " " */ - do j=1; z= j /*process a range, & then do some more.*/ - if j==N then j= word(spec, 1) /*now, use the high range of numbers. */ - if j>word(spec, 2) then leave /*done with " " " " " */ - if \isPrime(z) then iterate /*if Z isn't a prime, keep plugging.*/ - r= commas( testMer(z) ); L= length(r) /*add commas; get its new length. */ - if r==0 then say right('M'z, 10) "──────── is a Mersenne prime." - else say right('M'z, 50) "is composite, a factor:"right(r, max(L, 13) ) - end /*j*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure; parse arg x; if wordpos(x, '2 3 5 7') \== 0 then return 1 - if x<11 then return 0; if x//2 == 0 | x//3 == 0 then return 0 - do j=5 by 6; if x//j == 0 | x//(j+2) == 0 then return 0 - if j*j>x then return 1 /*◄─┐ ___ */ - end /*j*/ /* └─◄ Is j>√ x ? Then return 1*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -iSqrt: procedure; parse arg x; #= 1; r= 0; do while #<=x; #= # * 4 - end /*while*/ - do while #>1; #= # % 4; _= x-r-#; r= r % 2 - if _>=0 then do; x= _; r= r + # - end - end /*while*/ /*iSqrt ≡ integer square root.*/ - return r /*───── ─ ── ─ ─ */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -testMer: procedure; parse arg x; p= 2**x /* [↓] do we have enough digits?*/ - $$=x2b( d2x(x) ) + 0 - if pos('E',p)\==0 then do; parse var p "E" _; numeric digits _ + 2; p= 2**x - end - !.= 1; !.1= 0; !.7= 0 /*array used for a quicker test. */ - R= iSqrt(p) /*obtain integer square root of P*/ - do k=2 by 2; q= k*x + 1 /*(shortcut) compute value of Q. */ - m= q // 8 /*obtain the remainder when ÷ 8. */ - if !.m then iterate /*M must be either one or seven.*/ - parse var q '' -1 _; if _==5 then iterate /*last digit a five ? */ - if q// 3==0 then iterate /*divisible by three? */ - if q// 7==0 then iterate /* " " seven? */ - if q//11==0 then iterate /* " " eleven?*/ - /* ____ */ - if q>R then return 0 /*Is q>√2**x ? A Mersenne prime*/ - sq= 1; $= $$ /*obtain binary version from $. */ - do until $==''; sq= sq*sq - parse var $ _ 2 $ /*obtain 1st digit and the rest. */ - if _ then sq= (sq+sq) // q - end /*until*/ - if sq==1 then return q /*Not a prime? Return a factor.*/ - end /*k*/ diff --git a/Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number-2.rexx b/Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number.rexx similarity index 72% rename from Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number-2.rexx rename to Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number.rexx index 0c9b756a9b..31536d9a38 100644 --- a/Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number-2.rexx +++ b/Task/Factors-of-a-Mersenne-number/REXX/factors-of-a-mersenne-number.rexx @@ -1,11 +1,13 @@ +-- 22 Mar 2025 include Settings -say 'Factor of a Mersenne Number - Using REXX libraries' -parse version version; say version; say -call Time('r') + +say 'FACTORS OF A MERSENNE NUMBER' +say version +say numeric digits 300 n = Primes(1000) do i = 1 to n - x = prim.Prime.i + x = prim.i select when (x >= 2 & x <= 83) then call Task x @@ -15,7 +17,7 @@ do i = 1 to n nop end end -say; say Format(Time('e'),,3) 'seconds'; say +say; say Format(Time('e'),,3) 'seconds' exit Task: @@ -33,13 +35,13 @@ do k = 1 by 2*x to Isqrt(m) iterate k c = m//k if c = 1 then do - say a 'is Composite =' k 'x ...' + say a 'is composite =' k 'x ...' leave k end end end if c <> 1 then - say a 'is Prime' + say a 'is prime' return include Functions diff --git a/Task/Factors-of-an-integer/EasyLang/factors-of-an-integer.easy b/Task/Factors-of-an-integer/EasyLang/factors-of-an-integer.easy index 493a738a49..ff13ddc639 100644 --- a/Task/Factors-of-an-integer/EasyLang/factors-of-an-integer.easy +++ b/Task/Factors-of-an-integer/EasyLang/factors-of-an-integer.easy @@ -1,7 +1,8 @@ -n = 720 -for i = 1 to n - if n mod i = 0 - factors[] &= i - . +func[] factors n . + for i = 1 to n + if n mod i = 0 : f[] &= i + . + return f[] . -print factors[] +print factors 10 +print factors 720 diff --git a/Task/Factors-of-an-integer/REXX/factors-of-an-integer-1.rexx b/Task/Factors-of-an-integer/REXX/factors-of-an-integer-1.rexx index 7f2c60a2ca..4e743184e1 100644 --- a/Task/Factors-of-an-integer/REXX/factors-of-an-integer-1.rexx +++ b/Task/Factors-of-an-integer/REXX/factors-of-an-integer-1.rexx @@ -1,29 +1,32 @@ -/*REXX program displays divisors of any [negative/zero/positive] integer or a range.*/ -parse arg LO HI inc . /*obtain the optional args*/ -HI= word(HI LO 20, 1); LO= word(LO 1,1); inc= word(inc 1,1) /*define the range options*/ -w= length(HI) + 2; numeric digits max(9, w-2); != '∞' /*decimal digits for // */ -@.=left('',7); @.1= "{unity}"; @.2= '[prime]'; @.!= " {∞} " /*define some literals. */ -say center('n', w) "#divisors" center('divisors', 60) /*display the header. */ -say copies('═', w) "═════════" copies('═' , 60) /* " " separator. */ -pn= 0 /*count of prime numbers. */ - do k=2 until sq.k>=HI; sq.k= k*k /*memoization for squares.*/ - end /*k*/ - do n=LO to HI by inc; $= divs(n); #= words($) /*get list of divs; # divs*/ - if $==! then do; #= !; $= ' (infinite)'; end /*handle case for infinity*/ - p= @.#; if n<0 then if n\==-1 then p= @.. /* " " " negative*/ - if p==@.2 then pn= pn + 1 /*Prime? Then bump counter*/ - say center(n, w) center('['#"]", 9) "──► " p ' ' $ - end /*n*/ /* [↑] process a range of integers. */ -say -say right(pn, 20) ' primes were found.' /*display the number of primes found. */ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -divs: procedure expose sq.; parse arg x 1 b; a=1 /*set X and B to the 1st argument. */ - if x<2 then do; x= abs(x); if x==1 then return 1; if x==0 then return '∞'; b=x - end - odd= x // 2 /* [↓] process EVEN or ODD ints. ___*/ - do j=2+odd by 1+odd while sq.j= 0 { return s; } + return "-" + s; +} + +public function main() { + // task 1. solution by recursive generation of mediants + foreach int n in 1...11 { + frac l = new(0, 1); + frac r = new(1, 1); + io:print(`F(${n}): ${l} `); + f(l, r, n); + io:println(r); + } + io:println(); + + // task 2. direct solution by summing totient function + // 2.1 generate primes to 1000 + boolean[1001] composite = []; + foreach int p in [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31] { + foreach int n in int:range(p * 2, 1001, p) { composite[n] = true; } + } + + // 2.2 generate totients to 1000 + int[1001] tot = []; + foreach int i in 0...1000 { tot[i] = 1; } + foreach int n in 2...1000 { + if !composite[n] { + tot[n] = n - 1; + foreach int a in int:range(n * 2, 1001, n) { + int f = n - 1; + int r = a / n; + while r % n == 0 { + f *= n; + r /= n; + } + tot[a] *= f; + } + } + } + + // sum totients + int sum = 1; + foreach int n in 1...1000 { + sum += tot[n]; + if n % 100 == 0 { + string s1 = n.toString().padStart(4); + string s2 = commatize(sum).padStart(7); + io:println(`F(${s1}): ${s2}`); + } + } +} diff --git a/Task/Farey-sequence/EasyLang/farey-sequence.easy b/Task/Farey-sequence/EasyLang/farey-sequence.easy index a16f529e1c..602f6ec0e8 100644 --- a/Task/Farey-sequence/EasyLang/farey-sequence.easy +++ b/Task/Farey-sequence/EasyLang/farey-sequence.easy @@ -1,5 +1,7 @@ -proc farey n . . - b = 1 ; c = 1 ; d = n +proc farey n . + b = 1 + c = 1 + d = n write n & ": " repeat if n <= 11 diff --git a/Task/Fast-Fourier-transform/EasyLang/fast-fourier-transform.easy b/Task/Fast-Fourier-transform/EasyLang/fast-fourier-transform.easy index e5fc7b7705..4b6e1acb26 100644 --- a/Task/Fast-Fourier-transform/EasyLang/fast-fourier-transform.easy +++ b/Task/Fast-Fourier-transform/EasyLang/fast-fourier-transform.easy @@ -15,7 +15,7 @@ func[] cexp a[] . func cabs a[] . return sqrt (a[1] * a[1] + a[2] * a[2]) . -proc fft x[] . y[][] . +proc fft x[] &y[][] . n = len x[] if n = 1 y[][] = [ [ x[1] 0 ] ] diff --git a/Task/Faulhabers-formula/C/faulhabers-formula.c b/Task/Faulhabers-formula/C/faulhabers-formula.c index 12955f4db8..0388b37b1b 100644 --- a/Task/Faulhabers-formula/C/faulhabers-formula.c +++ b/Task/Faulhabers-formula/C/faulhabers-formula.c @@ -1,169 +1,121 @@ -#include -#include +#include #include +#include +#include +typedef unsigned long ul; +#define mpq_for(buf, op, n)\ +do {\ + size_t i;\ + for (i = 0; i < (n); ++i)\ + mpq_##op(buf[i]);\ +} while (0) -int binomial(int n, int k) { - int num, denom, i; - - if (n < 0 || k < 0 || n < k) return -1; - if (n == 0 || k == 0) return 1; - - num = 1; - for (i = k + 1; i <= n; ++i) { - num = num * i; +void mpz_choose_ui(mpz_t rop,ul a,ul b){ + mpz_set_ui(rop,1); + for(ul i=0;i 1) { - n = n / g; - d = d / g; - } - - result.num = n; - result.denom = d; - return result; -} - -Frac negateFrac(Frac f) { - return makeFrac(-f.num, f.denom); -} - -Frac subFrac(Frac lhs, Frac rhs) { - return makeFrac(lhs.num * rhs.denom - lhs.denom * rhs.num, rhs.denom * lhs.denom); -} - -Frac multFrac(Frac lhs, Frac rhs) { - return makeFrac(lhs.num * rhs.num, lhs.denom * rhs.denom); -} - -bool equalFrac(Frac lhs, Frac rhs) { - return (lhs.num == rhs.num) && (lhs.denom == rhs.denom); -} - -bool lessFrac(Frac lhs, Frac rhs) { - return (lhs.num * rhs.denom) < (rhs.num * lhs.denom); -} - -void printFrac(Frac f) { - printf("%d", f.num); - if (f.denom != 1) { - printf("/%d", f.denom); + for(ul i=1;i<=b;i++){ + mpz_div_ui(rop,rop,i); } } - -Frac bernoulli(int n) { - Frac a[16]; - int j, m; - - if (n < 0) { - a[0].num = 0; - a[0].denom = 0; - return a[0]; - } +void bernoulli(mpq_t rop, unsigned int n){ + unsigned int m, j; + mpq_t *a = malloc(sizeof(mpq_t) * (n + 1)); + mpq_for(a, init, n + 1); for (m = 0; m <= n; ++m) { - a[m] = makeFrac(1, m + 1); - for (j = m; j >= 1; --j) { - a[j - 1] = multFrac(subFrac(a[j - 1], a[j]), makeFrac(j, 1)); + mpq_set_ui(a[m], 1, m + 1); + for (j = m; j > 0; --j) { + mpq_sub(a[j-1], a[j], a[j-1]); + mpq_set_ui(rop, j, 1); + mpq_mul(a[j-1], a[j-1], rop); } } - if (n != 1) { - return a[0]; - } - - return negateFrac(a[0]); + mpq_set(rop, a[0]); + mpq_for(a, clear, n + 1); + free(a); +} +void bernoullip(mpq_t rop,unsigned int n){ + bernoulli(rop,n); + if(n!=1){return;} + mpq_neg(rop,rop); + return; } -void faulhaber(int p) { - Frac coeff, q; - int j, pwr, sign; +void mpq_print(mpq_t rop){ + mpz_t n,d; + mpz_inits(n,d,NULL); + mpq_get_num(n, rop); + mpq_get_den(d, rop); + gmp_printf("%Zd/%Zd\n", n, d); + mpz_clears(n,d,NULL); +} +void mpz_print(mpz_t rop){ - printf("%d : ", p); - q = makeFrac(1, p + 1); - sign = -1; - for (j = 0; j <= p; ++j) { - sign = -1 * sign; - coeff = multFrac(multFrac(multFrac(q, makeFrac(sign, 1)), makeFrac(binomial(p + 1, j), 1)), bernoulli(j)); - if (equalFrac(coeff, makeFrac(0, 1))) { - continue; - } - if (j == 0) { - if (!equalFrac(coeff, makeFrac(1, 1))) { - if (equalFrac(coeff, makeFrac(-1, 1))) { - printf("-"); - } else { - printFrac(coeff); - } - } - } else { - if (equalFrac(coeff, makeFrac(1, 1))) { - printf(" + "); - } else if (equalFrac(coeff, makeFrac(-1, 1))) { - printf(" - "); - } else if (lessFrac(makeFrac(0, 1), coeff)) { - printf(" + "); - printFrac(coeff); - } else { - printf(" - "); - printFrac(negateFrac(coeff)); - } - } - pwr = p + 1 - j; - if (pwr > 1) { - printf("n^%d", pwr); - } else { - printf("n"); - } - } - printf("\n"); + gmp_printf("%Zd\n",rop); +} +void mpq_div_ui(mpq_t op1,mpq_t op2,ul op3){ + mpq_t tmp; + mpq_init(tmp); + mpq_set_ui(tmp,op3,1); + mpq_div(op1,op2,tmp); + mpq_clear(tmp); } -int main() { - int i; - - for (i = 0; i < 10; ++i) { - faulhaber(i); +void mpq_mul_z(mpq_t op1,mpq_t op2,mpz_t op3){ + mpq_t tmp; + mpq_init(tmp); + mpq_set_z(tmp,op3); + mpq_mul(op1,op2,tmp); + mpq_clear(tmp); +} +void mpq_to_mpz(mpz_t rop,mpq_t op){ + mpz_t tmp; + mpz_init(tmp); + mpq_get_num(rop,op); + mpq_get_den(tmp,op); + if(mpz_cmp_ui(tmp,1)!=0){ + mpz_div(rop,rop,tmp); } - + mpz_clear(tmp); +} +void faulhaber(mpq_t out,ul n,ul p){ + mpq_t tmp; + mpz_t tmp2,tmp3; + mpq_init(tmp); + mpz_inits(tmp2,tmp3,NULL); + mpq_clear(out); + mpq_init(out); + for(ul r=0;r Self { + if d == 0 { + panic!("d must not be zero"); + } + + let mut nn = n; + let mut dd = d; + + if nn == 0 { + dd = 1; + } else if dd < 0 { + nn = -nn; + dd = -dd; + } + + let g = gcd(nn.abs(), dd.abs()); + if g > 1 { + nn /= g; + dd /= g; + } + + Frac { num: nn, denom: dd } + } + + fn zero() -> Self { + Frac::new(0, 1) + } + + fn one() -> Self { + Frac::new(1, 1) + } +} + +impl Neg for Frac { + type Output = Self; + + fn neg(self) -> Self { + Frac::new(-self.num, self.denom) + } +} + +impl Add for Frac { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Frac::new( + self.num * rhs.denom + self.denom * rhs.num, + rhs.denom * self.denom, + ) + } +} + +impl Sub for Frac { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + Frac::new( + self.num * rhs.denom - self.denom * rhs.num, + rhs.denom * self.denom, + ) + } +} + +impl Mul for Frac { + type Output = Self; + + fn mul(self, rhs: Self) -> Self { + Frac::new(self.num * rhs.num, self.denom * rhs.denom) + } +} + +impl fmt::Display for Frac { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.num == 0 || self.denom == 1 { + write!(f, "{}", self.num) + } else { + write!(f, "{}/{}", self.num, self.denom) + } + } +} + +fn bernoulli(n: i32) -> Frac { + if n < 0 { + panic!("n may not be negative or zero"); + } + + let mut a: Vec = Vec::new(); + for m in 0..=n { + a.push(Frac::new(1, (m + 1) as i64)); + for j in (1..=m).rev() { + let j_usize = j as usize; + a[j_usize - 1] = (a[j_usize - 1] - a[j_usize]) * Frac::new(j as i64, 1); + } + } + + // returns 'first' Bernoulli number + if n != 1 { + a[0] + } else { + -a[0] + } +} + +fn binomial(n: i32, k: i32) -> i64 { + if n < 0 || k < 0 || n < k { + panic!("parameters are invalid"); + } + if n == 0 || k == 0 { + return 1; + } + + let mut num: i64 = 1; + for i in (k + 1)..=n { + num *= i as i64; + } + + let mut denom: i64 = 1; + for i in 2..=(n - k) { + denom *= i as i64; + } + + num / denom +} + +fn faulhaber(p: i32) { + print!("{} : ", p); + + let q = Frac::new(1, (p + 1) as i64); + let mut sign: i32 = -1; + for j in 0..=p { + sign *= -1; + let coeff = q * Frac::new(sign as i64, 1) * Frac::new(binomial(p + 1, j), 1) * bernoulli(j); + if coeff == Frac::zero() { + continue; + } + if j == 0 { + if coeff == -Frac::one() { + print!("-"); + } else if coeff != Frac::one() { + print!("{}", coeff); + } + } else { + if coeff == Frac::one() { + print!(" + "); + } else if coeff == -Frac::one() { + print!(" - "); + } else if coeff < Frac::zero() { + print!(" - {}", -coeff); + } else { + print!(" + {}", coeff); + } + } + let pwr = p + 1 - j; + if pwr > 1 { + print!("n^{}", pwr); + } else { + print!("n"); + } + } + println!(); +} + +fn main() { + for i in 0..10 { + faulhaber(i); + } +} diff --git a/Task/Feigenbaum-constant-calculation/EasyLang/feigenbaum-constant-calculation.easy b/Task/Feigenbaum-constant-calculation/EasyLang/feigenbaum-constant-calculation.easy index 3b826f30aa..4400fb17ab 100644 --- a/Task/Feigenbaum-constant-calculation/EasyLang/feigenbaum-constant-calculation.easy +++ b/Task/Feigenbaum-constant-calculation/EasyLang/feigenbaum-constant-calculation.easy @@ -1,10 +1,13 @@ -numfmt 6 0 -a1 = 1 ; a2 = 0 ; d1 = 3.2 +numfmt 0 6 +a1 = 1 +a2 = 0 +d1 = 3.2 ipow2 = 4 for i = 2 to 13 a = a1 + (a1 - a2) / d1 for j = 1 to 10 - x = 0 ; y = 0 + x = 0 + y = 0 for k = 1 to ipow2 y = 1 - 2 * y * x x = a - x * x diff --git a/Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation-1.rexx b/Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation-1.rexx deleted file mode 100644 index 480cb4ca72..0000000000 --- a/Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation-1.rexx +++ /dev/null @@ -1,33 +0,0 @@ -/*REXX pgm calculates the (Mitchell) Feigenbaum bifurcation velocity, #digs can be given*/ -parse arg digs maxi maxj . /*obtain optional argument from the CL.*/ -if digs=='' | digs=="," then digs= 30 /*Not specified? Then use the default.*/ -if maxi=='' | maxi=="," then maxi= 20 /* " " " " " " */ -if maxJ=='' | maxJ=="," then maxJ= 10 /* " " " " " " */ -#= 4.669201609102990671853203820466201617258185577475768632745651343004134330211314737138, - || 68974402394801381716 /*◄──Feigenbaum's constant, true value.*/ -numeric digits digs /*use the specified # of decimal digits*/ - a1= 1 - a2= 0 - d1= 3.2 -say 'Using ' maxJ " iterations for maxJ, with " digs ' decimal digits:' -say -say copies(' ', 9) center("correct", 11) copies(' ', digs+1) -say center('i', 9, "─") center('digits' , 11, "─") center('d', digs+1, "─") - - do i=2 for maxi-1 - a= a1 + (a1 - a2) / d1 - do maxJ - x= 0; y= 0 - do 2**i; y= 1 - 2 * x * y - x= a - x*x - end /*2**i*/ - a= a - x / y - end /*maxj*/ - d= (a1 - a2) / (a - a1) /*compute the delta (D) of the function*/ - t= max(0, compare(d, #) - 2) /*# true digs so far, ignore dec. point*/ - say center(i, 9) center(t, 11) d /*display values for I & D ──►terminal*/ - parse value d a1 a with d1 a2 a1 /*assign 3 variables with 3 new values.*/ - end /*i*/ - /*stick a fork in it, we're all done. */ -say left('', 9 + 1 + 11 + 1 + t )"↑" /*show position of greatest accuracy. */ -say ' true value= ' # / 1 /*true value of Feigenbaum's constant. */ diff --git a/Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation-2.rexx b/Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation.rexx similarity index 72% rename from Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation-2.rexx rename to Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation.rexx index 81e8fa6e36..f01041e76f 100644 --- a/Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation-2.rexx +++ b/Task/Feigenbaum-constant-calculation/REXX/feigenbaum-constant-calculation.rexx @@ -1,20 +1,20 @@ -arg n; if n = '' then n = 30; numeric digits n -parse version version; say version; glob. = '' -say 'First Fiegenbaum constant, correct to about 11 decimals' -say 'Using algorithm cf RosettaCode' +-- 8 May 2025 +say 'FIRST FEIGENBAUM CONSTANT' +say 'Using algorithm cf RosettaCode, correct to about 11 decimals' say -call time('r'); a = Original(); e = format(time('e'),,3) +arg n; if n = '' then n = 30; numeric digits n +call Time('r'); a = Original(); e = Format(Time('e'),,3) say 'Original ' a '('e 'seconds)' -call time('r'); a = Optimized(); e = format(time('e'),,3) +call Time('r'); a = Optimized(); e = Format(Time('e'),,3) say 'Optimized ' a '('e 'seconds)' -call time('r'); a = TrueValue(); e = format(time('e'),,3) +call Time('r'); a = TrueValue(); e = Format(Time('e'),,3) say 'True value' a '('e 'seconds)' exit Original: procedure expose glob. /* Outer 2 loops with a fixed value */ -numeric digits digits()+2 +numeric digits Digits()+2 im = 20; jm = 10 a1 = 1; a2 = 0; d1 = 3.2 do i = 2 to im @@ -29,13 +29,13 @@ do i = 2 to im d = (a1-a2) / (a-a1) parse value d a1 a with d1 a2 a1 end -numeric digits digits()-2 +numeric digits Digits()-2 return d+0 Optimized: procedure expose glob. /* Center loop stops on achieving desired accuracy */ -numeric digits digits()+4; numeric fuzz 4 +numeric digits Digits()+4; numeric fuzz 4 /* Only outer loop maximum */ im = 20 a1 = 1; a2 = 0; d1 = 3.2 @@ -54,8 +54,9 @@ do i = 2 to im end d = (a1-a2) / (a-a1) parse value d a1 a with d1 a2 a1 + say Format(i,2) Format(d,1,12) end -numeric digits digits()-4 +numeric digits Digits()-4 return d+0 TrueValue: diff --git a/Task/Fermat-numbers/FreeBASIC/fermat-numbers.basic b/Task/Fermat-numbers/FreeBASIC/fermat-numbers.basic new file mode 100644 index 0000000000..15eae8e495 --- /dev/null +++ b/Task/Fermat-numbers/FreeBASIC/fermat-numbers.basic @@ -0,0 +1,102 @@ +#include "big_int/big_integer.bi" + +Function Bigint_isPrime(Byval ValorEval As Bigint) As Boolean + If ValorEval < Bigint("2") Then Return False + If ValorEval Mod Bigint("2") = Bigint("0") Then Return (ValorEval = Bigint("2")) + If ValorEval Mod Bigint("3") = Bigint("0") Then Return (ValorEval = Bigint("3")) + + Dim As Bigint d = Bigint("5") + While d * d <= ValorEval + If ValorEval Mod d = Bigint("0") Then + Return False + Else + d += Bigint("2") + End If + Wend + + Return True +End Function + +Function Bigint_gcd(x As Bigint, y As Bigint) As Bigint + Dim As Bigint a = x, b = y + While b <> 0 + Dim As Bigint next_a = b + b = a Mod b + a = next_a + Wend + + Return a +End Function + +Function CalcularFermat(n As Integer) As Bigint + Dim As Bigint valorBase = Bigint("1") Shl (1 Shl n) + valorBase += Bigint("1") + + Return valorBase +End Function + +Function PollardsRho(n As Bigint) As Bigint + If (n Mod Bigint("2")) = Bigint("0") Then Return Bigint("2") + + Dim As Bigint x = Bigint("2"), y = Bigint("2"), d = Bigint("1") + Dim As Bigint c = Bigint("1") + + While d = Bigint("1") + x = (x * x + c) Mod n + y = (y * y + c) Mod n + y = (y * y + c) Mod n + d = Bigint_gcd(Abs(x - y), n) + Wend + + Return Iif(d = n, Bigint("0"), d) ' Avoid returning n as a factor +End Function + +' Factorización prima usando Pollard's Rho +Sub FactorizarPrimos(n As Bigint, factores() As Bigint) + If n = Bigint("1") Then Exit Sub + + If Bigint_isPrime(n) Then + Redim Preserve factores(Ubound(factores) + 1) + factores(Ubound(factores)) = n + Exit Sub + End If + + Dim As Bigint d = PollardsRho(n) + + ' If we couldn't factor it, we treated it as prime. + If d = Bigint("0") Then ' Fallback if Pollard finds no factors + Redim Preserve factores(Ubound(factores) + 1) + factores(Ubound(factores)) = n + Else + FactorizarPrimos(d, factores()) + FactorizarPrimos(n \ d, factores()) + End If +End Sub + +' Main program +Dim As Integer i, j +Dim As Bigint numFermat(0 To 9) + +Print "The first 10 Fermat numbers are:" +For i = 0 To 9 + numFermat(i) = CalcularFermat(i) + Print "F" & i & " = " & Str(numFermat(i)) +Next i + +Print !"\nFactors of the first 7 Fermat numbers:" +For i = 0 To 6 + Dim As Bigint factores() + FactorizarPrimos(numFermat(i), factores()) + + Dim As String salida = "[" + For j = Lbound(factores) To Ubound(factores) + salida &= Str(factores(j)) + If j < Ubound(factores) Then salida &= ", " + Next + salida &= "]" + If Ubound(factores) = Lbound(factores) Then salida &= " (prime)" + + Print "F" & i & " = " & salida +Next i + +Sleep diff --git a/Task/Fermat-numbers/REXX/fermat-numbers-1.rexx b/Task/Fermat-numbers/REXX/fermat-numbers-1.rexx deleted file mode 100644 index 69b5b9cd55..0000000000 --- a/Task/Fermat-numbers/REXX/fermat-numbers-1.rexx +++ /dev/null @@ -1,33 +0,0 @@ -/*REXX program to find and display Fermat numbers, and show factors of Fermat numbers.*/ -parse arg n . /*obtain optional argument from the CL.*/ -if n=='' | n=="," then n= 9 /*Not specified? Then use the default.*/ -numeric digits 20 /*ensure enough decimal digits, for n=9*/ - - do j=0 to n; f= 2** (2**j) + 1 /*calculate a series of Fermat numbers.*/ - say right('F'j, length(n) + 1)': ' f /*display a particular " " */ - end /*j*/ -say - do k=0 to n; f= 2** (2**k) + 1; say /*calculate a series of Fermat numbers.*/ - say center(' F'k": " f' ', 79, "═") /*display a particular " " */ - p= factr(f) /*factor a Fermat number, given time. */ - if words(p)==1 then say f ' is prime.' - else say 'factors: ' p - end /*k*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -factr: procedure; parse arg x 1 z,,? - do k=1 to 11 by 2; j= k; if j==1 then j= 2; if j==9 then iterate - call build /*add J to the factors list. */ - end /*k*/ /* [↑] factor X with some low primes*/ - - do y=0 by 2; j= j + 2 + y // 4 /*ensure not ÷ by three. */ - parse var j '' -1 _; if _==5 then iterate /*last digit a "5"? Skip it.*/ - if j*j>x | j>z then leave - call build /*add Y to the factors list. */ - end /*y*/ /* [↑] factor X with other higher #s*/ - j= z - if z\==1 then ?= build() - if ?='' then do; @.1= x; ?= x; #= 1; end - return ? -/*──────────────────────────────────────────────────────────────────────────────────────*/ -build: do while z//j==0; z= z % j; ?= ? j; end; return strip(?) diff --git a/Task/Fermat-numbers/REXX/fermat-numbers-2.rexx b/Task/Fermat-numbers/REXX/fermat-numbers-2.rexx deleted file mode 100644 index 1d23ec4428..0000000000 --- a/Task/Fermat-numbers/REXX/fermat-numbers-2.rexx +++ /dev/null @@ -1,36 +0,0 @@ -/*REXX program to find and display Fermat numbers, and show factors of Fermat numbers.*/ -parse arg n . /*obtain optional argument from the CL.*/ -if n=='' | n=="," then n= 9 /*Not specified? Then use the default.*/ -numeric digits 200 /*ensure enough decimal digits, for n=9*/ - - do j=0 to n; f= 2** (2**j) + 1 /*calculate a series of Fermat numbers.*/ - say right('F'j, length(n) + 1)': ' f /*display a particular " " */ - end /*j*/ -say - do k=5 to n; f= 2** (2**k) + 1; say /*calculate a series of Fermat numbers.*/ - say center(' F'k": " f' ', 79, "═") /*display a particular " " */ - a= rho(f) /*factor a Fermat number, given time. */ - b= f % a - if a==b then say f ' is prime.' - else say 'factors: ' commas(a) " " commas(b) - end /*k*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg _; do ?=length(_)-3 to 1 by -3; _=insert(',', _, ?); end; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -rho: procedure; parse arg n; y= 2; d= 1 /*initialize X, Y, and D variables.*/ - do x=2 until d==n /*try rho method with X=2 for 1st time.*/ - do while d==1 - x= (x*x + 1) // n - v= (y*y + 1) // n - y= (v*v + 1) // n - parse value x-y with xy 1 sig 2 /*obtain sign of the x-y difference. */ - if sig=='-' then parse var xy 2 xy /*Negative? Then use absolute value. */ - nn= n - do until nn==0 - parse value xy//nn nn with nn xy /*assign two variables: NN and XY */ - end /*until*/ /*this is an in-line GCD function. */ - d= xy /*assign variable D with a new XY */ - end /*while*/ - end /*x*/ - return d /*found a factor of N. Return it.*/ diff --git a/Task/Fermat-numbers/REXX/fermat-numbers-3.rexx b/Task/Fermat-numbers/REXX/fermat-numbers.rexx similarity index 78% rename from Task/Fermat-numbers/REXX/fermat-numbers-3.rexx rename to Task/Fermat-numbers/REXX/fermat-numbers.rexx index 7cee294fbe..14cec3f2bb 100644 --- a/Task/Fermat-numbers/REXX/fermat-numbers-3.rexx +++ b/Task/Fermat-numbers/REXX/fermat-numbers.rexx @@ -1,8 +1,10 @@ +-- 22 Mar 2025 include Settings +say 'FERMAT NUMBERS' +say version +say numeric digits 200 -say 'Fermat numbers - Using REXX libraries' -parse version version; say version; say do i = 0 to 9 p = 2**(2**i)+1; l = Length(p) say 'Fermat number' i',' p',' l 'digits' @@ -13,13 +15,13 @@ do i = 0 to 9 else do call Charout ,'has factors ' do j = 1 to f - call Charout, fact.factor.j' ' + call Charout, fact.j' ' end say end end else do - if IsPrime(p) then + if Prime(p) then say 'is prime' else say 'is composite, but could not be factorized' @@ -30,5 +32,6 @@ say Format(Time('e'),,3) 'seconds'; say exit include Functions +include Sequences include Numbers include Abend diff --git a/Task/Fibonacci-n-step-number-sequences/EasyLang/fibonacci-n-step-number-sequences.easy b/Task/Fibonacci-n-step-number-sequences/EasyLang/fibonacci-n-step-number-sequences.easy index 8c3fd4bc20..7692027866 100644 --- a/Task/Fibonacci-n-step-number-sequences/EasyLang/fibonacci-n-step-number-sequences.easy +++ b/Task/Fibonacci-n-step-number-sequences/EasyLang/fibonacci-n-step-number-sequences.easy @@ -1,4 +1,4 @@ -proc sequ n$ val[] n . . +proc sequ n$ val[] n . write n$ & ": " il = len val[] len val[] n @@ -7,9 +7,7 @@ proc sequ n$ val[] n . . val[i] += val[i - j] . . - for v in val[] - write v & " " - . + for v in val[] : write v & " " print "" . sequ "Fibonacci" [ 1 1 ] 10 diff --git a/Task/Fibonacci-sequence/APL/fibonacci-sequence-1.apl b/Task/Fibonacci-sequence/APL/fibonacci-sequence-1.apl index 030afc8adc..d9b4d1971d 100644 --- a/Task/Fibonacci-sequence/APL/fibonacci-sequence-1.apl +++ b/Task/Fibonacci-sequence/APL/fibonacci-sequence-1.apl @@ -1 +1 @@ -fib←{⍵≤1:⍵ ⋄ (∇ ⍵-1)+∇ ⍵-2} +fib←{⍵≤1:⍵ ⋄ (+/∇¨⍵-1 2} diff --git a/Task/Fibonacci-sequence/APL/fibonacci-sequence-2.apl b/Task/Fibonacci-sequence/APL/fibonacci-sequence-2.apl index 5b4caf7c2d..aa0e04498d 100644 --- a/Task/Fibonacci-sequence/APL/fibonacci-sequence-2.apl +++ b/Task/Fibonacci-sequence/APL/fibonacci-sequence-2.apl @@ -1 +1 @@ -↑+.×/N/⊂2 2⍴1 1 1 0 +fib←{⍵≤1:⍵ ⋄ (∇⍵-1)+∇⍵-2} diff --git a/Task/Fibonacci-sequence/APL/fibonacci-sequence-3.apl b/Task/Fibonacci-sequence/APL/fibonacci-sequence-3.apl index a30ddaceb7..5b4caf7c2d 100644 --- a/Task/Fibonacci-sequence/APL/fibonacci-sequence-3.apl +++ b/Task/Fibonacci-sequence/APL/fibonacci-sequence-3.apl @@ -1 +1 @@ -↑0 1↓↑+.×/N/⊂2 2⍴1 1 1 0 +↑+.×/N/⊂2 2⍴1 1 1 0 diff --git a/Task/Fibonacci-sequence/APL/fibonacci-sequence-4.apl b/Task/Fibonacci-sequence/APL/fibonacci-sequence-4.apl index 3eff61d5ef..a30ddaceb7 100644 --- a/Task/Fibonacci-sequence/APL/fibonacci-sequence-4.apl +++ b/Task/Fibonacci-sequence/APL/fibonacci-sequence-4.apl @@ -1 +1 @@ -⌊.5+(((1+PHI)÷2)*⍳N)÷PHI←5*.5 +↑0 1↓↑+.×/N/⊂2 2⍴1 1 1 0 diff --git a/Task/Fibonacci-sequence/APL/fibonacci-sequence-5.apl b/Task/Fibonacci-sequence/APL/fibonacci-sequence-5.apl new file mode 100644 index 0000000000..3eff61d5ef --- /dev/null +++ b/Task/Fibonacci-sequence/APL/fibonacci-sequence-5.apl @@ -0,0 +1 @@ +⌊.5+(((1+PHI)÷2)*⍳N)÷PHI←5*.5 diff --git a/Task/Fibonacci-sequence/K/fibonacci-sequence-1.k b/Task/Fibonacci-sequence/K/fibonacci-sequence-1.k index 8816e02a00..cfdc75791e 100644 --- a/Task/Fibonacci-sequence/K/fibonacci-sequence-1.k +++ b/Task/Fibonacci-sequence/K/fibonacci-sequence-1.k @@ -1 +1 @@ -{:[x<3;1;_f[x-1]+_f[x-2]]} +{:[x<3;1;+/_f'x-1 2]} diff --git a/Task/Fibonacci-sequence/K/fibonacci-sequence-2.k b/Task/Fibonacci-sequence/K/fibonacci-sequence-2.k index 31a7786133..8b96d92fc1 100644 --- a/Task/Fibonacci-sequence/K/fibonacci-sequence-2.k +++ b/Task/Fibonacci-sequence/K/fibonacci-sequence-2.k @@ -1 +1 @@ -{c::.();{v:c[a:`$$x];:[x<3;1;:[_n~v;c[a]:_f[x-1]+_f[x-2];v]]}x} +{c::.();{v:c[a:`$$x];:[x<3;1;_n~v;c[a]:+/_f'x-1 2;v]}x} diff --git a/Task/Fibonacci-sequence/Uxntal/fibonacci-sequence.uxnatl b/Task/Fibonacci-sequence/Uxntal/fibonacci-sequence.uxnatl new file mode 100644 index 0000000000..cf6cfb7837 --- /dev/null +++ b/Task/Fibonacci-sequence/Uxntal/fibonacci-sequence.uxnatl @@ -0,0 +1,31 @@ +%newline { [ LIT2 0a -Console/write ] DEO } + +|18 @Console/write + +|100 + +#1400 +&loop + DUP #00 SWP fibonacci print/dec newline + INC GTHk ?&loop +POP2 + +BRK + +@fibonacci ( n* -- n!* ) + ORAk ?{ JMP2r } + ORAk #01 NEQ ?{ JMP2r } + DUP2 #0001 SUB2 fibonacci STH2 + #0002 SUB2 fibonacci + STH2r ADD2 + JMP2r + +@print/dec ( short* -- ) + #000a SWP2 [ LITr ff ] + &get ( -- ) + SWP2k DIV2k MUL2 SUB2 STH + POP OVR2 DIV2 ORAk ?&get + POP2 POP2 + &put ( -- ) + STHr INCk ?{ POP JMP2r } + [ LIT "0 ] ADD .Console/write DEO !&put diff --git a/Task/Fibonacci-sequence/Zig/fibonacci-sequence.zig b/Task/Fibonacci-sequence/Zig/fibonacci-sequence.zig new file mode 100644 index 0000000000..24574a0e56 --- /dev/null +++ b/Task/Fibonacci-sequence/Zig/fibonacci-sequence.zig @@ -0,0 +1,14 @@ +const std = @import("std"); + +pub fn main() !void { + var a: u32 = 1; + var b: u32 = 1; + const target: u32 = 48; + + for (3..target + 1) |n| { + const fib = a + b; + std.debug.print("F({}) = {}\n", .{n, fib}); + a = b; + b = fib; + } +} diff --git a/Task/Fibonacci-word/EasyLang/fibonacci-word.easy b/Task/Fibonacci-word/EasyLang/fibonacci-word.easy index f5bd61d5f4..a92d11b1db 100644 --- a/Task/Fibonacci-word/EasyLang/fibonacci-word.easy +++ b/Task/Fibonacci-word/EasyLang/fibonacci-word.easy @@ -3,9 +3,7 @@ func log2 x . . func entropy s$ . l = len s$ - if l <= 1 - return 0 - . + if l <= 1 : return 0 for v$ in strchars s$ cnt0 += if v$ = "0" . @@ -27,7 +25,7 @@ func$ fibword . swap a$ b$ return b$ . -numfmt 6 8 +numfmt 8 6 print " n length entropy" print " ——————————————————————" for n to 37 diff --git a/Task/File-extension-is-in-extensions-list/C-sharp/file-extension-is-in-extensions-list.cs b/Task/File-extension-is-in-extensions-list/C-sharp/file-extension-is-in-extensions-list.cs new file mode 100644 index 0000000000..dcbbeee683 --- /dev/null +++ b/Task/File-extension-is-in-extensions-list/C-sharp/file-extension-is-in-extensions-list.cs @@ -0,0 +1,20 @@ +List extensions = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2", ]; + +List tests = [ + "MyData.a##", + "MyData.tar.Gz", + "MyData.gzip", + "MyData.7z.backup", + "MyData...", + "MyData", + "MyData_v1.0.tar.bz2", + "MyData_v1.0.bz2", + ]; + +foreach (var filename in tests) +{ + Console.WriteLine($"{filename,20} {IsInList(filename, extensions)}"); +} + +static bool IsInList(string filename, List extensions) => + extensions.Any(e => filename.ToLowerInvariant().EndsWith("." + e.ToLowerInvariant())); diff --git a/Task/File-extension-is-in-extensions-list/M2000-Interpreter/file-extension-is-in-extensions-list.m2000 b/Task/File-extension-is-in-extensions-list/M2000-Interpreter/file-extension-is-in-extensions-list.m2000 new file mode 100644 index 0000000000..744022303d --- /dev/null +++ b/Task/File-extension-is-in-extensions-list/M2000-Interpreter/file-extension-is-in-extensions-list.m2000 @@ -0,0 +1,35 @@ +module File_extension_is_in_extensions_list { + extensions=List:="zip","rar", "7z","gz", "archive", "a##" + filenames=("MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup", "MyData...", "MyData") + scanExtensions(each(filenames)) + + ' extra + Append extensions, "tar.bz2" + extra_filenames=("MyData_v1.0.tar.bz2", "MyData_v1.0.bz2") + scanExtensions(each(extra_filenames)) + + sub scanExtensions(m) + local b as boolean, ext, n + while m + ext=@possible_extensions(array$(m)) + n=each(ext) + b=false + while n + b=exist(extensions, array$(n)) + if b then exit + end while + Print array$(m), b + end while + end sub + function possible_extensions(a as string) + stack new { + local string k=rightpart$(a,".") + do + data lcase$(k) + k=rightpart$(k,".") + until k="" + =array([]) + } + end function +} +File_extension_is_in_extensions_list diff --git a/Task/File-extension-is-in-extensions-list/Nu/file-extension-is-in-extensions-list.nu b/Task/File-extension-is-in-extensions-list/Nu/file-extension-is-in-extensions-list.nu new file mode 100644 index 0000000000..f02f36a2d8 --- /dev/null +++ b/Task/File-extension-is-in-extensions-list/Nu/file-extension-is-in-extensions-list.nu @@ -0,0 +1,20 @@ +let exts = ["zip" "rar" "7z" "gz" "archive" "A##" "tar.bz2"] +let filenames = [ + "MyData.a##" + "MyData.tar.Gz" + "MyData.gzip" + "MyData.7z.backup" + "MyData..." + "MyData" + "MyData_v1.0.tar.bz2" + "MyData_v1.0.bz2" +] + +$exts | wrap "extensions" + +$filenames | each { |filename| + let check = ($exts | any { |ext| + ($filename | str downcase) | str ends-with ("." + ($ext | str downcase)) + }) + $"($filename | fill -w 20 -c ' ') ($check)" +} | print diff --git a/Task/File-size-distribution/Nu/file-size-distribution.nu b/Task/File-size-distribution/Nu/file-size-distribution.nu new file mode 100644 index 0000000000..653f8186bb --- /dev/null +++ b/Task/File-size-distribution/Nu/file-size-distribution.nu @@ -0,0 +1,24 @@ + [d:/work d:/drivers d:/images ] | each { ls ($"($in)/**/*" | into glob) | + each { |it| + let size = ($it.size | into int) + { + name: $it.name + size: $size + SizeCategory: (match $size { + 0..1_000 => "Under 1 KB" + 1_001..5_000 => "1 KB 5 KB" + 5_001..10_000 => "5 KB 10 KB" + 10_001..25_000 => "10 KB to 25 KB" + 25_001..50_000 => "25 KB to 50 KB" + 50_001..1_000_000 => "50 KB to 1 MB" + 1_000_001..5_000_000 => "1 MB to 5 MB" + 5_000_001..10_000_000 => "5 MB to 10 MB" + 10_000_001..25_000_000 => "10 MB to 25 MB" + 25_000_001..50_000_000 => "25 MB to 50 MB" + 50_000_001..100_000_000 => "50 MB to 100 MB" + 100_000_001..500_000_000 => "100 MB to 500 MB" + 500_000_001..1_000_000_000 => "500 MB to 1 GB" + 1_000_000_001..3_000_000_000 => "1 GB to 3 GB" + _ => "Over 3 GB" + }) + } } } | flatten | histogram SizeCategory diff --git a/Task/File-size-distribution/Tcl/file-size-distribution-1.tcl b/Task/File-size-distribution/Tcl/file-size-distribution-1.tcl new file mode 100644 index 0000000000..8739c0547e --- /dev/null +++ b/Task/File-size-distribution/Tcl/file-size-distribution-1.tcl @@ -0,0 +1,75 @@ +#!/usr/bin/env tclsh + +# table/count of size categories +# (numbers are both strings and numbers) +# ''sizes(100)'' is the array member ''sizes("100")'' + +array set sizes { + 0 0 + 100 0 + 1000 0 + 10000 0 + 100000 0 + 1000000 0 + 10000000 0 + 100000000 0 + 1000000000 0 +} + +# sorted list of keys +set keys [lsort -integer [array names sizes]] + +# check size and update count +proc count {f} { + variable sizes + variable keys + + #size in bytes of file + set size [file size $f] + + # increment count + foreach { v } $keys { + if {$size <= $v} {incr sizes($v) ; break} + } +} + +#recursive file name glob +proc getfiles {f} { + + if { [file isfile $f] } { + + # function call + count $f + } elseif { [file isdirectory $f] } { + + set files [glob -nocomplain [file join $f *]] + + # recursive call + foreach d $files { getfiles $d } + + } else { + return + } +} + + +# main +if { [info script] eq $::argv0 } { + + if { $::argc eq 0 } { + puts stderr "need a dir to start searching" + return 1 + } + + foreach dir $::argv { + getfiles $dir + + foreach v $keys { + puts "$v : \t$sizes($v)" + } + } + + return 0 +} + +# end diff --git a/Task/File-size-distribution/Tcl/file-size-distribution.tcl b/Task/File-size-distribution/Tcl/file-size-distribution-2.tcl similarity index 100% rename from Task/File-size-distribution/Tcl/file-size-distribution.tcl rename to Task/File-size-distribution/Tcl/file-size-distribution-2.tcl diff --git a/Task/Find-Chess960-starting-position-identifier/D/find-chess960-starting-position-identifier.d b/Task/Find-Chess960-starting-position-identifier/D/find-chess960-starting-position-identifier.d new file mode 100644 index 0000000000..ea3eb5a62a --- /dev/null +++ b/Task/Find-Chess960-starting-position-identifier/D/find-chess960-starting-position-identifier.d @@ -0,0 +1,83 @@ +import std.stdio : writeln, writefln; +import std.array : split; +import std.range : join; + +string genChess960Position(int id) { + string[] pos = new string[8]; + + int q = id / 4; + int r = id % 4; + + pos[r * 2 + 1] = "B"; // <<< + + q /= 4; + r = q % 4; + + pos[r * 2] = "B"; // <<< + + q /= 6; + r = q % 6; + + int i = 0; + foreach (j; 0 .. 8) { + if (pos[j] is null) { + if (i == r) { + i = j; + break; + } + i++; + } + } + + pos[i] = "Q"; // <<< + + //////////////////// + + string[] krn = [ + "NNRKR", "NRNKR", "NRKNR", "NRKRN", + "RNNKR", "RNKNR", "RNKRN", + "RKNNR", "RKNRN", + "RKRNN" + ]; + + string krnString = krn[q]; + auto krnChars = krnString.split(""); // <<< + + i = 0; + foreach (j; 0 .. 8) { + if (pos[j] is null) { + pos[j] = krnChars[i++]; // <<< + } + } + + //////////////////// + + return pos.join(""); +} + +void main() { + writeln; + + writeln("Chess960 Position List by SP-ID"); + writeln; + + foreach (id; 0..3+1) { + writefln("%3s : %s", id, genChess960Position(id)); + } + + "... ........".writeln; + writeln; + + foreach (id; [518]) { + writefln("%3s : %s", id, genChess960Position(id)); + } + + "... ........".writeln; + writeln; + + foreach (id; 956..959+1) { + writefln("%3s : %s", id, genChess960Position(id)); + } + + writeln; +} diff --git a/Task/Find-common-directory-path/BQN/find-common-directory-path.bqn b/Task/Find-common-directory-path/BQN/find-common-directory-path.bqn new file mode 100644 index 0000000000..559c792f19 --- /dev/null +++ b/Task/Find-common-directory-path/BQN/find-common-directory-path.bqn @@ -0,0 +1,9 @@ +LongestPath ← {∾⟜𝕨⊸∾´ ⊑¨{1⊸+⌈´/≤⟜1¨≠¨𝕩}⊸↑ ⍷¨⥊⋈˘ ⍉> ⌊´∘(≠¨)⊸(↑¨) 𝕨⊸((+`׬)⊸-∘= ⊔ ⊢)¨ 𝕩} + +dirs ← ⟨ + "/home/user1/tmp/coverage/test", + "/home/user1/tmp/covert/operator", + "/home/user1/tmp/coven/members", +⟩ + +•Show '/' LongestPath dirs diff --git a/Task/Find-if-a-point-is-within-a-triangle/C-sharp/find-if-a-point-is-within-a-triangle.cs b/Task/Find-if-a-point-is-within-a-triangle/C-sharp/find-if-a-point-is-within-a-triangle.cs new file mode 100644 index 0000000000..f98f097d18 --- /dev/null +++ b/Task/Find-if-a-point-is-within-a-triangle/C-sharp/find-if-a-point-is-within-a-triangle.cs @@ -0,0 +1,90 @@ +using System.Numerics; + +Point a = new(new(1, 10), new(1, 9)); // 0.1, 0.1111... +Point b = new(12.5, new(100, 3)); // 12.5, 33.3333... +Point c = new(25, new(100, 9)); // 25, 11.1111... + +// Test a point on the boundary (supposedly fails with double-precision) +Point test = (4 * a + 3 * b) / 7; +test.IsInTriangle(a, b, c); + +// Other examples +a = new(1.5, 2.4); b = new(5.1, -3.1); c = new(-3.8, 1.2); +new Point(0, 0).IsInTriangle(a, b, c); +new Point(0, 1).IsInTriangle(a, b, c); +new Point(3, 1).IsInTriangle(a, b, c); + +record Point(Rational X, Rational Y) +{ + public static Point operator +(Point a, Point b) => new(a.X + b.X, a.Y + b.Y); + public static Point operator -(Point a, Point b) => new(a.X - b.X, a.Y - b.Y); + public static Point operator *(int s, Point p) => new(s * p.X, s * p.Y); + public static Point operator /(Point p, int s) => new(p.X / s, p.Y / s); + public override string ToString() => $"({X}, {Y})"; + + public Rational Det(Point other) => X * other.Y - Y * other.X; + + public bool IsInTriangle(Point a, Point b, Point c) + { + var v1 = b - a; + var v2 = c - a; + var d = v1.Det(v2); + var t = (Det(v2) - a.Det(v2)) / d; + var u = (a.Det(v1) - Det(v1)) / d; + var inside = t >= 0 && u >= 0 && 1 >= t + u; + Console.WriteLine($"{this} in {a}, {b}, {c} = {inside}"); + return inside; + } +} + +readonly struct Rational +{ + public readonly BigInteger n, d; + + public Rational(BigInteger n, BigInteger d) + { + var g = BigInteger.GreatestCommonDivisor(n, d) * d.Sign; + this.n = n / g; this.d = d / g; + } + + public static implicit operator Rational(int n) => new(n, 1); + public static implicit operator Rational(BigInteger n) => new(n, 1); + public static Rational operator +(Rational x, Rational y) => new(x.n * y.d + y.n * x.d, x.d * y.d); + public static Rational operator -(Rational x) => new(-x.n, x.d); + public static Rational operator -(Rational x, Rational y) => new(x.n * y.d - y.n * x.d, x.d * y.d); + public static Rational operator *(Rational x, Rational y) => new(x.n * y.n, x.d * y.d); + public static Rational operator /(Rational x, Rational y) => new(x.n * y.d, x.d * y.n); + public static bool operator >=(Rational x, Rational y) => x.n * y.d >= y.n * x.d; + public static bool operator <=(Rational x, Rational y) => x.n * y.d <= y.n * x.d; + public override readonly string ToString() => n == 0 ? "0" : d == 1 ? $"{n}" : $"{n}/{d}"; + + public static implicit operator Rational(double d) + { + if (d == 0.0) + return 0; + + long n = BitConverter.DoubleToInt64Bits(d); + bool negative = n < 0; + int exp = (int)(n >> 52) & 0x7FF; + long mantissa = n & 0xFFFFFFFFFFFFF; + + if (exp == 0) + { + exp = -1022; + } + else + { + mantissa |= 0x10000000000000; + exp -= 1023; + } + + exp -= 52; + long numerator = mantissa; + if (negative) numerator = -numerator; + + if (exp >= 0) + return new(numerator << exp, 1); + + return new(numerator, BigInteger.Pow(2, -exp)); + } +} diff --git a/Task/Find-if-a-point-is-within-a-triangle/EasyLang/find-if-a-point-is-within-a-triangle.easy b/Task/Find-if-a-point-is-within-a-triangle/EasyLang/find-if-a-point-is-within-a-triangle.easy index f57bc5c2a7..fd50ebd786 100644 --- a/Task/Find-if-a-point-is-within-a-triangle/EasyLang/find-if-a-point-is-within-a-triangle.easy +++ b/Task/Find-if-a-point-is-within-a-triangle/EasyLang/find-if-a-point-is-within-a-triangle.easy @@ -14,20 +14,21 @@ func isin px py ax ay bx by cx cy . z3 = sgn px py cx cy ax ay return if abs (z1 + z2 + z3) = 3 . -move 5 90 -textsize 4 -text "Move mouse into the triangle" -color 444 -polygon [ ax ay bx by cx cy ] +proc drawpoly in . + if in = 1 + gcolor 822 + else + gcolor 444 + . + gpolygon [ ax ay bx by cx cy ] +. +gtextsize 4 +gtext 5 90 "Move mouse into the triangle" +drawpoly 0 # on mouse_move if isin mouse_x mouse_y ax ay bx by cx cy <> in in = 1 - in - if in = 1 - color 822 - else - color 444 - . - polygon [ ax ay bx by cx cy ] + drawpoly in . . diff --git a/Task/Find-largest-left-truncatable-prime-in-a-given-base/REXX/find-largest-left-truncatable-prime-in-a-given-base.rexx b/Task/Find-largest-left-truncatable-prime-in-a-given-base/REXX/find-largest-left-truncatable-prime-in-a-given-base.rexx index 3f7aeeeb82..b943603212 100644 --- a/Task/Find-largest-left-truncatable-prime-in-a-given-base/REXX/find-largest-left-truncatable-prime-in-a-given-base.rexx +++ b/Task/Find-largest-left-truncatable-prime-in-a-given-base/REXX/find-largest-left-truncatable-prime-in-a-given-base.rexx @@ -1,6 +1,8 @@ include Settings -say version; say 'Left truncatable primes'; say +say 'LEFT TRUNCATABLE PRIME IN GIVEN BASE - 4 Mar 2025' +say version +say numeric digits 100; work. = 0 bases = '3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 21 23 25' do i = 1 to Words(bases) @@ -16,7 +18,7 @@ end say Words(bases) 'bases specified' say work.cycle 'digit cycles needed' say work.count 'numbers tested for primality' -say work.prime 'of them were actually prime' +say work.Prime 'of them were actually prime' say Format(Time('e'),,3) 'seconds' exit @@ -61,8 +63,8 @@ do i = 1 to work.in.0 a = work.in.i; b = x**work.digit do j = 1 to x-1 work.count = work.count+1; c = a+b*j - if Isprime(c) then do - work.prime = work.prime+1; n = n+1; work.out.n = c + if Prime(c) then do + work.Prime = work.Prime+1; n = n+1; work.out.n = c end end end diff --git a/Task/Find-limit-of-recursion/Ballerina/find-limit-of-recursion.ballerina b/Task/Find-limit-of-recursion/Ballerina/find-limit-of-recursion.ballerina new file mode 100644 index 0000000000..4415411d3b --- /dev/null +++ b/Task/Find-limit-of-recursion/Ballerina/find-limit-of-recursion.ballerina @@ -0,0 +1,10 @@ +import ballerina/io; + +function func(int n) { + io:println(n); + func(n + 1); +} + +public function main() { + func(1); +} diff --git a/Task/Find-limit-of-recursion/EasyLang/find-limit-of-recursion.easy b/Task/Find-limit-of-recursion/EasyLang/find-limit-of-recursion.easy index 050dea43eb..88bb3196a6 100644 --- a/Task/Find-limit-of-recursion/EasyLang/find-limit-of-recursion.easy +++ b/Task/Find-limit-of-recursion/EasyLang/find-limit-of-recursion.easy @@ -1,7 +1,5 @@ -proc recurse i . . - if i mod 10 = 0 - print i - . +proc recurse i . + if i mod 10 = 0 : print i recurse i + 1 . recurse 1 diff --git a/Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/EasyLang/find-palindromic-numbers-in-both-binary-and-ternary-bases.easy b/Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/EasyLang/find-palindromic-numbers-in-both-binary-and-ternary-bases.easy index 06db655d11..9838c747d2 100644 --- a/Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/EasyLang/find-palindromic-numbers-in-both-binary-and-ternary-bases.easy +++ b/Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/EasyLang/find-palindromic-numbers-in-both-binary-and-ternary-bases.easy @@ -4,9 +4,7 @@ fastfunc ispalin2 n . x = x * 2 + m mod 2 m = m div 2 . - if n = x - return 1 - . + if n = x : return 1 . fastfunc reverse3 n . while n > 0 @@ -16,11 +14,10 @@ fastfunc reverse3 n . return r . func$ itoa n b . - if n > 0 - return itoa (n div b) b & n mod b - . + if n > 0 : return itoa (n div b) b & n mod b + return "" . -proc main . . +proc main . print "0 0(2) 0(3)" print "1 1(2) 1(3)" pow3 = 3 @@ -31,9 +28,7 @@ proc main . . if ispalin2 n = 1 print n & " " & itoa n 2 & "(2) " & itoa n 3 & "(3)" cnt += 1 - if cnt = 6 - 2 - return - . + if cnt = 6 - 2 : return . . pow3 *= 3 diff --git a/Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/R/find-palindromic-numbers-in-both-binary-and-ternary-bases.r b/Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/R/find-palindromic-numbers-in-both-binary-and-ternary-bases.r new file mode 100644 index 0000000000..b95dbfbd60 --- /dev/null +++ b/Task/Find-palindromic-numbers-in-both-binary-and-ternary-bases/R/find-palindromic-numbers-in-both-binary-and-ternary-bases.r @@ -0,0 +1,82 @@ +require(stringi) + +base2 <- function(x){ + y <- integer(0) + while(x >= 2){ + r <- x %% 2 + x <- x %/% 2 + y <- c(r, y) + } + y <- c(x, y) + gsub(", ", "", toString(y)) +} + +base3 <- function(x){ + y <- integer(0) + while(x >= 3){ + r <- x %% 3 + x <- x %/% 3 + y <- c(r, y) + } + y <- c(x, y) + gsub(", ", "", toString(y)) +} + +# note: no check if input is legitimate base 3 number +base_3_to_base_10 <- function(base_3_number) { + place <- 0 + multiplier <- 1 + base_10_total <- 0 + base_3_number_as_list <- rev(number_to_list(base_3_number)) + for (one_number in base_3_number_as_list) { + base_10_total <- base_10_total + (one_number * multiplier) + place <- place + 1 + multiplier <- 3 ^ place + } + return(base_10_total) +} + +number_to_list <- function(input_number){ + string_number <- toString(input_number) + list_of_strings <- strsplit(string_number, NULL) + integer_list <- list() + for (one_string in list_of_strings) { + one_integer <- as.integer(one_string) + integer_list <- append(one_integer, integer_list) + } + return(integer_list) +} + +is_palindrome <- function(string) { + backwards <- stri_reverse(string) + identical(backwards, string) +} + +base_3_to_base_2 <- function(base_3_number) { + base_10_number <- base_3_to_base_10(base_3_number) + base_2_number_string <- base2(base_10_number) + return(base_2_number_string) +} + +list_first_2 <- function() { + cat(0, 0, 0, "\n") + cat(1, 1, 1, "\n") +} + +palindromes_in_base_2_and_base_3 <- function(number) { + list_first_2() + number <- number - 2 + count <- 1 + partial_base_number <- 1 + while (count <= number) { + partial_base_3 <- base3(partial_base_number) + full_base_3_string <- paste0 (partial_base_3, "1", stri_reverse (as.character(partial_base_3))) + base2_number <- base_3_to_base_2(full_base_3_string) + if (is_palindrome(base2_number)) { + base10_number <- base_3_to_base_10(full_base_3_string) + cat(base10_number, base2_number, full_base_3_string, "\n") + count <- count + 1 + } + partial_base_number <- partial_base_number + 1 + } +} diff --git a/Task/Find-the-intersection-of-a-line-with-a-plane/EasyLang/find-the-intersection-of-a-line-with-a-plane.easy b/Task/Find-the-intersection-of-a-line-with-a-plane/EasyLang/find-the-intersection-of-a-line-with-a-plane.easy index 9ece60947b..44221e29fe 100644 --- a/Task/Find-the-intersection-of-a-line-with-a-plane/EasyLang/find-the-intersection-of-a-line-with-a-plane.easy +++ b/Task/Find-the-intersection-of-a-line-with-a-plane/EasyLang/find-the-intersection-of-a-line-with-a-plane.easy @@ -1,30 +1,23 @@ -proc minus . l[] r[] res[] . - len res[] 3 - for i to 3 - res[i] = l[i] - r[i] - . +func[] minus &l[] &r[] . + for i to 3 : res[] &= l[i] - r[i] + return res[] . func dot l[] r[] . - for i to 3 - res += l[i] * r[i] - . + for i to 3 : res += l[i] * r[i] return res . -proc scale f . l[] . - for i to 3 - l[i] = l[i] * f - . +proc scale &l[] f . + for i to 3 : l[i] = l[i] * f . -proc inter_point rv[] rp[] pn[] pp[] . res[] . - minus rp[] pp[] dif[] +func[] inter_point &rv[] &rp[] &pn[] &pp[] . + dif[] = minus rp[] pp[] prd1 = dot dif[] pn[] prd2 = dot rv[] pn[] - scale (prd1 / prd2) rv[] - minus rp[] rv[] res[] + scale rv[] (prd1 / prd2) + return minus rp[] rv[] . rv[] = [ 0.0 -1.0 -1.0 ] rp[] = [ 0.0 0.0 10.0 ] pn[] = [ 0.0 0.0 1.0 ] pp[] = [ 0.0 0.0 5.0 ] -inter_point rv[] rp[] pn[] pp[] res[] -print res[] +print inter_point rv[] rp[] pn[] pp[] diff --git a/Task/Find-the-intersection-of-two-lines/EasyLang/find-the-intersection-of-two-lines.easy b/Task/Find-the-intersection-of-two-lines/EasyLang/find-the-intersection-of-two-lines.easy index 167f357dd3..af44525c32 100644 --- a/Task/Find-the-intersection-of-two-lines/EasyLang/find-the-intersection-of-two-lines.easy +++ b/Task/Find-the-intersection-of-two-lines/EasyLang/find-the-intersection-of-two-lines.easy @@ -1,21 +1,11 @@ -proc intersect ax1 ay1 ax2 ay2 bx1 by1 bx2 by2 . rx ry . - rx = 1 / 0 - ry = 1 / 0 +func[] intersect ax1 ay1 ax2 ay2 bx1 by1 bx2 by2 . d = (by2 - by1) * (ax2 - ax1) - (bx2 - bx1) * (ay2 - ay1) - if d = 0 - return - . + if d = 0 : return [ 1 / 0 1 / 0 ] ua = ((bx2 - bx1) * (ay1 - by1) - (by2 - by1) * (ax1 - bx1)) / d ub = ((ax2 - ax1) * (ay1 - by1) - (by2 - by1) * (ax1 - bx1)) / d - if abs ua > 1 or abs ub > 1 - return - . - rx = ax1 + ua * (ax2 - ax1) - ry = ay1 + ua * (ay2 - ay1) + if abs ua > 1 or abs ub > 1 : return [ 1 / 0 1 / 0 ] + return [ ax1 + ua * (ax2 - ax1) ay1 + ua * (ay2 - ay1) ] . -intersect 4 0 6 10 0 3 10 7 rx ry -print rx & " " & ry -intersect 4 0 6 10 0 3 10 7.1 rx ry -print rx & " " & ry -intersect 0 0 1 1 1 2 4 5 rx ry -print rx & " " & ry +print intersect 4 0 6 10 0 3 10 7 +print intersect 4 0 6 10 0 3 10 7.1 +print intersect 0 0 1 1 1 2 4 5 diff --git a/Task/Find-the-last-Sunday-of-each-month/EasyLang/find-the-last-sunday-of-each-month.easy b/Task/Find-the-last-Sunday-of-each-month/EasyLang/find-the-last-sunday-of-each-month.easy index e98f0923a4..c8d5ea7ea5 100644 --- a/Task/Find-the-last-Sunday-of-each-month/EasyLang/find-the-last-sunday-of-each-month.easy +++ b/Task/Find-the-last-Sunday-of-each-month/EasyLang/find-the-last-sunday-of-each-month.easy @@ -5,18 +5,14 @@ func wkday year month day . r = day + (13 * mm - 1) div 5 + yy + yy div 4 - yy div 100 + yy div 400 return r mod 7 + 1 . -proc show y . . +proc show y . days[] = [ 31 28 31 30 31 30 31 31 30 31 30 31 ] days[2] += if y mod 4 = 0 and (y mod 100 <> 0 or y mod 400 = 0) for m = 1 to 12 d = days[m] - while wkday y m d <> 1 - d -= 1 - . + while wkday y m d <> 1 : d -= 1 m$ = m - if m < 10 - m$ = 0 & m - . + if m < 10 : m$ = 0 & m print y & "-" & m$ & "-" & d . . diff --git a/Task/Find-the-missing-permutation/EasyLang/find-the-missing-permutation.easy b/Task/Find-the-missing-permutation/EasyLang/find-the-missing-permutation.easy index 86a7c5c24e..351a114673 100644 --- a/Task/Find-the-missing-permutation/EasyLang/find-the-missing-permutation.easy +++ b/Task/Find-the-missing-permutation/EasyLang/find-the-missing-permutation.easy @@ -1,24 +1,18 @@ -perms$[] = [ "ABCD" "CABD" "ACDB" "DACB" "BCDA" "ACBD" "ADCB" "CDAB" "DABC" "BCAD" "CADB" "CDBA" "CBAD" "ABDC" "ADBC" "BDCA" "DCBA" "BACD" "BADC" "BDAC" "CBDA" "DBCA" "DCAB" ] -n = len perms$[1] -len cnt[] n -# -nn = 1 -for i to n - 1 - nn *= i -. -for i to 4 - for j to n - cnt[j] = 0 - . - for s$ in perms$[] - cod = strcode substr s$ i 1 - 64 - cnt[cod] += 1 - . - for j to n - if cnt[j] <> nn - miss$ &= strchar (j + 64) - break 1 +func$ missing perms$[] . + n = len perms$[1] + len cnt[] n + nn = 1 + for i = 2 to n - 1 : nn *= i + for i to n + for j to n : cnt[j] = 0 + for s$ in perms$[] + cod = strcode substr s$ i 1 - 64 + cnt[cod] += 1 + . + for j to n + if cnt[j] <> nn : miss$ &= strchar (j + 64) . . + return miss$ . -print miss$ +print missing [ "ABCD" "CABD" "ACDB" "DACB" "BCDA" "ACBD" "ADCB" "CDAB" "DABC" "BCAD" "CADB" "CDBA" "CBAD" "ABDC" "ADBC" "BDCA" "DCBA" "BACD" "BADC" "BDAC" "CBDA" "DBCA" "DCAB" ] diff --git a/Task/Find-the-missing-permutation/Zig/find-the-missing-permutation.zig b/Task/Find-the-missing-permutation/Zig/find-the-missing-permutation.zig new file mode 100644 index 0000000000..dcdaf7be86 --- /dev/null +++ b/Task/Find-the-missing-permutation/Zig/find-the-missing-permutation.zig @@ -0,0 +1,39 @@ +const std = @import("std"); + +pub fn main() !void { + const N: usize = 4; + const perms = [_][]const u8{ + "ABCD", "CABD", "ACDB", "DACB", "BCDA", "ACBD", "ADCB", "CDAB", + "DABC", "BCAD", "CADB", "CDBA", "CBAD", "ABDC", "ADBC", "BDCA", + "DCBA", "BACD", "BADC", "BDAC", "CBDA", "DBCA", "DCAB", + }; + + // Calculate n = (N-1)!, the expected number of occurrences + var n: usize = 1; + var i: usize = 1; + while (i < N) : (i += 1) { + n *= i; + } + + var miss: [N]u8 = undefined; + var stdout = std.io.getStdOut().writer(); + + i = 0; + while (i < N) : (i += 1) { + var cnt = [_]usize{0} ** N; + + // Count how many times each letter occurs at position i + for (perms) |perm| { + const position = perm[i] - 'A'; + cnt[position] += 1; + } + + // Find letter not occurring (N-1)! times - that's the missing one + var j: usize = 0; + while (j < N and cnt[j] == n) : (j += 1) {} + + miss[i] = @as(u8, @intCast(j)) + 'A'; + } + + try stdout.print("Missing: {s}\n", .{miss}); +} diff --git a/Task/First-perfect-square-in-base-n-with-n-unique-digits/EasyLang/first-perfect-square-in-base-n-with-n-unique-digits.easy b/Task/First-perfect-square-in-base-n-with-n-unique-digits/EasyLang/first-perfect-square-in-base-n-with-n-unique-digits.easy index ca84da2be9..9323a7a527 100644 --- a/Task/First-perfect-square-in-base-n-with-n-unique-digits/EasyLang/first-perfect-square-in-base-n-with-n-unique-digits.easy +++ b/Task/First-perfect-square-in-base-n-with-n-unique-digits/EasyLang/first-perfect-square-in-base-n-with-n-unique-digits.easy @@ -1,8 +1,6 @@ alpha$ = "0123456789AB" func$ itoa n b . - if n > 0 - return itoa (n div b) b & substr alpha$ (n mod b + 1) 1 - . + if n > 0 : return itoa (n div b) b & substr alpha$ (n mod b + 1) 1 . func unique s$ . len dig[] 12 @@ -10,12 +8,10 @@ func unique s$ . ind = strpos alpha$ c$ dig[ind] = 1 . - for v in dig[] - cnt += v - . + for v in dig[] : cnt += v return cnt . -proc find b . . +proc find b . n = floor pow b ((b - 1) div 2) repeat sq = n * n diff --git a/Task/First-perfect-square-in-base-n-with-n-unique-digits/Fortran/first-perfect-square-in-base-n-with-n-unique-digits.f b/Task/First-perfect-square-in-base-n-with-n-unique-digits/Fortran/first-perfect-square-in-base-n-with-n-unique-digits.f new file mode 100644 index 0000000000..cc619f4a86 --- /dev/null +++ b/Task/First-perfect-square-in-base-n-with-n-unique-digits/Fortran/first-perfect-square-in-base-n-with-n-unique-digits.f @@ -0,0 +1,100 @@ +program perfect_squares + implicit none + integer :: base, i + integer(8) :: m, m_squared, base_power, start_m + character(len=:), allocatable :: m_str, square_str + logical :: found + + do base = 2, 16 + found = .false. + ! Calculate base^(base-1) for lower bound + base_power = 1_8 + do i = 1, base-1 + base_power = base_power * int(base, 8) + end do + ! Compute start_m as ceiling(sqrt(base_power)) + start_m = int(sqrt(real(base_power, kind=8)), kind=8) + if (start_m * start_m < base_power) start_m = start_m + 1_8 + ! Search until solution found (no upper limit) + do m = start_m, huge(1_8)-1 + m_squared = m * m + square_str = to_base(m_squared, base) + if (len(square_str) < base) cycle + if (is_valid_square(square_str, base)) then + m_str = to_base(m, base) + print "(A, I2, A, A,T25, A, A)", "Base ", base, " : Num ", trim(m_str), " Square ", trim(square_str) + found = .true. + exit + end if + end do + if (.not. found) print *, "No solution for base ", base + end do +contains +pure function to_base(n, base) result(str) + integer(8), intent(in) :: n + integer, intent(in) :: base + character(len=:), allocatable :: str + integer(8) :: tmp, bbase, rem + integer :: i, len + character(1) :: buffer(32) + character(1), parameter :: digits(16) = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'] + + tmp = n + bbase = base + i = 0 + buffer = ' ' ! Initialize buffer to blanks + + do while (tmp > 0) + rem = mod(tmp, bbase) + i = i + 1 + buffer(i) = digits(rem+1) + tmp = tmp / bbase + end do + + if (i == 0) then +! allocate(str(1)) + str(1:1) = '0' + return + end if + + allocate(character(i) :: str) + do len = 1, i + str(len:len) = buffer(i - len + 1) + end do +end function to_base + +pure function is_valid_square(str, base) result(ok) + character(len=*), intent(in) :: str + integer, intent(in) :: base + logical :: ok + integer :: i, digit, ascii, seen, mask + integer, parameter :: char_to_digit(48:70) = [ & + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, & ! '0'–'9' + ( -1, i = 58, 64 ), & ! ':'–'@' + 10, 11, 12, 13, 14, 15 ] ! 'A'–'F' + + if (len(str) < base) then + ok = .false. + return + end if + + seen = 0 + do i = 1, len(str) + ascii = iachar(str(i:i)) + if (ascii < 48 .or. ascii > 70) then + ok = .false. + return + end if + digit = char_to_digit(ascii) + if (digit < 0 .or. digit >= base) then + ok = .false. + return + end if + seen = ibset(seen, digit) + end do + + mask = ishft(1, base) - 1 + ok = (seen == mask) +end function is_valid_square + +end program perfect_squares diff --git a/Task/First-power-of-2-that-has-leading-decimal-digits-of-12/EasyLang/first-power-of-2-that-has-leading-decimal-digits-of-12.easy b/Task/First-power-of-2-that-has-leading-decimal-digits-of-12/EasyLang/first-power-of-2-that-has-leading-decimal-digits-of-12.easy index 89d2853742..d4192c6672 100644 --- a/Task/First-power-of-2-that-has-leading-decimal-digits-of-12/EasyLang/first-power-of-2-that-has-leading-decimal-digits-of-12.easy +++ b/Task/First-power-of-2-that-has-leading-decimal-digits-of-12/EasyLang/first-power-of-2-that-has-leading-decimal-digits-of-12.easy @@ -9,13 +9,11 @@ func p l n . while n > 0 test += 1 val = floor (factor * pow 10 (test * log mod 1)) - if val = l - n -= 1 - . + if val = l : n -= 1 . return test . -proc test l n . . +proc test l n . print "p(" & l & ", " & n & ") = " & p l n . test 12 1 diff --git a/Task/Fivenum/Ballerina/fivenum.ballerina b/Task/Fivenum/Ballerina/fivenum.ballerina new file mode 100644 index 0000000000..75a66eb8cd --- /dev/null +++ b/Task/Fivenum/Ballerina/fivenum.ballerina @@ -0,0 +1,30 @@ +import ballerina/io; + +function fivenum(float[] arr) returns float[5] { + float[] a = arr.sort(); + float[5] n5 = []; + float n = a.length(); + float n4 = ((a.length() + 3) / 2) / 2.0; + float[] d = [1, n4, (n + 1) / 2, n + 1 - n4, n]; + foreach [int, float] [e, de] in d.enumerate() { + int floor = (de - 1.0).floor(); + int ceil = (de - 1.0).ceiling(); + n5[e] = 0.5 * (a[floor] + a[ceil]); + } + return n5; +} + +public function main() { + float[] x1 = [36, 40, 7, 39, 41, 15]; + float[] x2 = [15, 6, 42, 41, 7, 36, 49, 40, 39, 47, 43]; + float[] x3 = [ + 0.14082834, 0.09748790, 1.73131507, 0.87636009, -1.95059594, + 0.73438555, -0.03035726, 1.46675970, -0.74621349, -0.72588772, + 0.63905160, 0.61501527, -0.98983780, -1.00447874, -0.62759469, + 0.66206163, 1.04312009, -0.10305385, 0.75775634, 0.32566578 + ]; + foreach var x in [x1, x2, x3] { + var res = fivenum(x); + io:println(re `,`.replaceAll(res.toString(), ", ")); + } +} diff --git a/Task/Fivenum/EasyLang/fivenum.easy b/Task/Fivenum/EasyLang/fivenum.easy index 910e2dc9be..2bcb5bc356 100644 --- a/Task/Fivenum/EasyLang/fivenum.easy +++ b/Task/Fivenum/EasyLang/fivenum.easy @@ -1,17 +1,13 @@ func median t[] low high . l = high - low + 1 m = low + l div 2 - if l mod 2 = 1 - return t[m] - . + if l mod 2 = 1 : return t[m] return (t[m - 1] + t[m]) / 2 . -proc sort . d[] . +proc sort &d[] . for i = 1 to len d[] - 1 for j = i + 1 to len d[] - if d[j] < d[i] - swap d[j] d[i] - . + if d[j] < d[i] : swap d[j] d[i] . . . diff --git a/Task/FizzBuzz/APL/fizzbuzz-1.apl b/Task/FizzBuzz/APL/fizzbuzz-1.apl index 9c4c983cb1..1e7e7de17d 100644 --- a/Task/FizzBuzz/APL/fizzbuzz-1.apl +++ b/Task/FizzBuzz/APL/fizzbuzz-1.apl @@ -1,2 +1,2 @@ -⎕IO←0 -(L,'Fizz' 'Buzz' 'FizzBuzz')[¯1+(L×W=0)+W←(100×~0=W)+W←⊃+/1 2×0=3 5|⊂L←1+⍳100] +⎕io←1 +{⎕←∊'Fizz' 'Buzz'⍵/⍨d,⍱/d←0=3 5|⍵}¨⍳100 diff --git a/Task/FizzBuzz/APL/fizzbuzz-2.apl b/Task/FizzBuzz/APL/fizzbuzz-2.apl index e2fbf6f312..03ea88a223 100644 --- a/Task/FizzBuzz/APL/fizzbuzz-2.apl +++ b/Task/FizzBuzz/APL/fizzbuzz-2.apl @@ -1 +1 @@ -A[I]←1+I←(0⍷A)/⍳⍴A←('FIZZBUZZ' 'FIZZ’ 'BUZZ' 0)[2⊥¨×(⊂3 5)|¨1+⍳100] +{⍵ 'Fizz' 'Buzz' 'FizzBuzz'[2⊥0=5 3|⍵]}¨1+⍳100 diff --git a/Task/FizzBuzz/APL/fizzbuzz-3.apl b/Task/FizzBuzz/APL/fizzbuzz-3.apl index b6e7b109d0..aefe79e331 100644 --- a/Task/FizzBuzz/APL/fizzbuzz-3.apl +++ b/Task/FizzBuzz/APL/fizzbuzz-3.apl @@ -1 +1 @@ -{ ⍵ 'Fizz' 'Buzz' 'FizzBuzz'[ +/1 2×0=3 5|⍵] }¨1+⍳100 +{('FizzBuzz' 'Fizz' 'Buzz',⍵)[(0=15 3 5|⍵)⍳1]}¨⍳100 diff --git a/Task/FizzBuzz/APL/fizzbuzz-4.apl b/Task/FizzBuzz/APL/fizzbuzz-4.apl index 75e0fad7c0..c4b7ddd6e7 100644 --- a/Task/FizzBuzz/APL/fizzbuzz-4.apl +++ b/Task/FizzBuzz/APL/fizzbuzz-4.apl @@ -1 +1,2 @@ -{(‘FizzBuzz’ ‘Fizz’ ‘Buzz’,⍵)[(0=15 3 5|⍵)⍳1]}¨⍳100 +⎕IO←0 +A[I]←1+I←(0⍷A)/⍳⍴A←('FIZZBUZZ' 'FIZZ' 'BUZZ' 0)[2⊥¨×(⊂3 5)|¨1+⍳100] diff --git a/Task/FizzBuzz/APL/fizzbuzz-5.apl b/Task/FizzBuzz/APL/fizzbuzz-5.apl index 21cc1d1b7c..fdd98bf784 100644 --- a/Task/FizzBuzz/APL/fizzbuzz-5.apl +++ b/Task/FizzBuzz/APL/fizzbuzz-5.apl @@ -1,40 +1,2 @@ - ∇ sv ← fizzbuzz n; t;d -[1] ⍝⍝ Solve the popular 'fizzbuzz' problem in APL. -[2] ⍝⍝ \param n - highest number to compute (≥0) -[3] ⍝⍝ \returns sv - a vector of strings representing the fizzbuzz solution for ⍳n -[4] ⍝⍝ (note we return a string vector to avoid a mixed-type result; remove the -[5] ⍝⍝ ⍕ function from the (⍕t[⍵]) term to see the difference). -[6] ⍝⍝⍝⍝ -[7] t←⍳n ⍝ the sequence 1..n itself which we'll pick from -[8] ⍝ ... or the words 'fizz', 'buzz', 'fizzbuzz' depending on -[9] ⍝ ... divisibility by 3 and/or 5 -[10] ⍝⎕←t ⍝ (Uncomment to see during call) -[11] -[12] d←1+(+⌿ ⊃ {((0=3|⍵)) (2×(0=5|⍵))} ⍳n) -[13] ⍝ || || | | | ↓↓ -[14] ⍝ || || | | | ⍳n: generate range (1..n) -[15] ⍝ || || | ↓.....................↓ ↓↓ -[16] ⍝ || || | A dfn (lambda) taking its right arg (⍵, ⍳n here) to compute two boolean -[17] ⍝ || || | vectors(v12): divisibility by 3 and 5, respectively, for each of ⍳n -[18] ⍝ || || ↓ -[19] ⍝ || || ⊃: Disclose ('lift-up' and pad w/zeros) the 'ragged' matrix of vectors (v12) -[20] ⍝ || || holding divisibility by 3 and 5 of each ⍳n -[21] ⍝ || ↓↓ -[22] ⍝ || +⌿: Sum (v12) row-wise to count divisibility (0=neither 3 nor 5, 1=3, 2=3 and 5) -[23] ⍝ ↓↓ -[24] ⍝ 1+: Add one to (v12) to make them 1-based for indexing below: -[25] ⍝⎕←d -[26] -[27] sv ← { ((⍕t[⍵]) 'Fizz' 'Buzz' 'FizzBuzz') [d[⍵]]}¨ ⍳n -[28] ⍝ | | | | | | -[29] ⍝ | | | ↓....↓ | -[30] ⍝ | |................................↓ idx | -[31] ⍝ | ( lookup output vector ) | -[32] ⍝ ↓...........................................↓ -[33] ⍝ A dfn (lambda) taking as its right arg (⍵) ⍳n and using the 'each' (¨) -[34] ⍝ operator to apply the lambda to each (idx) of ⍳n. -[35] -[36] ⍝⍝ USAGE -[37] ⍝⍝ ⎕ ← ,fizzbuzz 15 -[38] ⍝ 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz - ∇ +⎕IO←0 +(L,'Fizz' 'Buzz' 'FizzBuzz')[¯1+(L×W=0)+W←(100×0≠W)+W←⊃+/1 2×0=3 5|⊂L←1+⍳100] diff --git a/Task/FizzBuzz/APL/fizzbuzz-6.apl b/Task/FizzBuzz/APL/fizzbuzz-6.apl index 1e7e7de17d..9bdba7d172 100644 --- a/Task/FizzBuzz/APL/fizzbuzz-6.apl +++ b/Task/FizzBuzz/APL/fizzbuzz-6.apl @@ -1,2 +1,2 @@ -⎕io←1 -{⎕←∊'Fizz' 'Buzz'⍵/⍨d,⍱/d←0=3 5|⍵}¨⍳100 +⎕IO←0 +(L,'Fizz' 'Buzz' 'FizzBuzz')[¯1+(100+W[I])@(I←⍸0≠W←⊃+/1 2×0=3 5|⊂L)⊢L←1+⍳100] diff --git a/Task/FizzBuzz/APL/fizzbuzz-7.apl b/Task/FizzBuzz/APL/fizzbuzz-7.apl new file mode 100644 index 0000000000..21cc1d1b7c --- /dev/null +++ b/Task/FizzBuzz/APL/fizzbuzz-7.apl @@ -0,0 +1,40 @@ + ∇ sv ← fizzbuzz n; t;d +[1] ⍝⍝ Solve the popular 'fizzbuzz' problem in APL. +[2] ⍝⍝ \param n - highest number to compute (≥0) +[3] ⍝⍝ \returns sv - a vector of strings representing the fizzbuzz solution for ⍳n +[4] ⍝⍝ (note we return a string vector to avoid a mixed-type result; remove the +[5] ⍝⍝ ⍕ function from the (⍕t[⍵]) term to see the difference). +[6] ⍝⍝⍝⍝ +[7] t←⍳n ⍝ the sequence 1..n itself which we'll pick from +[8] ⍝ ... or the words 'fizz', 'buzz', 'fizzbuzz' depending on +[9] ⍝ ... divisibility by 3 and/or 5 +[10] ⍝⎕←t ⍝ (Uncomment to see during call) +[11] +[12] d←1+(+⌿ ⊃ {((0=3|⍵)) (2×(0=5|⍵))} ⍳n) +[13] ⍝ || || | | | ↓↓ +[14] ⍝ || || | | | ⍳n: generate range (1..n) +[15] ⍝ || || | ↓.....................↓ ↓↓ +[16] ⍝ || || | A dfn (lambda) taking its right arg (⍵, ⍳n here) to compute two boolean +[17] ⍝ || || | vectors(v12): divisibility by 3 and 5, respectively, for each of ⍳n +[18] ⍝ || || ↓ +[19] ⍝ || || ⊃: Disclose ('lift-up' and pad w/zeros) the 'ragged' matrix of vectors (v12) +[20] ⍝ || || holding divisibility by 3 and 5 of each ⍳n +[21] ⍝ || ↓↓ +[22] ⍝ || +⌿: Sum (v12) row-wise to count divisibility (0=neither 3 nor 5, 1=3, 2=3 and 5) +[23] ⍝ ↓↓ +[24] ⍝ 1+: Add one to (v12) to make them 1-based for indexing below: +[25] ⍝⎕←d +[26] +[27] sv ← { ((⍕t[⍵]) 'Fizz' 'Buzz' 'FizzBuzz') [d[⍵]]}¨ ⍳n +[28] ⍝ | | | | | | +[29] ⍝ | | | ↓....↓ | +[30] ⍝ | |................................↓ idx | +[31] ⍝ | ( lookup output vector ) | +[32] ⍝ ↓...........................................↓ +[33] ⍝ A dfn (lambda) taking as its right arg (⍵) ⍳n and using the 'each' (¨) +[34] ⍝ operator to apply the lambda to each (idx) of ⍳n. +[35] +[36] ⍝⍝ USAGE +[37] ⍝⍝ ⎕ ← ,fizzbuzz 15 +[38] ⍝ 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz + ∇ diff --git a/Task/FizzBuzz/Erlang/fizzbuzz.erl b/Task/FizzBuzz/Erlang/fizzbuzz-1.erl similarity index 100% rename from Task/FizzBuzz/Erlang/fizzbuzz.erl rename to Task/FizzBuzz/Erlang/fizzbuzz-1.erl diff --git a/Task/FizzBuzz/Erlang/fizzbuzz-2.erl b/Task/FizzBuzz/Erlang/fizzbuzz-2.erl new file mode 100644 index 0000000000..e0eca4b65c --- /dev/null +++ b/Task/FizzBuzz/Erlang/fizzbuzz-2.erl @@ -0,0 +1,27 @@ +-module(fizzbuzz). +-export([start/1, count/2, display/0]). + +fizzbuzz(N) when N rem 15 == 0 -> fizzbuzz; +fizzbuzz(N) when N rem 5 == 0 -> buzz; +fizzbuzz(N) when N rem 3 == 0 -> fizz; +fizzbuzz(N) -> N. + +count(N, Limit) when N==Limit -> + display ! fizzbuzz(N), + display ! finished; +count(N, Limit) when N + display ! fizzbuzz(N), + count(N+1, Limit). + +display() -> + receive + finished -> io:format("end!\n"); + fizzbuzz -> io:format("FizzBuzz!\n"), display(); + buzz -> io:format("Buzz!\n"), display(); + fizz -> io:format("Fizz!\n"), display(); + N -> io:format("~p\n", [N]), display() + end. + +start(Max) -> + register(display, spawn(fizzbuzz, display, [])), + count(1, Max). diff --git a/Task/FizzBuzz/Excel/fizzbuzz.excel b/Task/FizzBuzz/Excel/fizzbuzz.excel new file mode 100644 index 0000000000..72b590c3e0 --- /dev/null +++ b/Task/FizzBuzz/Excel/fizzbuzz.excel @@ -0,0 +1,11 @@ +=LET( + i, SEQUENCE(100), + isDivBy3, MOD(i, 3) = 0, + isDivBy5, MOD(i, 5) = 0, + IFS( + isDivBy3 * isDivBy5, "FizzBuzz", + isDivBy3, "Fizz", + isDivBy5, "Buzz", + TRUE, i + ) + ) diff --git a/Task/FizzBuzz/Factor/fizzbuzz-1.factor b/Task/FizzBuzz/Factor/fizzbuzz-1.factor index e761b31263..b00a4fcc29 100644 --- a/Task/FizzBuzz/Factor/fizzbuzz-1.factor +++ b/Task/FizzBuzz/Factor/fizzbuzz-1.factor @@ -1,7 +1,2 @@ -USING: math kernel io math.functions math.parser math.ranges ; -IN: fizzbuzz -: fizz ( n -- str ) 3 divisor? "Fizz" "" ? ; -: buzz ( n -- str ) 5 divisor? "Buzz" "" ? ; -: fizzbuzz ( n -- str ) dup [ fizz ] [ buzz ] bi append [ number>string ] [ nip ] if-empty ; -: main ( -- ) 100 [1,b] [ fizzbuzz print ] each ; -MAIN: main +USE: math.parser +1 101 [ [ 3 5 [ mod 0 = ] bi-curry@ bi "Fizz" "Buzz" swapd [ and ] 2bi@ append ] keep number>string or print ] each-integer-from diff --git a/Task/FizzBuzz/Factor/fizzbuzz-2.factor b/Task/FizzBuzz/Factor/fizzbuzz-2.factor index cc6c825348..e761b31263 100644 --- a/Task/FizzBuzz/Factor/fizzbuzz-2.factor +++ b/Task/FizzBuzz/Factor/fizzbuzz-2.factor @@ -1,19 +1,7 @@ -USING: kernel sequences arrays generalizations fry math math.parser prettyprint ; +USING: math kernel io math.functions math.parser math.ranges ; IN: fizzbuzz - -: zz ( m seq -- v ) dup length 1 V{ } clone 4 -nrot 1 4 -nrot 3 nrot - '[ dup _ <= ] - 3 -nrot - '[ - "" _ [ _ [ swap execute( str n -- str n ) ] change-nth ] each-index - dup empty? [ drop dup number>string ] [ ] if swapd suffix! swap 1 + - ] - while drop ; - -: fizz ( str n -- str n ) dup 3 < [ 1 + ] [ drop "Fizz" append 1 ] if ; -: buzz ( str n -- str n ) dup 5 < [ 1 + ] [ drop "Buzz" append 1 ] if ; -: quxx ( str n -- str n ) dup 7 < [ 1 + ] [ drop "Quxx" append 1 ] if ; -: FizzBuzzQuxx ( m -- v ) { fizz buzz quxx } zz ; -: FizzBuzzQuxx-100 ( -- ) 100 FizzBuzzQuxx . ; - -MAIN: FizzBuzzQuxx-100 +: fizz ( n -- str ) 3 divisor? "Fizz" "" ? ; +: buzz ( n -- str ) 5 divisor? "Buzz" "" ? ; +: fizzbuzz ( n -- str ) dup [ fizz ] [ buzz ] bi append [ number>string ] [ nip ] if-empty ; +: main ( -- ) 100 [1,b] [ fizzbuzz print ] each ; +MAIN: main diff --git a/Task/FizzBuzz/Factor/fizzbuzz-3.factor b/Task/FizzBuzz/Factor/fizzbuzz-3.factor index 16b9ef4955..cc6c825348 100644 --- a/Task/FizzBuzz/Factor/fizzbuzz-3.factor +++ b/Task/FizzBuzz/Factor/fizzbuzz-3.factor @@ -1,24 +1,19 @@ -USING: io kernel math math.functions math.parser ranges -sequences ; -IN: rosetta-code.fizz-buzz +USING: kernel sequences arrays generalizations fry math math.parser prettyprint ; +IN: fizzbuzz -PREDICATE: fizz < integer 3 divisor? ; -PREDICATE: buzz < integer 5 divisor? ; +: zz ( m seq -- v ) dup length 1 V{ } clone 4 -nrot 1 4 -nrot 3 nrot + '[ dup _ <= ] + 3 -nrot + '[ + "" _ [ _ [ swap execute( str n -- str n ) ] change-nth ] each-index + dup empty? [ drop dup number>string ] [ ] if swapd suffix! swap 1 + + ] + while drop ; -INTERSECTION: fizzbuzz fizz buzz ; +: fizz ( str n -- str n ) dup 3 < [ 1 + ] [ drop "Fizz" append 1 ] if ; +: buzz ( str n -- str n ) dup 5 < [ 1 + ] [ drop "Buzz" append 1 ] if ; +: quxx ( str n -- str n ) dup 7 < [ 1 + ] [ drop "Quxx" append 1 ] if ; +: FizzBuzzQuxx ( m -- v ) { fizz buzz quxx } zz ; +: FizzBuzzQuxx-100 ( -- ) 100 FizzBuzzQuxx . ; -GENERIC: fizzbuzz>string ( n -- str ) - -M: fizz fizzbuzz>string - drop "Fizz" ; - -M: buzz fizzbuzz>string - drop "Buzz" ; - -M: fizzbuzz fizzbuzz>string - drop "FizzBuzz" ; - -M: integer fizzbuzz>string - number>string ; - -MAIN: [ 1 100 [a..b] [ fizzbuzz>string print ] each ] +MAIN: FizzBuzzQuxx-100 diff --git a/Task/FizzBuzz/Factor/fizzbuzz-4.factor b/Task/FizzBuzz/Factor/fizzbuzz-4.factor new file mode 100644 index 0000000000..16b9ef4955 --- /dev/null +++ b/Task/FizzBuzz/Factor/fizzbuzz-4.factor @@ -0,0 +1,24 @@ +USING: io kernel math math.functions math.parser ranges +sequences ; +IN: rosetta-code.fizz-buzz + +PREDICATE: fizz < integer 3 divisor? ; +PREDICATE: buzz < integer 5 divisor? ; + +INTERSECTION: fizzbuzz fizz buzz ; + +GENERIC: fizzbuzz>string ( n -- str ) + +M: fizz fizzbuzz>string + drop "Fizz" ; + +M: buzz fizzbuzz>string + drop "Buzz" ; + +M: fizzbuzz fizzbuzz>string + drop "FizzBuzz" ; + +M: integer fizzbuzz>string + number>string ; + +MAIN: [ 1 100 [a..b] [ fizzbuzz>string print ] each ] diff --git a/Task/FizzBuzz/J/fizzbuzz-1.j b/Task/FizzBuzz/J/fizzbuzz-1.j index 5dde9baf98..cf8f496d2d 100644 --- a/Task/FizzBuzz/J/fizzbuzz-1.j +++ b/Task/FizzBuzz/J/fizzbuzz-1.j @@ -1,2 +1 @@ - classify =: +/@(1 2 * 0 = 3 5&|~) - (":@]`('Fizz'"_)`('Buzz'"_)`('FizzBuzz'"_) @. classify "0) >:i.100 +(":[^:(0=#@])(>;:'Fizz Buzz'),@#~0=3 5&|)"0>:i.100 diff --git a/Task/FizzBuzz/J/fizzbuzz-10.j b/Task/FizzBuzz/J/fizzbuzz-10.j new file mode 100644 index 0000000000..4e32de5dc2 --- /dev/null +++ b/Task/FizzBuzz/J/fizzbuzz-10.j @@ -0,0 +1,2 @@ + ;:inv}.(":&.> [^:(0 = #@])&.> [: ,&.>/ ;:@'Fizz Buzz' #&.>~ 0=3 5|/])i.101 +1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fiz... diff --git a/Task/FizzBuzz/J/fizzbuzz-11.j b/Task/FizzBuzz/J/fizzbuzz-11.j new file mode 100644 index 0000000000..caa56ca729 --- /dev/null +++ b/Task/FizzBuzz/J/fizzbuzz-11.j @@ -0,0 +1,36 @@ + i.10 +0 1 2 3 4 5 6 7 8 9 + (3 5 |/ ])i.10 +0 1 2 0 1 2 0 1 2 0 +0 1 2 3 4 0 1 2 3 4 + (0=3 5 |/ ])i.10 +1 0 0 1 0 0 1 0 0 1 +1 0 0 0 0 1 0 0 0 0 + (;:'Fizz Buzz') +┌────┬────┐ +│Fizz│Buzz│ +└────┴────┘ + ((;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 +┌────┬┬┬────┬┬────┬────┬┬┬────┐ +│Fizz│││Fizz││ │Fizz│││Fizz│ +├────┼┼┼────┼┼────┼────┼┼┼────┤ +│Buzz│││ ││Buzz│ │││ │ +└────┴┴┴────┴┴────┴────┴┴┴────┘ + ([: ,&.>/ (;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 +┌────────┬┬┬────┬┬────┬────┬┬┬────┐ +│FizzBuzz│││Fizz││Buzz│Fizz│││Fizz│ +└────────┴┴┴────┴┴────┴────┴┴┴────┘ + (":&.>)i.10 +┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ +│0│1│2│3│4│5│6│7│8│9│ +└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ + (":&.> [^:(0 = #@])&.> [: ,&.>/ (;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 +┌────────┬─┬─┬────┬─┬────┬────┬─┬─┬────┐ +│FizzBuzz│1│2│Fizz│4│Buzz│Fizz│7│8│Fizz│ +└────────┴─┴─┴────┴─┴────┴────┴─┴─┴────┘ + }.(":&.> [^:(0 = #@])&.> [: ,&.>/ (;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 +┌─┬─┬────┬─┬────┬────┬─┬─┬────┐ +│1│2│Fizz│4│Buzz│Fizz│7│8│Fizz│ +└─┴─┴────┴─┴────┴────┴─┴─┴────┘ + ;:inv}.(":&.> [^:(0 = #@])&.> [: ,&.>/ (;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 +1 2 Fizz 4 Buzz Fizz 7 8 Fizz diff --git a/Task/FizzBuzz/J/fizzbuzz-2.j b/Task/FizzBuzz/J/fizzbuzz-2.j index eff230eaa9..ae7ac2541f 100644 --- a/Task/FizzBuzz/J/fizzbuzz-2.j +++ b/Task/FizzBuzz/J/fizzbuzz-2.j @@ -1 +1 @@ -> }. (<'FizzBuzz') (I.0=15|n)} (<'Buzz') (I.0=5|n)} (<'Fizz') (I.0=3|n)} ":&.> n=: i.101 +>((2#.3 q:15&+.){(|.(;~,&;);:'Fizz Buzz');~":)&>1+i.100 diff --git a/Task/FizzBuzz/J/fizzbuzz-3.j b/Task/FizzBuzz/J/fizzbuzz-3.j index ea1082f9c2..d25b1526f6 100644 --- a/Task/FizzBuzz/J/fizzbuzz-3.j +++ b/Task/FizzBuzz/J/fizzbuzz-3.j @@ -1,5 +1 @@ -Fizz=: 'Fizz' #~ 0 = 3&| -Buzz=: 'Buzz' #~ 0 = 5&| -FizzBuzz=: ": [^:('' -: ]) Fizz,Buzz - -FizzBuzz"0 >: i.100 +":`('Fizz'"_)`('Buzz'"_)`('FizzBuzz'"_)@.(2#.0=3 5&|)"0>:i.100 diff --git a/Task/FizzBuzz/J/fizzbuzz-4.j b/Task/FizzBuzz/J/fizzbuzz-4.j index 4b811ea712..4daf942db5 100644 --- a/Task/FizzBuzz/J/fizzbuzz-4.j +++ b/Task/FizzBuzz/J/fizzbuzz-4.j @@ -1,6 +1 @@ -CRT0=: 2 : ' (, 0 = +./)@(0 = m | ]) ;@# n , <@": ' -NB. Rather (, 0 = +./) than (, +:/) because designed for -NB. 3 5 7 CRT0 (;:'Chinese Remainder Period') "0 >: i. */3 5 7 -FizzBuzz=: 3 5 CRT0 (;:'Fizz Buzz') - -FizzBuzz"0 >: i.100 +{{":`('Fizz'"_)`('Buzz'"_)`,@.((0;1;2;1 3 2){~#.0=3 5|y)y}}"0 >:i.20 diff --git a/Task/FizzBuzz/J/fizzbuzz-5.j b/Task/FizzBuzz/J/fizzbuzz-5.j index 9c48851a18..eff230eaa9 100644 --- a/Task/FizzBuzz/J/fizzbuzz-5.j +++ b/Task/FizzBuzz/J/fizzbuzz-5.j @@ -1,6 +1 @@ -'`f b fb' =: ('Fizz'"_) ` ('Buzz'"_) ` (f , b) -'`cm3 cm5 cm15'=: (3&|) ` (5&|) ` (15&|) (0&=@) -FizzBuzz=: ": ` f @. cm3 ` b @. cm5 ` fb @. cm15 NB. also: -FizzBuzz=: ": ` f @. cm3 ` b @. cm5 ` (f,b) @. (cm3 *. cm5) - -FizzBuzz"0 >: i.100 +> }. (<'FizzBuzz') (I.0=15|n)} (<'Buzz') (I.0=5|n)} (<'Fizz') (I.0=3|n)} ":&.> n=: i.101 diff --git a/Task/FizzBuzz/J/fizzbuzz-6.j b/Task/FizzBuzz/J/fizzbuzz-6.j index 3b006a37bf..ea1082f9c2 100644 --- a/Task/FizzBuzz/J/fizzbuzz-6.j +++ b/Task/FizzBuzz/J/fizzbuzz-6.j @@ -1,2 +1,5 @@ - ;:inv}.(":&.> [^:(0 = #@])&.> [: ,&.>/ (;:'Fizz Buzz') #&.>~ 0 = 3 5 |/ ])i.101 -1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fiz... +Fizz=: 'Fizz' #~ 0 = 3&| +Buzz=: 'Buzz' #~ 0 = 5&| +FizzBuzz=: ": [^:('' -: ]) Fizz,Buzz + +FizzBuzz"0 >: i.100 diff --git a/Task/FizzBuzz/J/fizzbuzz-7.j b/Task/FizzBuzz/J/fizzbuzz-7.j index caa56ca729..4b811ea712 100644 --- a/Task/FizzBuzz/J/fizzbuzz-7.j +++ b/Task/FizzBuzz/J/fizzbuzz-7.j @@ -1,36 +1,6 @@ - i.10 -0 1 2 3 4 5 6 7 8 9 - (3 5 |/ ])i.10 -0 1 2 0 1 2 0 1 2 0 -0 1 2 3 4 0 1 2 3 4 - (0=3 5 |/ ])i.10 -1 0 0 1 0 0 1 0 0 1 -1 0 0 0 0 1 0 0 0 0 - (;:'Fizz Buzz') -┌────┬────┐ -│Fizz│Buzz│ -└────┴────┘ - ((;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 -┌────┬┬┬────┬┬────┬────┬┬┬────┐ -│Fizz│││Fizz││ │Fizz│││Fizz│ -├────┼┼┼────┼┼────┼────┼┼┼────┤ -│Buzz│││ ││Buzz│ │││ │ -└────┴┴┴────┴┴────┴────┴┴┴────┘ - ([: ,&.>/ (;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 -┌────────┬┬┬────┬┬────┬────┬┬┬────┐ -│FizzBuzz│││Fizz││Buzz│Fizz│││Fizz│ -└────────┴┴┴────┴┴────┴────┴┴┴────┘ - (":&.>)i.10 -┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ -│0│1│2│3│4│5│6│7│8│9│ -└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ - (":&.> [^:(0 = #@])&.> [: ,&.>/ (;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 -┌────────┬─┬─┬────┬─┬────┬────┬─┬─┬────┐ -│FizzBuzz│1│2│Fizz│4│Buzz│Fizz│7│8│Fizz│ -└────────┴─┴─┴────┴─┴────┴────┴─┴─┴────┘ - }.(":&.> [^:(0 = #@])&.> [: ,&.>/ (;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 -┌─┬─┬────┬─┬────┬────┬─┬─┬────┐ -│1│2│Fizz│4│Buzz│Fizz│7│8│Fizz│ -└─┴─┴────┴─┴────┴────┴─┴─┴────┘ - ;:inv}.(":&.> [^:(0 = #@])&.> [: ,&.>/ (;:'Fizz Buzz') #&.>~0=3 5 |/ ])i.10 -1 2 Fizz 4 Buzz Fizz 7 8 Fizz +CRT0=: 2 : ' (, 0 = +./)@(0 = m | ]) ;@# n , <@": ' +NB. Rather (, 0 = +./) than (, +:/) because designed for +NB. 3 5 7 CRT0 (;:'Chinese Remainder Period') "0 >: i. */3 5 7 +FizzBuzz=: 3 5 CRT0 (;:'Fizz Buzz') + +FizzBuzz"0 >: i.100 diff --git a/Task/FizzBuzz/J/fizzbuzz-8.j b/Task/FizzBuzz/J/fizzbuzz-8.j new file mode 100644 index 0000000000..9c48851a18 --- /dev/null +++ b/Task/FizzBuzz/J/fizzbuzz-8.j @@ -0,0 +1,6 @@ +'`f b fb' =: ('Fizz'"_) ` ('Buzz'"_) ` (f , b) +'`cm3 cm5 cm15'=: (3&|) ` (5&|) ` (15&|) (0&=@) +FizzBuzz=: ": ` f @. cm3 ` b @. cm5 ` fb @. cm15 NB. also: +FizzBuzz=: ": ` f @. cm3 ` b @. cm5 ` (f,b) @. (cm3 *. cm5) + +FizzBuzz"0 >: i.100 diff --git a/Task/FizzBuzz/J/fizzbuzz-9.j b/Task/FizzBuzz/J/fizzbuzz-9.j new file mode 100644 index 0000000000..e259c246e8 --- /dev/null +++ b/Task/FizzBuzz/J/fizzbuzz-9.j @@ -0,0 +1 @@ +{{>(#.|:0=3 5|&>L=.1+i.y),|:(y,3)$;:'Fizz Buzz FizzBuzz'}}100 diff --git a/Task/FizzBuzz/K/fizzbuzz-1.k b/Task/FizzBuzz/K/fizzbuzz-1.k index 1592aa685d..827c202ee0 100644 --- a/Task/FizzBuzz/K/fizzbuzz-1.k +++ b/Task/FizzBuzz/K/fizzbuzz-1.k @@ -1 +1 @@ -`0:\:{:[0=#a:{,/$(:[0=x!3;"Fizz"];:[0=x!5;"Buzz"])}@x;$x;a]}'1_!101 +{,/$(s;x)@~#s:`Fizz`Buzz@&~x!'3 5}'1+!30 diff --git a/Task/FizzBuzz/K/fizzbuzz-2.k b/Task/FizzBuzz/K/fizzbuzz-2.k index 78fc38d860..fa59579991 100644 --- a/Task/FizzBuzz/K/fizzbuzz-2.k +++ b/Task/FizzBuzz/K/fizzbuzz-2.k @@ -1,2 +1 @@ - fizzbuzz:{:[0=x!15;`0:,"FizzBuzz";0=x!3;`0:,"Fizz";0=x!5;`0:,"Buzz";`0:,$x]} - fizzbuzz' 1+!100 + {:[0=x!15;`0:,"FizzBuzz";0=x!3;`0:,"Fizz";0=x!5;`0:,"Buzz";`0:,$x]}'1+!100 diff --git a/Task/FizzBuzz/K/fizzbuzz-3.k b/Task/FizzBuzz/K/fizzbuzz-3.k index 6e9a070c6a..1592aa685d 100644 --- a/Task/FizzBuzz/K/fizzbuzz-3.k +++ b/Task/FizzBuzz/K/fizzbuzz-3.k @@ -1,8 +1 @@ -fizzbuzz:{ - v:1+!x - i:(&0=)'v!/:3 5 15 - r:@[v;i 0;{"Fizz"}] - r:@[r;i 1;{"Buzz"}] - @[r;i 2;{"FizzBuzz"}]} - -`0:$fizzbuzz 100 +`0:\:{:[0=#a:{,/$(:[0=x!3;"Fizz"];:[0=x!5;"Buzz"])}@x;$x;a]}'1_!101 diff --git a/Task/FizzBuzz/K/fizzbuzz-4.k b/Task/FizzBuzz/K/fizzbuzz-4.k index 827c202ee0..6e9a070c6a 100644 --- a/Task/FizzBuzz/K/fizzbuzz-4.k +++ b/Task/FizzBuzz/K/fizzbuzz-4.k @@ -1 +1,8 @@ -{,/$(s;x)@~#s:`Fizz`Buzz@&~x!'3 5}'1+!30 +fizzbuzz:{ + v:1+!x + i:(&0=)'v!/:3 5 15 + r:@[v;i 0;{"Fizz"}] + r:@[r;i 1;{"Buzz"}] + @[r;i 2;{"FizzBuzz"}]} + +`0:$fizzbuzz 100 diff --git a/Task/FizzBuzz/Pascal/fizzbuzz.pas b/Task/FizzBuzz/Pascal/fizzbuzz.pas deleted file mode 100644 index ecf0f31b7d..0000000000 --- a/Task/FizzBuzz/Pascal/fizzbuzz.pas +++ /dev/null @@ -1,14 +0,0 @@ -program fizzbuzz(output); -var - i: integer; -begin - for i := 1 to 100 do - if i mod 15 = 0 then - writeln('FizzBuzz') - else if i mod 3 = 0 then - writeln('Fizz') - else if i mod 5 = 0 then - writeln('Buzz') - else - writeln(i) -end. diff --git a/Task/FizzBuzz/Python/fizzbuzz-10.py b/Task/FizzBuzz/Python/fizzbuzz-10.py index ecb948c678..b29ebd9a54 100644 --- a/Task/FizzBuzz/Python/fizzbuzz-10.py +++ b/Task/FizzBuzz/Python/fizzbuzz-10.py @@ -1,33 +1,13 @@ -'''Fizz buzz''' +from itertools import cycle, izip, count, islice -from itertools import count, cycle, islice +fizzes = cycle([""] * 2 + ["Fizz"]) +buzzes = cycle([""] * 4 + ["Buzz"]) +both = (f + b for f, b in izip(fizzes, buzzes)) +# if the string is "", yield the number +# otherwise yield the string +fizzbuzz = (word or n for word, n in izip(both, count(1))) -# fizzBuzz :: () -> Generator [String] -def fizzBuzz(): - '''A non-finite stream of fizzbuzz terms. - ''' - return map( - lambda f, b, n: (f + b) or str(n), - cycle([''] * 2 + ['Fizz']), - cycle([''] * 4 + ['Buzz']), - count(1) - ) - - -# ------------------------- TEST ------------------------- -def main(): - '''Display of first 100 terms of the fizzbuzz series. - ''' - print( - '\n'.join( - list(islice( - fizzBuzz(), - 100 - )) - ) - ) - - -if __name__ == '__main__': - main() +# print the first 100 +for i in islice(fizzbuzz, 100): + print i diff --git a/Task/FizzBuzz/Python/fizzbuzz-11.py b/Task/FizzBuzz/Python/fizzbuzz-11.py index f5123bf731..ecb948c678 100644 --- a/Task/FizzBuzz/Python/fizzbuzz-11.py +++ b/Task/FizzBuzz/Python/fizzbuzz-11.py @@ -1 +1,33 @@ -print(*map(lambda n: 'Fizzbuzz '[(i):i+13] if (i := n**4%-15) > -14 else n, range(1,100))) +'''Fizz buzz''' + +from itertools import count, cycle, islice + + +# fizzBuzz :: () -> Generator [String] +def fizzBuzz(): + '''A non-finite stream of fizzbuzz terms. + ''' + return map( + lambda f, b, n: (f + b) or str(n), + cycle([''] * 2 + ['Fizz']), + cycle([''] * 4 + ['Buzz']), + count(1) + ) + + +# ------------------------- TEST ------------------------- +def main(): + '''Display of first 100 terms of the fizzbuzz series. + ''' + print( + '\n'.join( + list(islice( + fizzBuzz(), + 100 + )) + ) + ) + + +if __name__ == '__main__': + main() diff --git a/Task/FizzBuzz/Python/fizzbuzz-12.py b/Task/FizzBuzz/Python/fizzbuzz-12.py index 1bd2e48a8c..f5123bf731 100644 --- a/Task/FizzBuzz/Python/fizzbuzz-12.py +++ b/Task/FizzBuzz/Python/fizzbuzz-12.py @@ -1,12 +1 @@ -def numsum(n): - ''' The recursive sum of all digits in a number - unit a single character is obtained''' - res = sum([int(i) for i in str(n)]) - if res < 10: return res - else : return numsum(res) - -for n in range(1,101): - response = 'Fizz'*(numsum(n) in [3,6,9]) + \ - 'Buzz'*(str(n)[-1] in ['5','0'])\ - or n - print(response) +print(*map(lambda n: 'Fizzbuzz '[(i):i+13] if (i := n**4%-15) > -14 else n, range(1,100))) diff --git a/Task/FizzBuzz/Python/fizzbuzz-13.py b/Task/FizzBuzz/Python/fizzbuzz-13.py index 15158ad45a..1bd2e48a8c 100644 --- a/Task/FizzBuzz/Python/fizzbuzz-13.py +++ b/Task/FizzBuzz/Python/fizzbuzz-13.py @@ -1 +1,12 @@ -print(*((lambda x=x: ''.join(chr(c) for c in (102, 105)) + (2 * chr(122)) + ''.join(chr(c) for c in (98, 117)) + (2 * chr(122)) + '\n' if x % (30 >> 1) == 0 else ''.join(chr(c) for c in (102, 105)) + (2 * chr(122)) + '\n' if x % (6 >> 1) == 0 else ''.join(chr(c) for c in (98, 117)) + (2 * chr(122)) + '\n' if x % (10 >> 1) == 0 else str(x) + '\n')() for x in range(1, 101))) +def numsum(n): + ''' The recursive sum of all digits in a number + unit a single character is obtained''' + res = sum([int(i) for i in str(n)]) + if res < 10: return res + else : return numsum(res) + +for n in range(1,101): + response = 'Fizz'*(numsum(n) in [3,6,9]) + \ + 'Buzz'*(str(n)[-1] in ['5','0'])\ + or n + print(response) diff --git a/Task/FizzBuzz/Python/fizzbuzz-14.py b/Task/FizzBuzz/Python/fizzbuzz-14.py new file mode 100644 index 0000000000..15158ad45a --- /dev/null +++ b/Task/FizzBuzz/Python/fizzbuzz-14.py @@ -0,0 +1 @@ +print(*((lambda x=x: ''.join(chr(c) for c in (102, 105)) + (2 * chr(122)) + ''.join(chr(c) for c in (98, 117)) + (2 * chr(122)) + '\n' if x % (30 >> 1) == 0 else ''.join(chr(c) for c in (102, 105)) + (2 * chr(122)) + '\n' if x % (6 >> 1) == 0 else ''.join(chr(c) for c in (98, 117)) + (2 * chr(122)) + '\n' if x % (10 >> 1) == 0 else str(x) + '\n')() for x in range(1, 101))) diff --git a/Task/FizzBuzz/Python/fizzbuzz-8.py b/Task/FizzBuzz/Python/fizzbuzz-8.py index 746414bdc9..ef80bcefd1 100644 --- a/Task/FizzBuzz/Python/fizzbuzz-8.py +++ b/Task/FizzBuzz/Python/fizzbuzz-8.py @@ -1 +1,17 @@ -[print("FizzBuzz") if i % 15 == 0 else print("Fizz") if i % 3 == 0 else print("Buzz") if i % 5 == 0 else print(i) for i in range(1,101)] +actions = { + 0: lambda i: print(i), + 1: lambda i: print("fizz"), + 2: lambda i: print("buzz"), + 3: lambda i: print("fizzbuzz"), +} + +for i in range(1, 101): + action_index = 0 + + if i % 3 == 0: + action_index += 1 + + if i % 5 == 0: + action_index += 2 + + actions[action_index](i) diff --git a/Task/FizzBuzz/Python/fizzbuzz-9.py b/Task/FizzBuzz/Python/fizzbuzz-9.py index b29ebd9a54..746414bdc9 100644 --- a/Task/FizzBuzz/Python/fizzbuzz-9.py +++ b/Task/FizzBuzz/Python/fizzbuzz-9.py @@ -1,13 +1 @@ -from itertools import cycle, izip, count, islice - -fizzes = cycle([""] * 2 + ["Fizz"]) -buzzes = cycle([""] * 4 + ["Buzz"]) -both = (f + b for f, b in izip(fizzes, buzzes)) - -# if the string is "", yield the number -# otherwise yield the string -fizzbuzz = (word or n for word, n in izip(both, count(1))) - -# print the first 100 -for i in islice(fizzbuzz, 100): - print i +[print("FizzBuzz") if i % 15 == 0 else print("Fizz") if i % 3 == 0 else print("Buzz") if i % 5 == 0 else print(i) for i in range(1,101)] diff --git a/Task/FizzBuzz/Smalltalk/fizzbuzz-4.st b/Task/FizzBuzz/Smalltalk/fizzbuzz-4.st index 12bbef1dcd..67f72c15dd 100644 --- a/Task/FizzBuzz/Smalltalk/fizzbuzz-4.st +++ b/Task/FizzBuzz/Smalltalk/fizzbuzz-4.st @@ -1,10 +1,12 @@ -1 to: 100 do: [:n | |r| - r := n rem: 15. - Transcript show: (r isZero - ifTrue:['fizzbuzz'] - ifFalse: [(#(3 6 9 12) includes: r) - ifTrue:['fizz'] - ifFalse:[((#(5 10) includes: r)) - ifTrue:['buzz'] - ifFalse:[n]]]); - cr]. +0 to: 100 do: [ :i | + (i \\ 3 = 0 and: [ i \\ 5 = 0 ]) + ifTrue: [ Transcript show: 'FizzBuzz'; cr. ] + ifFalse: [ + (i \\ 3 = 0) + ifTrue: [ Transcript show: 'Fizz'; cr. ]. + (i \\ 5 = 0) + ifTrue: [ Transcript show: 'Buzz'; cr. ]. + ((i \\ 3 ~= 0) and: [ i \\ 5 ~= 0 ]) + ifTrue: [ Transcript show: i printString; cr. ]. + ]. +]. diff --git a/Task/FizzBuzz/Smalltalk/fizzbuzz-5.st b/Task/FizzBuzz/Smalltalk/fizzbuzz-5.st index 83e4ca616e..12bbef1dcd 100644 --- a/Task/FizzBuzz/Smalltalk/fizzbuzz-5.st +++ b/Task/FizzBuzz/Smalltalk/fizzbuzz-5.st @@ -1,5 +1,10 @@ -fbz := (1 to: 100) asOrderedCollection. - 3 to: 100 by: 3 do: [:i | fbz at: i put: 'Fizz']. - 5 to: 100 by: 5 do: [:i | fbz at: i put: 'Buzz']. -15 to: 100 by: 15 do: [:i | fbz at: i put: 'FizzBuzz']. -fbz do: [:i | Transcript show: i; cr]. +1 to: 100 do: [:n | |r| + r := n rem: 15. + Transcript show: (r isZero + ifTrue:['fizzbuzz'] + ifFalse: [(#(3 6 9 12) includes: r) + ifTrue:['fizz'] + ifFalse:[((#(5 10) includes: r)) + ifTrue:['buzz'] + ifFalse:[n]]]); + cr]. diff --git a/Task/FizzBuzz/Smalltalk/fizzbuzz-6.st b/Task/FizzBuzz/Smalltalk/fizzbuzz-6.st index a0c292e114..83e4ca616e 100644 --- a/Task/FizzBuzz/Smalltalk/fizzbuzz-6.st +++ b/Task/FizzBuzz/Smalltalk/fizzbuzz-6.st @@ -1,5 +1,5 @@ -1 to: 100 do: [:i | |fb s| - fb := {i isDivisibleBy: 3. i isDivisibleBy: 5. nil}. - fb at: 3 put: (fb first | fb second) not. - s := '<1?Fizz:><2?Buzz:><3?{1}:>' format: {i printString}. - Transcript show: (s expandMacrosWithArguments: fb); cr]. +fbz := (1 to: 100) asOrderedCollection. + 3 to: 100 by: 3 do: [:i | fbz at: i put: 'Fizz']. + 5 to: 100 by: 5 do: [:i | fbz at: i put: 'Buzz']. +15 to: 100 by: 15 do: [:i | fbz at: i put: 'FizzBuzz']. +fbz do: [:i | Transcript show: i; cr]. diff --git a/Task/FizzBuzz/Smalltalk/fizzbuzz-7.st b/Task/FizzBuzz/Smalltalk/fizzbuzz-7.st new file mode 100644 index 0000000000..a0c292e114 --- /dev/null +++ b/Task/FizzBuzz/Smalltalk/fizzbuzz-7.st @@ -0,0 +1,5 @@ +1 to: 100 do: [:i | |fb s| + fb := {i isDivisibleBy: 3. i isDivisibleBy: 5. nil}. + fb at: 3 put: (fb first | fb second) not. + s := '<1?Fizz:><2?Buzz:><3?{1}:>' format: {i printString}. + Transcript show: (s expandMacrosWithArguments: fb); cr]. diff --git a/Task/Flow-control-structures/Uxntal/flow-control-structures.uxnatl b/Task/Flow-control-structures/Uxntal/flow-control-structures.uxnatl new file mode 100644 index 0000000000..7b135f37f9 --- /dev/null +++ b/Task/Flow-control-structures/Uxntal/flow-control-structures.uxnatl @@ -0,0 +1,24 @@ +|18 @Console/write + +|100 + +example + +BRK + +@example ( x y -- ) + ;start print/str + !&world ( goto &world ) + ;never print/str + &world ( label &world ) + ;end !print/str + +@print/str ( str* -- ) + LDAk .Console/write DEO + INC2 LDAk ?&str + POP2 + JMP2r + +@start "Hello, 2000 +@never "Never 20 "printed. 0a00 +@end "World! 0a00 diff --git a/Task/Floyd-Warshall-algorithm/EasyLang/floyd-warshall-algorithm.easy b/Task/Floyd-Warshall-algorithm/EasyLang/floyd-warshall-algorithm.easy index 0f7444170a..4d4159674a 100644 --- a/Task/Floyd-Warshall-algorithm/EasyLang/floyd-warshall-algorithm.easy +++ b/Task/Floyd-Warshall-algorithm/EasyLang/floyd-warshall-algorithm.easy @@ -1,9 +1,7 @@ -proc floydwarshall w[][] n . . +proc floydwarshall w[][] n . for i to n con[][] &= [ ] - for j to n - con[i][] &= 1 / 0 - . + for j to n : con[i][] &= 1 / 0 . for i to len w[][] con[w[i][1]][w[i][2]] = w[i][3] diff --git a/Task/Floyd-Warshall-algorithm/XPL0/floyd-warshall-algorithm.xpl0 b/Task/Floyd-Warshall-algorithm/XPL0/floyd-warshall-algorithm.xpl0 new file mode 100644 index 0000000000..ec04cf0579 --- /dev/null +++ b/Task/Floyd-Warshall-algorithm/XPL0/floyd-warshall-algorithm.xpl0 @@ -0,0 +1,49 @@ +include xpllib; \for Print + +proc FloydWarshall(Weights, Len, Verts); +int Weights, Len, Verts; +int Dist, Next, I, J, K, W; + + proc PrintResult; + int U, V; + [Print("Pair Dist Path\n"); + for I:= 0 to Verts-1 do + for J:= 0 to Verts-1 do + if I # J then + [U:= I+1; V:= J+1; + Print("%d -> %d %2d %d", U, V, Dist(I,J), U); + repeat U:= Next(U-1, V-1); + Print(" -> %d", U); + until U = V; + Print("\n"); + ]; + ]; + +[Dist:= Reserve(Verts*IntSize); +for I:= 0 to Verts-1 do + [Dist(I):= Reserve(Verts*IntSize); + for J:= 0 to Verts-1 do + Dist(I,J):= \Inf\10000; + ]; +for W:= 0 to Len-1 do + Dist(Weights(W,0)-1, Weights(W,1)-1):= Weights(W,2); +Next:= Reserve(Verts*IntSize); +for I:= 0 to Verts-1 do + [Next(I):= Reserve(Verts*IntSize); + for J:= 0 to Verts-1 do + Next(I,J):= if I=J then 0 else J+1; + ]; +for K:= 0 to Verts-1 do + for I:= 0 to Verts-1 do + for J:= 0 to Verts-1 do + if Dist(I,J) > Dist(I,K) + Dist(K,J) then + [Dist(I,J):= Dist(I,K) + Dist(K,J); + Next(I,J):= Next(I,K); + ]; +PrintResult; +]; + +int Weights; +[Weights:= [ [1, 3, -2], [2, 1, 4], [2, 3, 3], [3, 4, 2], [4, 2, -1] ]; +FloydWarshall(Weights, 5, 4); +] diff --git a/Task/Floyd-Warshall-algorithm/Zig/floyd-warshall-algorithm.zig b/Task/Floyd-Warshall-algorithm/Zig/floyd-warshall-algorithm.zig new file mode 100644 index 0000000000..fe8d6dd20d --- /dev/null +++ b/Task/Floyd-Warshall-algorithm/Zig/floyd-warshall-algorithm.zig @@ -0,0 +1,99 @@ +// floyd_warshall.zig +const std = @import("std"); + +const F64_INF = std.math.inf(f64); + +fn idx(i: usize, j: usize, n: usize) usize { + return i * n + j; +} + +fn printResult(dist: []const f64, next: []const usize, n: usize) void { + std.debug.print("(pair, dist, path)\n", .{}); + for (0..n) |i| { + for (0..n) |j| { + if (i == j) continue; + + const @"u0" = i + 1; + const v0 = j + 1; + + std.debug.print("({d} -> {d}, {d}, ", .{ + @"u0", v0, dist[idx(i, j, n)], + }); + + var u = @"u0"; + std.debug.print("{d}", .{u}); + while (u != v0) { + u = next[idx(u - 1, v0 - 1, n)]; + std.debug.print(" -> {d}", .{u}); + } + std.debug.print(")\n", .{}); + } + } +} + +fn solve( + allocator: std.mem.Allocator, + edges: []const [3]i64, // (u,v,w) 1‑based + n: usize, +) !void { + // Allocate matrices + var dist = try allocator.alloc(f64, n * n); + defer allocator.free(dist); + + var next_v = try allocator.alloc(usize, n * n); + defer allocator.free(next_v); + + // Initialise + for (dist)|*d| d.* = F64_INF; + for (next_v)|*x| x.* = 0; + + // Edge weights + for (edges) |e| { + const u = @as(usize, @intCast(e[0] - 1)); + const v = @as(usize, @intCast(e[1] - 1)); + dist[idx(u, v, n)] = @as(f64, @floatFromInt(e[2])); + } + + // Successor matrix + for (0..n) |i| { + for (0..n) |j| { + if (i != j) next_v[idx(i, j, n)] = j + 1; // 1‑based + } + } + + // Floyd–Warshall + for (0..n) |k| { + for (0..n) |i| { + for (0..n) |j| { + const dik = dist[idx(i, k, n)]; + const dkj = dist[idx(k, j, n)]; + if (std.math.isFinite(dik) and std.math.isFinite(dkj)) { + const alt = dik + dkj; + const pos = idx(i, j, n); + if (alt < dist[pos]) { + dist[pos] = alt; + next_v[pos] = next_v[idx(i, k, n)]; + } + } + } + } + } + + printResult(dist, next_v, n); +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const alloc = gpa.allocator(); + + const edges = [_][3]i64{ + .{ 1, 3, -2 }, + .{ 2, 1, 4 }, + .{ 2, 3, 3 }, + .{ 3, 4, 2 }, + .{ 4, 2, -1 }, + }; + + try solve(alloc, edges[0..], 4); +} diff --git a/Task/Floyds-triangle/Ballerina/floyds-triangle.ballerina b/Task/Floyds-triangle/Ballerina/floyds-triangle.ballerina new file mode 100644 index 0000000000..0a4976e6f9 --- /dev/null +++ b/Task/Floyds-triangle/Ballerina/floyds-triangle.ballerina @@ -0,0 +1,20 @@ +import ballerina/io; + +function floyd(int n) { + int k = 1; + foreach int i in 1...n { + foreach int j in 1...i { + int p = j < 9 ? 3 : 4; + io:print(k.toString().padStart(p)); + k += 1; + } + io:println(); + } +} + +public function main() { + io:println("Floyd(5):"); + floyd(5); + io:println("\nFloyd(14):"); + floyd(14); +} diff --git a/Task/Floyds-triangle/EasyLang/floyds-triangle.easy b/Task/Floyds-triangle/EasyLang/floyds-triangle.easy index 3e5e057b64..092f392cbd 100644 --- a/Task/Floyds-triangle/EasyLang/floyds-triangle.easy +++ b/Task/Floyds-triangle/EasyLang/floyds-triangle.easy @@ -1,17 +1,15 @@ func ceil h . f = floor h - if h <> f - f += 1 - . + if h <> f : f += 1 return f . -proc triangle n . . +proc triangle n . print n & " rows:" row = 1 while row <= n printme += 1 cols = ceil log10 (n * (n - 1) / 2 + nprinted + 2) - numfmt 0 cols + numfmt cols 0 write printme & " " nprinted += 1 if nprinted = row diff --git a/Task/Floyds-triangle/Objeck/floyds-triangle.objeck b/Task/Floyds-triangle/Objeck/floyds-triangle.objeck new file mode 100644 index 0000000000..567e784e01 --- /dev/null +++ b/Task/Floyds-triangle/Objeck/floyds-triangle.objeck @@ -0,0 +1,20 @@ +class Floyds { + function : Main(args : String[]) ~ Nil { + PrintTriangle(5); + PrintTriangle(14); + } + + function : PrintTriangle(n : Int) ~ Nil { + "{$n} rows:"->PrintLine(); + + rowNum := 1; printMe := 1; numsPrinted := 0; + for(; rowNum <= n; printMe++;){ + "{$printMe}\t"->Print(); + + if(++numsPrinted = rowNum){ + ""->PrintLine(); + rowNum++; numsPrinted := 0; + } + } + } +} diff --git a/Task/Floyds-triangle/YAMLScript/floyds-triangle.ys b/Task/Floyds-triangle/YAMLScript/floyds-triangle.ys index b633b847da..3737ab63e1 100644 --- a/Task/Floyds-triangle/YAMLScript/floyds-triangle.ys +++ b/Task/Floyds-triangle/YAMLScript/floyds-triangle.ys @@ -1,6 +1,6 @@ !YS-v0 -defn main(n): +defn main(n=14): nums =: range().map(inc).map(str) rows =: loop row-n 1, nums nums, rows []: diff --git a/Task/Forest-fire/EasyLang/forest-fire.easy b/Task/Forest-fire/EasyLang/forest-fire.easy index e524ca0c60..f2e94eacce 100644 --- a/Task/Forest-fire/EasyLang/forest-fire.easy +++ b/Task/Forest-fire/EasyLang/forest-fire.easy @@ -3,62 +3,51 @@ p_tree = 0.002 # len f[] 102 * 102 len p[] len f[] -background 100 -clear -for r = 0 to 99 - for c = 0 to 99 - i = r * 102 + c + 104 - if randomf < 0.5 - f[i] = 1 - . - . +gbackground 100 +gclear +for r = 0 to 99 : for c = 0 to 99 + i = r * 102 + c + 104 + if randomf < 0.5 : f[i] = 1 . timer 0 # subr show - for r = 0 to 99 - for c = 0 to 99 - i = r * 102 + c + 104 - h = f[i] - if h <> p[i] - move c + 0.5 r + 0.5 - if h = 0 - color 100 - circle 0.6 - elif h = 1 - color 151 - circle 0.5 - else - color 9 * 100 + (18 - 2 * h) * 10 - circle 0.5 - . + for r = 0 to 99 : for c = 0 to 99 + i = r * 102 + c + 104 + h = f[i] + if h <> p[i] + if h = 0 + gcolor 100 + gcircle c + 0.5 r + 0.5 0.6 + elif h = 1 + gcolor 151 + gcircle c + 0.5 r + 0.5 0.5 + else + gcolor 9 * 100 + (18 - 2 * h) * 10 + gcircle c + 0.5 r + 0.5 0.5 . . . . subr update swap f[] p[] - for r = 0 to 99 - for c = 0 to 99 - i = r * 102 + c + 104 - if p[i] = 0 - f[i] = 0 - if randomf < p_tree - f[i] = 1 - . - elif p[i] = 1 - f[i] = 1 - s = p[i - 103] + p[i - 102] + p[i - 101] - s += p[i - 1] + p[i + 1] - s += p[i + 101] + p[i + 102] + p[i + 103] - if s >= 9 or randomf < p_fire - f[i] = 9 - . - elif p[i] = 4 - f[i] = 0 - else - f[i] = p[i] - 1 + for r = 0 to 99 : for c = 0 to 99 + i = r * 102 + c + 104 + if p[i] = 0 + f[i] = 0 + if randomf < p_tree : f[i] = 1 + elif p[i] = 1 + f[i] = 1 + s = p[i - 103] + p[i - 102] + p[i - 101] + s += p[i - 1] + p[i + 1] + s += p[i + 101] + p[i + 102] + p[i + 103] + if s >= 9 or randomf < p_fire + f[i] = 9 . + elif p[i] = 4 + f[i] = 0 + else + f[i] = p[i] - 1 . . . diff --git a/Task/Forest-fire/J/forest-fire-3.j b/Task/Forest-fire/J/forest-fire-3.j new file mode 100644 index 0000000000..cb31a84084 --- /dev/null +++ b/Task/Forest-fire/J/forest-fire-3.j @@ -0,0 +1,16 @@ +mt=:{{ (? 0) I.~ +/\ (y { x) }} NB. Mutate state function +pad=:0,0,~0(,.)0,.~] NB. Pading with zero +ib=:+./@:(=&2)@, NB. IsBurning to check if fire in the area +f=:0.005 NB. Probability of starting fire +p=:0.05 NB. Probability of three +tm0=:3 3$(1-p),p,0,0,(1-f),f,1,0,0 NB. Transition matrix of state with no fire in area +tm1=:3 3 $(1-p),p,0,0,0,1,1,0,0 NB. Transition matrix of state with fire in area + +opt0=:[:tm0&mt(<1 1){] NB. Option #0 (for mutation with no fire in area) +opt1=:[:tm1&mt(<1 1){] NB. Option #1 (for mutation with fire in area) + +ff=:(,.~1 3)([: pad(opt0`opt1@.ib);._3)] NB. Core function FireForest + + NB. Using it.... +dt =: 10 10 $ 0 NB. Create a empty 10x10 matrix +ff ^:(i.100) dt NB. Iterate 100 time, output include initial empty matrix. diff --git a/Task/Forest-fire/J/forest-fire-4.j b/Task/Forest-fire/J/forest-fire-4.j new file mode 100644 index 0000000000..1ccf79b0b7 --- /dev/null +++ b/Task/Forest-fire/J/forest-fire-4.j @@ -0,0 +1,10 @@ +0 0 0 0 0 0 0 0 0 0 +0 1 1 1 1 1 1 1 1 0 +0 1 2 1 1 1 1 0 1 0 +0 1 0 1 1 0 1 1 0 0 +0 1 1 1 0 0 1 0 0 0 +0 0 0 0 2 0 2 0 0 0 +0 0 0 2 1 0 0 0 1 0 +0 1 0 0 0 0 0 2 1 0 +0 1 0 2 0 0 0 0 1 0 +0 0 0 0 0 0 0 0 0 0 diff --git a/Task/Formatted-numeric-output/ALGOL-68/formatted-numeric-output.alg b/Task/Formatted-numeric-output/ALGOL-68/formatted-numeric-output-1.alg similarity index 100% rename from Task/Formatted-numeric-output/ALGOL-68/formatted-numeric-output.alg rename to Task/Formatted-numeric-output/ALGOL-68/formatted-numeric-output-1.alg diff --git a/Task/Formatted-numeric-output/ALGOL-68/formatted-numeric-output-2.alg b/Task/Formatted-numeric-output/ALGOL-68/formatted-numeric-output-2.alg new file mode 100644 index 0000000000..b066063291 --- /dev/null +++ b/Task/Formatted-numeric-output/ALGOL-68/formatted-numeric-output-2.alg @@ -0,0 +1,59 @@ +( + OP UNSUPPRESS = ( STRING v )STRING: # replace leading spaces with zeros # + IF LWB v > UPB v + THEN v # empty string # + ELSE STRING result := v; + INT p1 := LWB result; + IF result[ p1 ] = " " THEN result[ p1 ] := "0" FI; + FOR p FROM LWB result + 1 TO UPB result DO + CHAR c = result[ p ]; + IF c = " " THEN result[ p ] := "0" + ELIF c = "-" OR c = "+" THEN result[ p ] := "0"; result[ p1 ] := c + ELIF c = "e" THEN p1 := p + 1 + FI + OD; + result + FI # UNSUPPRESS # ; + OP SUPPRESSPLUS = ( STRING v )STRING: # replace leading space/zero with "+" # + IF LWB v > UPB v THEN v ELIF CHAR c = v[ LWB v ]; c = "+" OR c = "0" THEN " " + v[ LWB v + 1 : ] ELSE v FI; + PRIO SUPPRESS = 5; # suppress up to d leading zeros # + OP SUPPRESS = ( STRING v, INT d )STRING: + IF LWB v > UPB v + THEN v + ELIF CHAR c1 = v[ LWB v ]; c1 /= "+" AND c1 /= "-" AND c1 /= "0" + THEN v + ELSE INT len = ( UPB v - LWB v ) + 1; + INT max p = ( LWB v - 1 ) + IF len > d THEN d ELSE len FI; + STRING result := v; + CHAR sign char = IF c1 = "0" THEN " " ELSE c1 FI; + result[ LWB result ] := " "; + BOOL inserted sign := FALSE; + FOR p FROM LWB result + 1 TO max p + WHILE CHAR c = result[ p ]; + IF c /= "0" THEN result[ p - 1 ] := sign char; inserted sign := TRUE FI; + NOT inserted sign + DO result[ p ] := " " + OD; + IF NOT inserted sign THEN result[ max p ] := sign char FI; + result + FI # SUPPRESS # ; + + REAL r=exp(pi)-pi; + print((r,newline)); + print((fixed(-r,16,4),newline)); + print((fixed(r,-16,4),newline)); + print((fixed(r,16,4),newline)); + print((float(r,16,4,1),newline)); + + print((SUPPRESSPLUS UNSUPPRESS fixed(-r,-10,4),newline)); + print((SUPPRESSPLUS UNSUPPRESS fixed(r,-10,4),newline)); + print((UNSUPPRESS fixed(r,10,4),newline)); + print((UNSUPPRESS fixed(ABS r,-10,4),newline)); + + print((fixed(ABS r,-10,4),newline)); + + print((SUPPRESSPLUS UNSUPPRESS fixed(-r,12,4) SUPPRESS 5,newline)); + print((SUPPRESSPLUS UNSUPPRESS float(-r,16,4,-3) SUPPRESS 5,newline)); + print((SUPPRESSPLUS UNSUPPRESS float(-r,-13,4,3),newline)); + print((SUPPRESSPLUS UNSUPPRESS float(r,-17,4,5),newline)) +) diff --git a/Task/Formatted-numeric-output/Applesoft-BASIC/formatted-numeric-output.basic b/Task/Formatted-numeric-output/Applesoft-BASIC/formatted-numeric-output.basic new file mode 100644 index 0000000000..4c13390339 --- /dev/null +++ b/Task/Formatted-numeric-output/Applesoft-BASIC/formatted-numeric-output.basic @@ -0,0 +1,27 @@ + 0 P = 5:T = 3:R = 7.125: GOSUB 100"FORMATTED NUMERIC OUTPUT + 9 END + +REM FORMATTED NUMERIC OUTPUT + +REM Given R a Real number +REM and P as left Padding amount, P$ as the Padding +REM and T as the Trailing amount, T$ as the Trailing padding + + 100 R$ = STR$ (R):L = LEN (R$):S$ = "": IF MID$ (R$,1,1) = " " THEN S$ = " ":L = L - 1:R$ = RIGHT$ (R$,L) + 110 IF MID$ (R$,1,1) = "-" THEN L = L - 1:R$ = RIGHT$ (R$,L):S$ = S$ + "-": REM SIGN + 120 LET D$ = "":D = 0:E$ = "":E = 0: REM DECIMAL, EXPONENT and POSITIONS + 130 IF P$ = "" THEN P$ = "0": REM LEFT PADDING + 140 IF T$ = "" THEN T$ = "0": REM TRAILING PADDING + 150 FOR I = 1 TO L + 160 LET C$ = MID$ (R$,I,1) + 170 IF C$ = "." THEN D = I + 180 IF C$ = "E" THEN E = I + 190 NEXT I + 200 IF E THEN E$ = MID$ (R$,E):R$ = LEFT$ (R$,E - 1) + 210 IF D THEN D$ = MID$ (R$,D + 1):R$ = LEFT$ (R$,D - 1) + 220 LET PAD$ = "": FOR I = 1 TO P:PAD$ = P$ + PAD$: NEXT + 230 PRINT S$ RIGHT$ (PAD$ + R$,P); + 240 LET PAD$ = "": FOR I = 1 TO T:PAD$ = PAD$ + T$: NEXT + 250 IF T THEN PRINT "." LEFT$ (D$ + PAD$,T); + 260 PRINT E$; + 270 RETURN diff --git a/Task/Formatted-numeric-output/JavaScript/formatted-numeric-output.js b/Task/Formatted-numeric-output/JavaScript/formatted-numeric-output.js index 4d1f797beb..a48931e09e 100644 --- a/Task/Formatted-numeric-output/JavaScript/formatted-numeric-output.js +++ b/Task/Formatted-numeric-output/JavaScript/formatted-numeric-output.js @@ -1,3 +1,18 @@ -var n = 123; -var str = ("00000" + n).slice(-5); -alert(str); +function fmt(n, options) { + const [whole, fraction] = String(n).split('.', 2) + return [ + whole.padStart(options.whole || 1, '0'), + (fraction ?? '').padEnd(options.fraction, '0').slice(0, options.fraction), + ].filter(Boolean).join('.') +} + +for (const [n, options] of [ + [123, { whole: 1, fraction: 2 }], // 123.00 + [123, { whole: 5, fraction: 2 }], // 00123.00 + [123, { whole: 5, fraction: 0 }], // 00123 + [0.5, { whole: 1, fraction: 2 }], // 0.50 + [0.5, { whole: 5, fraction: 2 }], // 00000.50 + [0.5, { whole: 5, fraction: 0 }], // 00000 +]) { + console.log(fmt(n, options)) +} diff --git a/Task/Fortunate-numbers/EasyLang/fortunate-numbers.easy b/Task/Fortunate-numbers/EasyLang/fortunate-numbers.easy index 2c1cb9afb6..dc96747c37 100644 --- a/Task/Fortunate-numbers/EasyLang/fortunate-numbers.easy +++ b/Task/Fortunate-numbers/EasyLang/fortunate-numbers.easy @@ -1,9 +1,7 @@ fastfunc isprim num . i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 @@ -15,22 +13,18 @@ fastfunc nextprim prim . . return prim . -proc insert e . d[] . +proc insert &d[] e . for i = 1 to len d[] if d[i] >= e - if d[i] = e - return - . + if d[i] = e : return break 1 . . d[] &= 0 - for i = len d[] downto i + 1 - d[i] = d[i - 1] - . + for i = len d[] downto i + 1 : d[i] = d[i - 1] d[i] = e . -proc fortunates . . +proc fortunates . maxint = pow 2 53 primorial = 1 prim = 2 @@ -42,10 +36,8 @@ proc fortunates . . while isprim (primorial + j) = 0 j = j + 2 . - insert j fortuns[] - . - for i to 8 - write fortuns[i] & " " + insert fortuns[] j . + for i to 8 : write fortuns[i] & " " . fortunates diff --git a/Task/Fortunate-numbers/REXX/fortunate-numbers-1.rexx b/Task/Fortunate-numbers/REXX/fortunate-numbers-1.rexx deleted file mode 100644 index a39ae2d9b5..0000000000 --- a/Task/Fortunate-numbers/REXX/fortunate-numbers-1.rexx +++ /dev/null @@ -1,54 +0,0 @@ -/*REXX program finds/displays fortunate numbers N, where N is specified (default=8).*/ -numeric digits 12 -parse arg n cols . /*obtain optional argument from the CL.*/ -if n=='' | n=="," then n= 8 /*Not specified? Then use the default.*/ -if cols=='' | cols=="," then cols= 10 /* " " " " " " */ -call genP n**2 /*build array of semaphores for primes.*/ -pp.= 1 - do i=1 for n+1; im= i - 1; pp.i= pp.im * @.i /*calculate primorial numbers*/ - end /*i*/ -i=i-1; call genp pp.i + 1000 - title= ' fortunate numbers' -w= 10 /*maximum width of a number in any col.*/ -say ' index │'center(title, 1 + cols*(w+1) ) -say '───────┼'center("" , 1 + cols*(w+1), '─') -found= 0; idx= 1 /*number of fortunate (so far) & index.*/ -!!.= 0; maxFN= 0 /*(stemmed) array of fortunate numbers*/ - do j=1 until found==n; pt= pp.j /*search for fortunate numbers in range*/ - pt= pp.j /*get the precalculated primorial prime*/ - do m=3 by 2; t= pt + m /*find M that satisfies requirement. */ - if !.t=='' then leave /*Is !.t prime? Then we found a good M*/ - end /*m*/ - if !!.m then iterate /*Fortunate # already found? Then skip*/ - !!.m= 1; found= found + 1 /*assign fortunate number; bump count.*/ - maxFN= max(maxFN, t) /*obtain max fortunate # for displaying*/ - end /*j*/ -$=; finds= 0 /*$: line of output; FINDS: count.*/ - do k=1 for maxFN; if \!!.k then iterate /*show the fortunate numbers we found. */ - finds= finds + 1 /*bump the count of numbers (for $). */ - c= commas(k) /*maybe add commas to the number. */ - $= $ right(c, max(w, length(c) ) ) /*add a nice prime ──► list, allow big#*/ - if found//cols\==0 then iterate /*have we populated a line of output? */ - say center(idx, 7)'│' substr($, 2); $= /*display what we have so far (cols). */ - idx= idx + cols /*bump the index count for the output*/ - end /*k*/ - -if $\=='' then say center(idx, 7)"│" substr($, 2) /*possible display residual output.*/ -say '───────┴'center("" , 1 + cols*(w+1), '─') /*display the foot separator. */ -say -say 'Found ' commas(found) title -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11 /*define some low primes. */ - !.=0; !.2=; !.3=; !.5=; !.7=; !.11= /* " " " " semaphores. */ - #= 5; sq.#= @.#**2 /*squares of low primes.*/ - do j=@.#+2 by 2 to arg(1) /*find odd primes from here on. */ - parse var j '' -1 _; if _==5 then iterate /*J ÷ by 5 ? */ - if j//3==0 then iterate; if j//7==0 then iterate /*" " " 3?; J ÷ by 7 ? */ - do k=5 while sq.k<=j /* [↓] divide by the known odd primes.*/ - if j // @.k == 0 then iterate j /*Is J ÷ X? Then not prime. ___ */ - end /*k*/ /* [↑] only process numbers ≤ √ J */ - #= #+1; @.#= j; sq.#= j*j; !.j= /*bump # of Ps; assign next P; P²; P# */ - end /*j*/; return diff --git a/Task/Fortunate-numbers/REXX/fortunate-numbers-2.rexx b/Task/Fortunate-numbers/REXX/fortunate-numbers.rexx similarity index 92% rename from Task/Fortunate-numbers/REXX/fortunate-numbers-2.rexx rename to Task/Fortunate-numbers/REXX/fortunate-numbers.rexx index 5d4aa0d250..d621367661 100644 --- a/Task/Fortunate-numbers/REXX/fortunate-numbers-2.rexx +++ b/Task/Fortunate-numbers/REXX/fortunate-numbers.rexx @@ -1,6 +1,9 @@ +-- 8 May 2025 include Settings -say version; say 'Fortunate numbers'; say +say 'FORTUNATE NUMBERS' +say version +say numeric digits 155 call GetPrimorials 75 call GenerateFortunate 75 @@ -21,7 +24,7 @@ arg x say 'Generate fortunate numbers...' work. = 0; m = 0; n = 0 do i = 1 to x - p = prmo.primorial.i + p = prmo.i do j = 3 by 2 m = m+1 if Prime(p+j) then @@ -57,5 +60,6 @@ return include Numbers include Sequences include Functions +include Special include Constants include Abend diff --git a/Task/Four-bit-adder/Ballerina/four-bit-adder.ballerina b/Task/Four-bit-adder/Ballerina/four-bit-adder.ballerina new file mode 100644 index 0000000000..b995469a4c --- /dev/null +++ b/Task/Four-bit-adder/Ballerina/four-bit-adder.ballerina @@ -0,0 +1,31 @@ +import ballerina/io; + +function xor(byte a, byte b) returns byte { + return a & (~b) | b & (~a); +} + +function ha(byte a, byte b) returns [byte, byte] { + return [xor(a, b), a & b]; +} + +function fa(byte a, byte b, byte c0) returns [byte, byte] { + var [sa, ca] = ha(a, c0); + var [s, cb] = ha(sa, b); + var c1 = ca | cb; + return [s, c1]; +} + +function add4(byte a3, byte a2, byte a1, byte a0, byte b3, byte b2, byte b1, byte b0) + returns [byte, byte, byte, byte, byte] { + var [s0, c0] = fa(a0, b0, 0); + var [s1, c1] = fa(a1, b1, c0); + var [s2, c2] = fa(a2, b2, c1); + var [s3, v] = fa(a3, b3, c2); + return [v, s3, s2, s1, s0]; +} + +public function main() { + // add 10+9 result should be [1, 0, 0, 1, 1] + var sum = add4(1, 0, 1, 0, 1, 0, 0, 1); + io:println(re `,`.replaceAll(sum.toString(), ", ")); +} diff --git a/Task/Four-bit-adder/EasyLang/four-bit-adder.easy b/Task/Four-bit-adder/EasyLang/four-bit-adder.easy index a7fb1f576f..0596b197e5 100644 --- a/Task/Four-bit-adder/EasyLang/four-bit-adder.easy +++ b/Task/Four-bit-adder/EasyLang/four-bit-adder.easy @@ -1,18 +1,18 @@ -proc xor a b . r . +proc xor a b &r . na = bitand bitnot a 1 nb = bitand bitnot b 1 r = bitor bitand a nb bitand b na . -proc half_add a b . s c . +proc half_add a b &s &c . xor a b s c = bitand a b . -proc full_add a b c . s g . +proc full_add a b c &s &g . half_add a c x y half_add x b s z g = bitor y z . -proc bit4add a4 a3 a2 a1 b4 b3 b2 b1 . s4 s3 s2 s1 c . +proc bit4add a4 a3 a2 a1 b4 b3 b2 b1 &s4 &s3 &s2 &s1 &c . full_add a1 b1 0 s1 c full_add a2 b2 c s2 c full_add a3 b3 c s3 c diff --git a/Task/Fractal-tree/EasyLang/fractal-tree.easy b/Task/Fractal-tree/EasyLang/fractal-tree.easy index 8fee6f444d..ef4681c547 100644 --- a/Task/Fractal-tree/EasyLang/fractal-tree.easy +++ b/Task/Fractal-tree/EasyLang/fractal-tree.easy @@ -1,18 +1,12 @@ color 555 -proc tree x y deg n . . - if n > 0 - linewidth n * 0.4 - move x y - x += cos deg * n * 1.3 * (randomf + 0.5) - y += sin deg * n * 1.3 * (randomf + 0.5) - line x y - tree x y deg - 20 n - 1 - tree x y deg + 20 n - 1 +proc tree x y angle depth . + glinewidth depth * 0.4 + xn = x + cos angle * depth * 1.4 * (randomf + 0.5) + yn = y + sin angle * depth * 1.4 * (randomf + 0.5) + gline x y xn yn + if depth > 1 + tree xn yn (angle - 20) (depth - 1) + tree xn yn (angle + 20) (depth - 1) . . -timer 0 -on timer - clear - tree 50 10 90 10 - timer 2 -. +tree 50 10 90 10 diff --git a/Task/Fractran/EasyLang/fractran.easy b/Task/Fractran/EasyLang/fractran.easy index 5ee0b75bf6..1fed677ff9 100644 --- a/Task/Fractran/EasyLang/fractran.easy +++ b/Task/Fractran/EasyLang/fractran.easy @@ -1,4 +1,4 @@ -proc fractran prog$ val limit . r[] . +func[] fractran prog$ val limit . for s$ in strsplit prog$ " " : n[][] &= number strsplit s$ "/" for n to limit r[] &= val @@ -8,19 +8,19 @@ proc fractran prog$ val limit . r[] . if i > len n[][] : break 1 val = val / n[i][2] * n[i][1] . + return r[] . p$ = "17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11 15/14 15/2 55/1" -fractran p$ 2 15 r[] -print r[] +print fractran p$ 2 15 # -proc sort . d[] . +proc sort &d[] . for i = 1 to len d[] - 1 for j = i + 1 to len d[] if d[j] < d[i] : swap d[j] d[i] . . . -fractran p$ 2 1000 r[] +r[] = fractran p$ 2 1000 sort r[] i = 1 prim = 2 diff --git a/Task/Fractran/Julia/fractran.jl b/Task/Fractran/Julia/fractran.jl index 7bd1303fe5..87f70c2989 100644 --- a/Task/Fractran/Julia/fractran.jl +++ b/Task/Fractran/Julia/fractran.jl @@ -1,29 +1,70 @@ -using Base.Iterators: filter, map, take -using Dates: now, seconds +using .Iterators, BenchmarkTools +using Primes: Factorization, factor -struct FRACTRAN - P::Vector{Rational{BigInt}} - i::BigInt +# type alias for abbreviation +Factors = Factorization{Int} + +# iterable stuct with parametric type polymorphism +struct Fractran{T} + program::Vector{@NamedTuple{num::T, den::T}} + input::Int + + # inner constructor + function Fractran{T}(program::Vector{Rational{Int}}, input::Int) where T + c = Dict(BigInt => identity, Factors => factor)[T] + new{T}([(num = c(f.num), den = c(f.den)) for f ∈ program], input) + end end -# a new method for the builtin function 'iterate' to make the Fractran program run -Base.iterate(ft::FRACTRAN, n = ft.i) = - for f in ft.P +# methods for Fractran with n::BigInt +Base.iterate(ft::Fractran{BigInt}, n = big(ft.input)) = + for f ∈ ft.program if iszero(n % f.den) n = n ÷ f.den * f.num return n, n end end -"lazy generation of Fractran output sequence" -out(ft::FRACTRAN) = map(trailing_zeros, filter(ispow2, ft)) +iters(ft::Fractran{BigInt}) = ft -"convenient Fractran scripting" -macro P_str(s) eval(Meta.parse(replace("[$s]", "/" => "//"))) end +output(ft::Fractran{BigInt}) = (trailing_zeros(n) for n ∈ ft if ispow2(n)) -primes = FRACTRAN(P"17/91, 78/85, 19/51, 23/38, 29/33, 77/29, 95/23, 77/19, 1/17, 11/13, 13/11, 15/14, 15/2, 55/1", 2) +# methods for Fractran with n::Factorization{Int} +Base.iterate(ft::Fractran{Factors}, n = factor(ft.input)) = + for f ∈ ft.program + if all(n[p] ≥ e for (p, e) ∈ f.den) + for (p, e) ∈ f.den n[p] -= e end + for (p, e) ∈ f.num n[p] += e end + return n, n + end + end -println("2, ", join(take(primes, 20), ", "), "...") -t = now() -join(stdout, take(out(primes), 25), ", ") -println("...\n25 primes in $(seconds(now() - t)) seconds") +iters(ft::Fractran{Factors}) = (prod(n) for n ∈ ft) + +output(ft::Fractran{Factors}) = (n[2] for n ∈ ft if + all((iszero(e) || (p == 2)) for (p, e) ∈ n)) + +# convenient Fractran scripting +macro ft_str(s::String) + eval(Meta.parse(replace("[$s]", "/" => "//"))) +end + +# instantiation of Fractran example generating prime numbers +primes(T) = Fractran{T}(ft"17/91, 78/85, 19/51, 23/38, 29/33, 77/29, + 95/23, 77/19, 1/17, 11/13, 13/11, 15/14, 15/2, 55/1", 2) + +# Output including Benchmark +ilim = 20; plim = 45 + +function printout(T) + println("\n$ilim iterations and output of $plim prime numbers using ", T) + println(join(take(iters(primes(T)), ilim), ", "), "…") + join(stdout, take(output(primes(T)), plim), ", ") + print("…\nBenchmark: $plim primes in") +end + +printout(BigInt) +@btime collect(take(output(primes(BigInt)), plim)) + +printout(Factors) +@btime collect(take(output(primes(Factors)), plim)); diff --git a/Task/Fractran/Odin/fractran.odin b/Task/Fractran/Odin/fractran.odin new file mode 100644 index 0000000000..bae9287c2f --- /dev/null +++ b/Task/Fractran/Odin/fractran.odin @@ -0,0 +1,77 @@ +package main + +import "core:fmt" +import "core:os" +import "core:strconv" +import "core:strings" +import "core:text/match" +import "core:math" + + +main :: proc() { + // fmt.println(os.args) + + n:int + number:int + number_conv:bool + fracts:[dynamic]int + defer delete(fracts) + + n,number_conv = strconv.parse_int(os.args[1]) + assert(number_conv, "Number must be given in first place!") + assert(len(os.args)>1,"no command line arguments given") + + data:="17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11 15/14 15/2 55/1" + + ss := strings.split(string(data), " ") + defer delete(ss) + + + a: [dynamic]string + dummy:[]string + defer delete(a) + defer delete(dummy) + + for i in ss{ + dummy =strings.split(i,"/") + for j in dummy{ + // fmt.println(j) + + append_elem(&a,j) + } + } + + for k in a{ + // fmt.println(k) + number,number_conv = strconv.parse_int(k) + assert(number_conv, "Number must be given in program") + append_elem(&fracts,number) + } + + + // fmt.println(len(fracts)) + cond:int + buf: [256]byte + bb:int + end:=0 + fmt.println(n) + frac: for j:=0;j 0 then do - call Time('r'); r = Stirling(x); e = Format(Time('e'),,3) + call Time('r'); r = Stirling(x)+0; e = Format(Time('e'),,3) say 'Stirling' Format(x,4,1) r '('e 'seconds)' end end @@ -31,25 +34,25 @@ w = '-99.9 99.9' do i = 1 to Words(w) x = Word(w,i) numeric digits Min(60,n) - call Time('r'); r = Gamma(x); e = Format(Time('e'),,3) + call Time('r'); r = Gamma(x)+0; e = Format(Time('e'),,3) say 'Lanczos ' Format(x,4,1) r '('e 'seconds)' numeric digits n - call Time('r'); r = Gamma(x); e = Format(Time('e'),,3) + call Time('r'); r = Gamma(x)+0; e = Format(Time('e'),,3) say 'Spouge ' Format(x,4,1) r '('e 'seconds)' if x > 0 then do - call Time('r'); r = Stirling(x); e = Format(Time('e'),,3) + call Time('r'); r = Stirling(x)+0; e = Format(Time('e'),,3) say 'Stirling' Format(x,4,1) r '('e 'seconds)' end end exit Stirling: -/* Sterling */ procedure expose glob. fact. arg x return Sqrt(2*Pi()/x) * Power(x/e(),x) include Constants include Functions +include Special include Numbers include Abend diff --git a/Task/Gapful-numbers/Ballerina/gapful-numbers.ballerina b/Task/Gapful-numbers/Ballerina/gapful-numbers.ballerina new file mode 100644 index 0000000000..867bb7d72a --- /dev/null +++ b/Task/Gapful-numbers/Ballerina/gapful-numbers.ballerina @@ -0,0 +1,26 @@ +import ballerina/io; + +public function main() { + int[] starts = [100, 1e6, 1e7, 1e9, 7123]; + int[] counts = [30, 15, 15, 10, 25]; + foreach int i in 0..= 10 * pow { pow *= 10; } + } + io:println("\n"); + } +} diff --git a/Task/Gapful-numbers/EasyLang/gapful-numbers.easy b/Task/Gapful-numbers/EasyLang/gapful-numbers.easy index 3b1c7a2403..ef8893d1a1 100644 --- a/Task/Gapful-numbers/EasyLang/gapful-numbers.easy +++ b/Task/Gapful-numbers/EasyLang/gapful-numbers.easy @@ -1,12 +1,10 @@ func gapful n . m = n l = n mod 10 - while m >= 10 - m = m div 10 - . + while m >= 10 : m = m div 10 return if n mod (m * 10 + l) = 0 . -proc show n gaps . . +proc show n gaps . print "First " & gaps & " gapful numbers >= " & n while inc < gaps if gapful n = 1 diff --git a/Task/Gauss-Jordan-matrix-inversion/EasyLang/gauss-jordan-matrix-inversion.easy b/Task/Gauss-Jordan-matrix-inversion/EasyLang/gauss-jordan-matrix-inversion.easy index dac0cbf67d..3027f65812 100644 --- a/Task/Gauss-Jordan-matrix-inversion/EasyLang/gauss-jordan-matrix-inversion.easy +++ b/Task/Gauss-Jordan-matrix-inversion/EasyLang/gauss-jordan-matrix-inversion.easy @@ -1,39 +1,31 @@ -proc rref . m[][] . +proc rref &m[][] . nrow = len m[][] ncol = len m[1][] lead = 1 for r to nrow - if lead > ncol - return - . + if lead > ncol : return i = r while m[i][lead] = 0 i += 1 if i > nrow i = r lead += 1 - if lead > ncol - return - . + if lead > ncol : return . . swap m[i][] m[r][] m = m[r][lead] - for k to ncol - m[r][k] /= m - . + for k to ncol : m[r][k] /= m for i to nrow if i <> r m = m[i][lead] - for k to ncol - m[i][k] -= m * m[r][k] - . + for k to ncol : m[i][k] -= m * m[r][k] . . lead += 1 . . -proc inverse . mat[][] inv[][] . +proc inverse &mat[][] &inv[][] . inv[][] = [ ] ln = len mat[][] for i to ln @@ -43,9 +35,7 @@ proc inverse . mat[][] inv[][] . . aug[][] &= [ ] len aug[i][] 2 * ln - for j to ln - aug[i][j] = mat[i][j] - . + for j to ln : aug[i][j] = mat[i][j] aug[i][ln + i] = 1 . rref aug[][] diff --git a/Task/Gauss-Jordan-matrix-inversion/JavaScript/gauss-jordan-matrix-inversion.js b/Task/Gauss-Jordan-matrix-inversion/JavaScript/gauss-jordan-matrix-inversion.js new file mode 100644 index 0000000000..854bc332e7 --- /dev/null +++ b/Task/Gauss-Jordan-matrix-inversion/JavaScript/gauss-jordan-matrix-inversion.js @@ -0,0 +1,99 @@ +// Vector and matrix types +// In JavaScript, we'll use arrays directly + +function printMatrix(matrix, title) { + console.log(title); + for (const row of matrix) { + console.log(row.map(x => x.toString().padStart(10)).join('')); + } +} + +function createIdentityMatrix(n) { + const result = Array(n).fill().map(() => Array(n).fill(0)); + for (let i = 0; i < n; i++) { + result[i][i] = 1; + } + return result; +} + +function inverse(matrix) { + const n = matrix.length; + + // Check if it's a square matrix + for (const row of matrix) { + if (row.length !== n) { + throw new Error("Not a square matrix"); + } + } + + // Create identity matrix for the result + const b = createIdentityMatrix(n); + + // Create a copy of the input matrix + const a = matrix.map(row => [...row]); + + for (let k = 0; k < n; k++) { + let iMax = 0; + let max = -1; + + for (let i = k; i < n; i++) { + const row = a[i]; + + // Compute scale factor s = max abs in row + let s = -1; + for (let j = k; j < n; j++) { + const x = Math.abs(row[j]); + if (x > s) { + s = x; + } + } + + if (s === 0) { + throw new Error("Irregular matrix"); + } + + // Scale the abs used to pick the pivot + const abs = Math.abs(row[k]) / s; + if (abs > max) { + iMax = i; + max = abs; + } + } + + // Swap rows if needed + if (k !== iMax) { + [a[k], a[iMax]] = [a[iMax], a[k]]; + [b[k], b[iMax]] = [b[iMax], b[k]]; + } + + const akk = a[k][k]; + + for (let j = 0; j < n; j++) { + a[k][j] /= akk; + b[k][j] /= akk; + } + + for (let i = 0; i < n; i++) { + if (i !== k) { + const aik = a[i][k]; + for (let j = 0; j < n; j++) { + a[i][j] -= a[k][j] * aik; + b[i][j] -= b[k][j] * aik; + } + } + } + } + + return b; +} + +function main() { + const a = [[1, 2, 3], [4, 1, 6], [7, 8, 9]]; + printMatrix(inverse(a), "Inverse of A is:\n"); + + const b = [[2, -1, 0], [-1, 2, -1], [0, -1, 2]]; + printMatrix(inverse(b), "Inverse of B is:\n"); +} + +// Run the main function +main(); diff --git a/Task/Gaussian-elimination/EasyLang/gaussian-elimination.easy b/Task/Gaussian-elimination/EasyLang/gaussian-elimination.easy index 12bd0ba26f..49718d4e90 100644 --- a/Task/Gaussian-elimination/EasyLang/gaussian-elimination.easy +++ b/Task/Gaussian-elimination/EasyLang/gaussian-elimination.easy @@ -1,4 +1,4 @@ -proc gauss_elim . a[][] b[] x[] . +proc gauss_elim &a[][] &b[] &x[] . n = len a[][] for i to n maxr = i diff --git a/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-1.d b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-1.d index a0e9db973f..adef3fcc8c 100644 --- a/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-1.d +++ b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-1.d @@ -1,13 +1,63 @@ -void main() { - import std.stdio, std.range, std.algorithm, std.string, permutations2; +import std.stdio; +import std.random; +import std.algorithm; +import std.range; - const pieces = "KQRrBbNN"; - alias I = indexOf; - auto starts = pieces.dup.permutations.filter!(p => - I(p, 'B') % 2 != I(p, 'b') % 2 && // Bishop constraint. - // King constraint. - ((I(p, 'r') < I(p, 'K') && I(p, 'K') < I(p, 'R')) || - (I(p, 'R') < I(p, 'K') && I(p, 'K') < I(p, 'r')))) - .map!toUpper.array.sort().uniq; - writeln(starts.walkLength, "\n", starts.front); +string[] ch960startPos() { + string[] rank = new string[8]; + + auto d = (size_t num) => uniform(0, num); + + auto emptySquares = () { + return rank.enumerate + .filter!(t => t.value is null) + .map!(t => t.index) + .array(); + }; + + // Place one Bishop << on a black square + rank[d(4) * 2] = "♗"; + + // Place the other Bishop << on a white square + rank[d(4) * 2 + 1] = "♗"; + + // Place the Queen << + auto empty = emptySquares(); + rank[empty[d(empty.length)]] = "♕"; + + // Place one Knight << + empty = emptySquares(); + rank[empty[d(empty.length)]] = "♘"; + + // Place the second Knight << + empty = emptySquares(); + rank[empty[d(empty.length)]] = "♘"; + + // Remaining positions: place 2 Rooks << and 1 King << + empty = emptySquares(); + empty.sort(); // Sort positions for easier logic + + size_t kingPosIndex = d(empty.length); + size_t kingPos = empty[kingPosIndex]; + + auto left = empty[0 .. kingPosIndex]; + auto right = empty[kingPosIndex + 1 .. $]; + + if (left.empty || right.empty) { + // Invalid setup, retry + return ch960startPos(); + } + + size_t rook1 = left[d(left.length)]; + size_t rook2 = right[d(right.length)]; + + rank[rook1] = "♖"; + rank[kingPos] = "♔"; + rank[rook2] = "♖"; + + return rank; +} + +void main() { + iota(10).each!(_ => writeln(ch960startPos().join(""))); } diff --git a/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-2.d b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-2.d index 420a99b0c8..a349f282e0 100644 --- a/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-2.d +++ b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-2.d @@ -1,11 +1,25 @@ -void main() { - import std.stdio, std.regex, std.range, std.algorithm, permutations2; +import std.stdio : writeln; +import std.random; +import std.array : join; +import std.string : indexOf, lastIndexOf; +import std.algorithm : nextPermutation; - immutable pieces = "KQRRBBNN"; - immutable bish = r"B(|..|....|......)B"; - immutable king = r"R.*K.*R"; - auto starts3 = permutations(pieces.dup) - .filter!(p => p.match(bish) && p.match(king)) - .array.sort().uniq; - writeln(starts3.walkLength, "\n", starts3.front); +void main() { + // The Pieces, no King at all but 3 Rooks! + auto pos = ["Q", "R", "R", "R", "B", "B", "N", "N"].randomShuffle; + + do { + auto candidate = pos.join(""); + + if (candidate.indexOf('B') % 2 != candidate.lastIndexOf('B') % 2) { + auto dupPos = pos.dup; + + // Promote middle Rook to King + dupPos[candidate[0..candidate.lastIndexOf('R')].lastIndexOf('R')] = "K"; + + dupPos.join("").writeln; // Output! + + return; + } + } while (pos.nextPermutation); } diff --git a/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-3.d b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-3.d index 5885e3bb3d..a0e9db973f 100644 --- a/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-3.d +++ b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-3.d @@ -1,13 +1,13 @@ void main() { - import std.stdio, std.random, std.array, std.range; + import std.stdio, std.range, std.algorithm, std.string, permutations2; - // Subsequent order unchanged by insertions. - auto start = "RKR".dup; - foreach (immutable piece; "QNN") - start.insertInPlace(uniform(0, start.length), piece); - - immutable bishpos = uniform(0, start.length); - start.insertInPlace(bishpos, 'B'); - start.insertInPlace(iota(bishpos % 2, start.length, 2)[uniform(0,$)], 'B'); - start.writeln; + const pieces = "KQRrBbNN"; + alias I = indexOf; + auto starts = pieces.dup.permutations.filter!(p => + I(p, 'B') % 2 != I(p, 'b') % 2 && // Bishop constraint. + // King constraint. + ((I(p, 'r') < I(p, 'K') && I(p, 'K') < I(p, 'R')) || + (I(p, 'R') < I(p, 'K') && I(p, 'K') < I(p, 'r')))) + .map!toUpper.array.sort().uniq; + writeln(starts.walkLength, "\n", starts.front); } diff --git a/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-4.d b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-4.d new file mode 100644 index 0000000000..420a99b0c8 --- /dev/null +++ b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-4.d @@ -0,0 +1,11 @@ +void main() { + import std.stdio, std.regex, std.range, std.algorithm, permutations2; + + immutable pieces = "KQRRBBNN"; + immutable bish = r"B(|..|....|......)B"; + immutable king = r"R.*K.*R"; + auto starts3 = permutations(pieces.dup) + .filter!(p => p.match(bish) && p.match(king)) + .array.sort().uniq; + writeln(starts3.walkLength, "\n", starts3.front); +} diff --git a/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-5.d b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-5.d new file mode 100644 index 0000000000..5885e3bb3d --- /dev/null +++ b/Task/Generate-Chess960-starting-position/D/generate-chess960-starting-position-5.d @@ -0,0 +1,13 @@ +void main() { + import std.stdio, std.random, std.array, std.range; + + // Subsequent order unchanged by insertions. + auto start = "RKR".dup; + foreach (immutable piece; "QNN") + start.insertInPlace(uniform(0, start.length), piece); + + immutable bishpos = uniform(0, start.length); + start.insertInPlace(bishpos, 'B'); + start.insertInPlace(iota(bishpos % 2, start.length, 2)[uniform(0,$)], 'B'); + start.writeln; +} diff --git a/Task/Generate-Chess960-starting-position/Delphi/generate-chess960-starting-position.pas b/Task/Generate-Chess960-starting-position/Delphi/generate-chess960-starting-position.pas new file mode 100644 index 0000000000..79f51aab19 --- /dev/null +++ b/Task/Generate-Chess960-starting-position/Delphi/generate-chess960-starting-position.pas @@ -0,0 +1,41 @@ +program byconstruct; + +{$APPTYPE CONSOLE} + +uses + System.SysUtils, System.Math, Generics.Collections; + +var + start: TList; + piece: Char; + bishpos: Integer; + resultString: String; + +begin + Randomize; + + start := TList.Create; + + try + start.AddRange(['R', 'K', 'R']); // << + + for piece in ['Q', 'N', 'N'] do + start.Insert(Random(start.Count), piece); // << + + bishpos := Random(start.Count); + start.Insert(bishpos, 'B'); // << + + if bishpos mod 2 = 0 then + start.Insert(Random(start.Count div 2) * 2, 'B') // << + else + start.Insert(Random((start.Count - bishpos + 1) div 2) * 2 + bishpos, 'B'); // << + + // Convert TList to String + resultString := String.Create(start.ToArray); + + WriteLn(resultString); + + finally + start.Free; + end; +end. diff --git a/Task/Generate-Chess960-starting-position/EasyLang/generate-chess960-starting-position.easy b/Task/Generate-Chess960-starting-position/EasyLang/generate-chess960-starting-position.easy index 80dca8ffad..dd1be571b9 100644 --- a/Task/Generate-Chess960-starting-position/EasyLang/generate-chess960-starting-position.easy +++ b/Task/Generate-Chess960-starting-position/EasyLang/generate-chess960-starting-position.easy @@ -1,5 +1,5 @@ len t$[] 8 -proc randins c$ l r . pos . +proc randins c$ l r &pos . repeat pos = random (r - l + 1) + l - 1 until t$[pos] = "" diff --git a/Task/Generate-Chess960-starting-position/Rust/generate-chess960-starting-position-3.rs b/Task/Generate-Chess960-starting-position/Rust/generate-chess960-starting-position-3.rs new file mode 100644 index 0000000000..fc4dda4049 --- /dev/null +++ b/Task/Generate-Chess960-starting-position/Rust/generate-chess960-starting-position-3.rs @@ -0,0 +1,36 @@ +use rand::seq::SliceRandom; +use rand::rng; + +fn generate_chess960() -> String { + let mut rng = rng(); + + loop { + let mut pieces = vec!['♛', '♜', '♜', '♜', '♝', '♝', '♞', '♞']; + pieces.shuffle(&mut rng); + + let bishops: Vec = pieces.iter() + .enumerate() + .filter(|&(_, p)| *p == '♝') + .map(|(i, _)| i) + .collect(); + + if bishops.len() == 2 && bishops[0] % 2 != bishops[1] % 2 { + let mut rooks: Vec = pieces.iter() + .enumerate() + .filter(|&(_, p)| *p == '♜') + .map(|(i, _)| i) + .collect(); + + rooks.sort(); // Sort to locate the middle rook + let middle_rook = rooks[1]; // Promote the second rook to King + pieces[middle_rook] = '♚'; // Replace middle rook with King + + return pieces.iter().collect(); + } + } +} + +fn main() { + let position = generate_chess960(); + println!("Chess960 Position: {position}"); +} diff --git a/Task/Generate-lower-case-ASCII-alphabet/Objeck/generate-lower-case-ascii-alphabet.objeck b/Task/Generate-lower-case-ASCII-alphabet/Objeck/generate-lower-case-ascii-alphabet.objeck new file mode 100644 index 0000000000..dee3ea9202 --- /dev/null +++ b/Task/Generate-lower-case-ASCII-alphabet/Objeck/generate-lower-case-ascii-alphabet.objeck @@ -0,0 +1,7 @@ +function : Main(args : String[]) ~ Nil { + buffer := ""; + for(i := 'a'; i <= 'z'; i += 1;) { + buffer += i->As(Char); + }; + buffer->PrintLine(); +} diff --git a/Task/Generate-lower-case-ASCII-alphabet/Rust/generate-lower-case-ascii-alphabet.rs b/Task/Generate-lower-case-ASCII-alphabet/Rust/generate-lower-case-ascii-alphabet-1.rs similarity index 100% rename from Task/Generate-lower-case-ASCII-alphabet/Rust/generate-lower-case-ascii-alphabet.rs rename to Task/Generate-lower-case-ASCII-alphabet/Rust/generate-lower-case-ascii-alphabet-1.rs diff --git a/Task/Generate-lower-case-ASCII-alphabet/Rust/generate-lower-case-ascii-alphabet-2.rs b/Task/Generate-lower-case-ASCII-alphabet/Rust/generate-lower-case-ascii-alphabet-2.rs new file mode 100644 index 0000000000..e73620e114 --- /dev/null +++ b/Task/Generate-lower-case-ASCII-alphabet/Rust/generate-lower-case-ascii-alphabet-2.rs @@ -0,0 +1 @@ +'a'..='z' diff --git a/Task/Generator-Exponential/Tcl/generator-exponential.tcl b/Task/Generator-Exponential/Tcl/generator-exponential-1.tcl similarity index 100% rename from Task/Generator-Exponential/Tcl/generator-exponential.tcl rename to Task/Generator-Exponential/Tcl/generator-exponential-1.tcl diff --git a/Task/Generator-Exponential/Tcl/generator-exponential-2.tcl b/Task/Generator-Exponential/Tcl/generator-exponential-2.tcl new file mode 100644 index 0000000000..fba5346de8 --- /dev/null +++ b/Task/Generator-Exponential/Tcl/generator-exponential-2.tcl @@ -0,0 +1,13 @@ +package require Tcl 8.6 +package require generator + +generator define range {n m} { + for {set i $n} {$i <= $m} {incr i} { + generator yield $i + } +} + +generator foreach x [range 22 35] { + puts -nonewline stdout "${x} " +} +puts stdout "" diff --git a/Task/Generator-Exponential/Tcl/generator-exponential-3.tcl b/Task/Generator-Exponential/Tcl/generator-exponential-3.tcl new file mode 100644 index 0000000000..f3b6c68265 --- /dev/null +++ b/Task/Generator-Exponential/Tcl/generator-exponential-3.tcl @@ -0,0 +1,54 @@ +#!/usr/bin/env tclsh + +package require generator + +generator define idx_range {n m} { + for {set i $n} {$i < [expr $m -1]} {incr i} { generator yield $i } +} + +generator define mth_power {m} { + set n 0 + while {1} { + generator yield [expr $n ** $m] + incr n + } +} + +generator define squares {} { + + generator for x [mth_power 2] { + generator yield $x + } +} + +generator define cubes {} { + + generator for x [mth_power 3] { + generator yield $x + } +} + +set acc {} ; # accumulator + +set comm {} ; # common result + +set limit 50 + +# run both generators concurrently + +generator foreach x [squares] y [cubes] { + + lappend acc $y + + if { ! [expre {$x in $acc}] } { lappend comm $x } + + if { [llength $comm] > $limit } {break} +} + +# elements 20.. 30 +set results [lrange $comm 19 29] ; # list range + +generator foreach idx [idx_range 20 30] { + set x [lindex $comm $idx] + puts "$x" +} diff --git a/Task/Generator-Exponential/Ursalang/generator-exponential.ursa b/Task/Generator-Exponential/Ursalang/generator-exponential.ursa index c1d70cc2d5..653aea0e9e 100644 --- a/Task/Generator-Exponential/Ursalang/generator-exponential.ursa +++ b/Task/Generator-Exponential/Ursalang/generator-exponential.ursa @@ -26,7 +26,6 @@ let filtered = gen(s1, s2) { } } - let squares = powers(2) let cubes = powers(3) let f = filtered(squares, cubes) diff --git a/Task/Globally-replace-text-in-several-files/BQN/globally-replace-text-in-several-files.bqn b/Task/Globally-replace-text-in-several-files/BQN/globally-replace-text-in-several-files.bqn new file mode 100644 index 0000000000..0c25af9969 --- /dev/null +++ b/Task/Globally-replace-text-in-several-files/BQN/globally-replace-text-in-several-files.bqn @@ -0,0 +1,9 @@ +#!/usr/bin/env bqn + +_onfile ← {𝕩 •FChars (𝕨 𝔽 •FChars⎊"" 𝕩)} + +FindReplace ← {(⊣-⊸⌽(1⊑𝕨)∾(≠⊑𝕨)↓⊣⌽⊢)´𝕩∾⟜<˜/(⊑𝕨)⍷𝕩} + +files ← •wdpath⊸•file.At¨ •args + +"Goodbye London!"‿"Hello New York!"⊸(FindReplace _onfile)¨ files diff --git a/Task/Goldbachs-comet/EasyLang/goldbachs-comet.easy b/Task/Goldbachs-comet/EasyLang/goldbachs-comet.easy index 666e90ef38..1a4a2b23d6 100644 --- a/Task/Goldbachs-comet/EasyLang/goldbachs-comet.easy +++ b/Task/Goldbachs-comet/EasyLang/goldbachs-comet.easy @@ -1,30 +1,22 @@ func isprim n . - if n mod 2 = 0 and n > 2 - return 0 - . + if n mod 2 = 0 and n > 2 : return 0 i = 3 sq = sqrt n while i <= sq - if n mod i = 0 - return 0 - . + if n mod i = 0 : return 0 i += 2 . return 1 . func goldbach n . for i = 2 to n div 2 - if isprim i = 1 - cnt += isprim (n - i) - . + if isprim i = 1 : cnt += isprim (n - i) . return cnt . -numfmt 0 3 +numfmt 3 0 for n = 4 step 2 to 202 write goldbach n - if n mod 20 = 2 - print "" - . + if n mod 20 = 2 : print "" . print goldbach 1000000 diff --git a/Task/Goldbachs-comet/Go/goldbachs-comet.go b/Task/Goldbachs-comet/Go/goldbachs-comet.go new file mode 100644 index 0000000000..4c8b45dc6c --- /dev/null +++ b/Task/Goldbachs-comet/Go/goldbachs-comet.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "math" +) + +var primes []bool + +func initialisePrimes(limit int) { + primes = make([]bool, limit) + for i := 2; i < limit; i++ { + primes[i] = true + } + + sqrtLimit := int(math.Sqrt(float64(limit))) + for n := 2; n < sqrtLimit; n++ { + if primes[n] { + for k := n * n; k < limit; k += n { + primes[k] = false + } + } + } +} + +func goldbachFunction(number int) (int, error) { + if number <= 2 || number%2 == 1 { + return 0, fmt.Errorf("argument must be even and greater than 2: %d", number) + } + + result := 0 + for i := 1; i <= number/2; i++ { + if primes[i] && primes[number-i] { + result++ + } + } + return result, nil +} + +func main() { + initialisePrimes(2000000) + + fmt.Println("The first 100 Goldbach numbers:") + for n := 2; n < 102; n++ { + value, err := goldbachFunction(2 * n) + if err != nil { + fmt.Printf("Error: %v\n", err) + continue + } + fmt.Printf("%3d", value) + if n%10 == 1 { + fmt.Println() + } + } + + fmt.Println("\nThe 1,000,000th Goldbach number =", func() string { + value, err := goldbachFunction(1000000) + if err != nil { + return fmt.Sprintf("Error: %v", err) + } + return fmt.Sprintf("%d", value) + }()) +} diff --git a/Task/Goldbachs-comet/REXX/goldbachs-comet.rexx b/Task/Goldbachs-comet/REXX/goldbachs-comet.rexx index db599de5d4..6090954e96 100644 --- a/Task/Goldbachs-comet/REXX/goldbachs-comet.rexx +++ b/Task/Goldbachs-comet/REXX/goldbachs-comet.rexx @@ -1,6 +1,9 @@ +-- 22 Mar 2025 include Settings -say version; say 'Goldbach''s comet'; say +say 'GOLDBACH''S COMET' +say version +say numeric digits 7 call GetPrimes call ShowFirst100 @@ -8,7 +11,7 @@ call ShowMillion exit GetPrimes: -procedure expose prim. +procedure expose prim. flag. call Time('r') say 'Collect Primes up to 1000000...' call Primes(1e6) @@ -17,7 +20,7 @@ say return ShowFirst100: -procedure expose prim. +procedure expose prim. flag. call Time('r') say 'First 100 values...' do i = 4 by 2 to 202 @@ -30,22 +33,22 @@ say return ShowMillion: -procedure expose prim. +procedure expose prim. flag. call Time('r') -say 'G(1000000)...' +say 'g(1000000)...' say Goldbach(1e6) say Time('e')/1 'seconds' say return Goldbach: -procedure expose prim. +procedure expose prim. flag. arg x y = 0 do i = 2 to x%2 - if prim.flag.i then do + if flag.i then do j = x-i - if prim.flag.j then do + if flag.j then do y = y+1 end end diff --git a/Task/Golden-ratio-Convergence/EasyLang/golden-ratio-convergence.easy b/Task/Golden-ratio-Convergence/EasyLang/golden-ratio-convergence.easy index 66bf65792e..c5d55953a8 100644 --- a/Task/Golden-ratio-Convergence/EasyLang/golden-ratio-convergence.easy +++ b/Task/Golden-ratio-Convergence/EasyLang/golden-ratio-convergence.easy @@ -5,7 +5,7 @@ repeat phi0 = phi iter += 1 . -numfmt 10 0 +numfmt 0 10 print "Iterations: " & iter print "Result: " & phi print "Error: " & phi - (1 + sqrt 5) / 2 diff --git a/Task/Gotchas/C-sharp/gotchas.cs b/Task/Gotchas/C-sharp/gotchas.cs new file mode 100644 index 0000000000..0a88a5fcdf --- /dev/null +++ b/Task/Gotchas/C-sharp/gotchas.cs @@ -0,0 +1,18 @@ +using System.Diagnostics; + + +// Methods that return values and don't modify the object + +int[] arr = [1, 2, 3, 4, 5]; +arr.Reverse(); +Console.WriteLine(string.Join(", ", arr)); + + +// Tasks are not threads! There are not 50 threads here even though there are 50 tasks. +// See https://blog.stephencleary.com/2013/11/there-is-no-thread.html + +Console.WriteLine(Process.GetCurrentProcess().Threads.Count); +Task[] tasks = [.. Enumerable.Range(0, 50).Select(i => Task.Delay(1000))]; +Console.WriteLine(Process.GetCurrentProcess().Threads.Count); +Task.WaitAll(tasks); +Console.WriteLine(Process.GetCurrentProcess().Threads.Count); diff --git a/Task/Graph-colouring/FreeBASIC/graph-colouring.basic b/Task/Graph-colouring/FreeBASIC/graph-colouring.basic new file mode 100644 index 0000000000..dbead294ee --- /dev/null +++ b/Task/Graph-colouring/FreeBASIC/graph-colouring.basic @@ -0,0 +1,149 @@ +Const tests As String = "0-1 1-2 2-0 3" & Chr(10) & _ +"1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7" & Chr(10) & _ +"1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6" & Chr(10) & _ +"1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7" + +Sub Colour(links() As Integer, nodeCount As Integer, colours() As Integer, _ + soln() As Integer, Byref best As Integer, sgte As Integer, used As Integer = 0) + + Dim As Integer i, c = 1 + Dim As Integer tmpColours(nodeCount - 1) + + For i = 0 To nodeCount - 1 + tmpColours(i) = colours(i) + Next + + While c <= best + Dim As Boolean avail = True + For i = 0 To nodeCount - 1 + If links(sgte, i) = 1 Andalso tmpColours(i) = c Then + avail = False + Exit For + End If + Next + + If avail Then + tmpColours(sgte) = c + Dim As Integer newused = used + If c > used Then newused = c + + If sgte < nodeCount - 1 Then + Colour(links(), nodeCount, tmpColours(), soln(), best, sgte + 1, newused) + Elseif newused < best Then + best = newused + For i = 0 To nodeCount - 1 + soln(i) = tmpColours(i) + Next + End If + End If + c += 1 + Wend +End Sub + +Function GetNodeIndex(nodeMap() As String, nodeCount As Integer, nodeName As String) As Integer + For i As Integer = 0 To nodeCount - 1 + If nodeMap(i) = nodeName Then Return i + Next + Return -1 +End Function + +Sub main() + Dim As String testLines(3) + Dim As Integer lineCount = 0, posic = 1, nextPos + + ' Split the test chain into lines + Do + nextPos = Instr(posic, tests, Chr(10)) + If nextPos = 0 Then + testLines(lineCount) = Mid(tests, posic) + lineCount += 1 + Exit Do + Else + testLines(lineCount) = Mid(tests, posic, nextPos - posic) + lineCount += 1 + posic = nextPos + 1 + End If + Loop + + For t As Integer = 0 To 3 + Dim As String linea = testLines(t) + Dim As String nodeMap(20) + Dim As Integer nodeCount = 0 + Dim As String token + posic = 1 + + Do + If posic > Len(linea) Then Exit Do + + nextPos = Instr(posic, linea, " ") + If nextPos = 0 Then nextPos = Len(linea) + 1 + + token = Mid(linea, posic, nextPos - posic) + posic = nextPos + 1 + + Dim As Integer dashPos = Instr(token, "-") + If dashPos > 0 Then + Dim As String node1 = Left(token, dashPos - 1) + Dim As String node2 = Mid(token, dashPos + 1) + + If GetNodeIndex(nodeMap(), nodeCount, node1) = -1 Then + nodeMap(nodeCount) = node1 + nodeCount += 1 + End If + + If GetNodeIndex(nodeMap(), nodeCount, node2) = -1 Then + nodeMap(nodeCount) = node2 + nodeCount += 1 + End If + Else + If GetNodeIndex(nodeMap(), nodeCount, token) = -1 Then + nodeMap(nodeCount) = token + nodeCount += 1 + End If + End If + Loop + + Dim As Integer links(nodeCount - 1, nodeCount - 1) + Dim As Integer edgeCount = 0 + + posic = 1 + Do + If posic > Len(linea) Then Exit Do + + nextPos = Instr(posic, linea, " ") + If nextPos = 0 Then nextPos = Len(linea) + 1 + + token = Mid(linea, posic, nextPos - posic) + posic = nextPos + 1 + + Dim As Integer dashPos = Instr(token, "-") + If dashPos > 0 Then + Dim As String node1 = Left(token, dashPos - 1) + Dim As String node2 = Mid(token, dashPos + 1) + + Dim As Integer idx1 = GetNodeIndex(nodeMap(), nodeCount, node1) + Dim As Integer idx2 = GetNodeIndex(nodeMap(), nodeCount, node2) + + links(idx1, idx2) = 1 + links(idx2, idx1) = 1 + edgeCount += 1 + End If + Loop + + Dim As Integer colours(nodeCount - 1), soln(nodeCount - 1) + Dim As Integer best = nodeCount + + Colour(links(), nodeCount, colours(), soln(), best, 0) + + Print "test" & t + 1 & ": " & nodeCount & " nodes, " & edgeCount & " edges, " & best & " colours:"; + + For i As Integer = 0 To nodeCount - 1 + Print soln(i); + Next + Print + Next +End Sub + +main() + +Sleep diff --git a/Task/Graph-colouring/JavaScript/graph-colouring.js b/Task/Graph-colouring/JavaScript/graph-colouring.js new file mode 100644 index 0000000000..2da345b834 --- /dev/null +++ b/Task/Graph-colouring/JavaScript/graph-colouring.js @@ -0,0 +1,222 @@ +// Equivalent to: +// #include +// #include +const allColours = ["PINK", "ORANGE", "CYAN", "YELLOW", "RED", "GREEN", "BLUE"]; + +// Equivalent to: +// class Node { ... }; +class Node { + constructor(id, saturation, colour) { + this.id = id; // Equivalent to int32_t id + this.saturation = saturation; // Equivalent to int32_t saturation + this.colour = colour; // Equivalent to std::string colour + this.excludedFromSearch = false; // Equivalent to bool excluded_from_search + } + + // The default constructor Node() : id(0), ... is handled implicitly in how we create nodes in the Map. + // If a key doesn't exist, Map.get() returns undefined, we explicitly use Map.set() to create nodes. +} + +// Equivalent to: +// int main() { ... } +function main() { + // Equivalent to: + // std::map graph; + // In JavaScript, Map keys are ordered by insertion or can be iterated over, + // but there's no built-in custom comparator for sorted access like std::map. + // However, the algorithm iterates through *all* map entries to find the max saturation node, + // so the map's internal order doesn't affect the result. + let graph = new Map(); // Map + + // Equivalent to: + // std::map, decltype([](const int32_t& a, const int32_t& b) { return a < b; })> neighbours; + // Similar to graph, Set doesn't guarantee element order like std::set, + // but neighbor order isn't relevant to the coloring logic. + let neighbours = new Map(); // Map> + + // Equivalent to: + // const std::vector graph_representations = { ... }; + const graphRepresentations = [ + "0-1 1-2 2-0 3", + "1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7", + "1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6", + "1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7" + ]; + + // Equivalent to: + // for ( const std::string& graph_representation : graph_representations ) { ... } + for (const graphRepresentation of graphRepresentations) { + graph.clear(); + neighbours.clear(); + + // Equivalent to: + // std::stringstream stream(graph_representation); + // std::string element; + // while ( stream >> element ) { ... } + const elements = graphRepresentation.split(/\s+/); // Split string by one or more whitespace characters + for (const element of elements) { + if (element === "") continue; // Skip empty strings that might result from multiple spaces + + // Equivalent to: if ( element.find("-") != std::string::npos ) { ... } + if (element.includes("-")) { + const parts = element.split("-"); + // Equivalent to: const int32_t id1 = element[0] - '0'; + const id1 = parseInt(parts[0], 10); + // Equivalent to: const int32_t id2 = element[element.length() - 1] - '0'; + const id2 = parseInt(parts[parts.length - 1], 10); // Use last part, robust for potential future formats like 10-11 + + // Ensure nodes exist in the graph map. + // Equivalent to: if ( ! graph.contains(id1) ) { graph[id1] = Node(id1, 0, "NO_COLOUR"); } + if (!graph.has(id1)) { + graph.set(id1, new Node(id1, 0, "NO_COLOUR")); + } + // C++ `Node node1 = graph[id1];` gets a *copy*. In JS, graph.get(id1) gets a *reference*. + // We don't need to store the reference here just yet as we only needed to ensure the node exists. + + // Equivalent to: if ( ! graph.contains(id2) ) { graph[id2] = Node(id2, 0, "NO_COLOUR"); } + if (!graph.has(id2)) { + graph.set(id2, new Node(id2, 0, "NO_COLOUR")); + } + // C++ `Node node2 = graph[id2];` + + // Ensure neighbor sets exist and add neighbors. + // Equivalent to: neighbours[id1].emplace(id2); + if (!neighbours.has(id1)) { + neighbours.set(id1, new Set()); // Equivalent to std::set + } + neighbours.get(id1).add(id2); // Equivalent to emplace + + // Equivalent to: neighbours[id2].emplace(id1); + if (!neighbours.has(id2)) { + neighbours.set(id2, new Set()); + } + neighbours.get(id2).add(id1); + + } else { // Handle isolated nodes (e.g., "3") + // Equivalent to: const int32_t id = element[0] - '0'; + const id = parseInt(element, 10); // Parse the whole element as an ID + + // Equivalent to: if ( ! graph.contains(id) ) { graph[id] = Node(id, 0, "NO_COLOUR"); } + if (!graph.has(id)) { + graph.set(id, new Node(id, 0, "NO_COLOUR")); + } + } + } + + // Graph Coloring Loop (DSatur-like heuristic) + // Equivalent to: for ( uint64_t i = 0; i < graph.size(); ++i ) { ... } + // This loop structure implies that each node is processed exactly once + // because one node is marked excluded_from_search in each iteration. + for (let i = 0; i < graph.size; ++i) { + let maxNodeId = -1; + let maxSaturation = -1; + + // Find the node with the maximum saturation among those not yet colored. + // Equivalent to: for ( const auto& [key, value] : graph ) { ... } + for (const [key, node] of graph) { + // Equivalent to: if ( ! value.excluded_from_search && value.saturation > max_saturation ) { ... } + // If multiple nodes have the same max saturation, the one encountered first in the map iteration order is chosen. + if (!node.excludedFromSearch && node.saturation > maxSaturation) { + maxSaturation = node.saturation; + maxNodeId = key; + } + } + + // If maxNodeId is still -1, it means no unexcluded node was found. + // This shouldn't happen until all nodes are processed due to the loop count. + if (maxNodeId === -1) { + // Should only happen if the graph was empty or already fully excluded, + // which the outer loop count should prevent prematurely. + continue; // Skip this iteration if no node found. + } + + // Find colours used by neighbours of the selected node. + // Equivalent to: std::unordered_set colours_used; + const coloursUsed = new Set(); // Use Set for efficient `has` check + + // Equivalent to: for ( const int32_t& neighbour : neighbours[max_node_id] ) { ... } + // Get the set of neighbor IDs for the selected node. Handle case where node has no neighbors entry. + const neighborIdsOfSelected = neighbours.get(maxNodeId) || new Set(); + for (const neighbourId of neighborIdsOfSelected) { + // Get the neighbor node object from the graph map + const neighbourNode = graph.get(neighbourId); + // Check if the neighbor node exists in the graph and add its color to the set + if (neighbourNode) { + coloursUsed.add(neighbourNode.colour); + } + } + + // Find the smallest available colour. + // Equivalent to: std::string min_colour; + let minColour = ""; + // Equivalent to: for ( const std::string& colour : all_colours ) { ... } + for (const colour of allColours) { + // Equivalent to: if ( ! colours_used.contains(colour) ) { ... } + if (!coloursUsed.has(colour)) { + minColour = colour; + break; // Found the first available colour, stop searching. + } + } + + // Assign colour to the selected node and mark it as excluded. + // Equivalent to: graph[max_node_id].excluded_from_search = true; + // Equivalent to: graph[max_node_id].colour = min_colour; + const selectedNode = graph.get(maxNodeId); // Get the reference to the node object + selectedNode.excludedFromSearch = true; + selectedNode.colour = minColour; + + // Update saturation of neighbours. + // Equivalent to: for ( int32_t neighbour : neighbours[max_node_id] ) { ... } + for (const neighbourId of neighborIdsOfSelected) { + const neighbourNode = graph.get(neighbourId); + // Equivalent to: if ( graph[neighbour].colour == "NO_COLOUR" ) { ... } + // C++ logic: only update saturation if the neighbour is still uncolored. + // Set saturation to the number of *distinct colors* used by the *selected node's* neighbors + // *at the moment the selected node was processed*. + if (neighbourNode && neighbourNode.colour === "NO_COLOUR") { + neighbourNode.saturation = coloursUsed.size; // Uses the size calculated above + } + } + // Note: This saturation update logic is a direct translation of the C++ code. + // A more standard DSatur might update saturation differently (e.g., incrementing + // the saturation of *all* uncolored neighbors if the newly assigned color is new to *their* neighborhood). + // We adhere to the C++ code's exact implementation. + } + + // Output the results for the colored graph. + // Equivalent to: std::unordered_set graph_colours; + const graphColours = new Set(); // Use Set to count unique colors + + // Equivalent to: for ( const auto& [key, value] : graph ) { ... } + // Iterate over the graph map which now contains the final colored nodes. + for (const [key, node] of graph) { + // Equivalent to: graph_colours.emplace(value.colour); + graphColours.add(node.colour); + + // Equivalent to: std::cout << "Node " << key << ": colour = " + value.colour; + let output = `Node ${key}: colour = ${node.colour}`; + + // Equivalent to: if ( ! neighbours[key].empty() ) { ... } + const neighborIds = neighbours.get(key) || new Set(); // Get neighbors for the current node key + if (neighborIds.size > 0) { + // Equivalent to: std::cout << std::string(8 - value.colour.length(), ' ') << "neighbours = "; + // Calculate padding for alignment based on C++ padding (8 - color length) + const padding = ' '.repeat(Math.max(0, 8 - node.colour.length)); + output += `${padding}neighbours = `; + + // Equivalent to: for ( const int32_t& neighbour : neighbours[key] ) { std::cout << neighbour << " "; } + // Convert the Set of neighbor IDs to an Array and join them with spaces. + const neighborList = Array.from(neighborIds).join(" "); + output += neighborList; + } + // Equivalent to: std::cout << std::endl; + console.log(output); + } + // Equivalent to: std::cout << "Number of colours used: " << graph_colours.size() << std::endl << std::endl; + console.log(`Number of colours used: ${graphColours.size}`); + console.log(""); // Add an extra newline as in the C++ output + } +} + +// Execute the main function +main(); diff --git a/Task/Graph-colouring/Rust/graph-colouring.rs b/Task/Graph-colouring/Rust/graph-colouring.rs new file mode 100644 index 0000000000..5d71bbc098 --- /dev/null +++ b/Task/Graph-colouring/Rust/graph-colouring.rs @@ -0,0 +1,134 @@ +use std::collections::{HashMap, HashSet}; + +const ALL_COLOURS: [&str; 7] = ["PINK", "ORANGE", "CYAN", "YELLOW", "RED", "GREEN", "BLUE"]; + +#[derive(Debug, Clone)] +struct Node { + id: i32, + saturation: i32, + colour: String, + excluded_from_search: bool, +} + +impl Node { + fn new(id: i32, saturation: i32, colour: String) -> Self { + Node { + id, + saturation, + colour, + excluded_from_search: false, + } + } + + fn default() -> Self { + Node { + id: 0, + saturation: 0, + colour: "NO_COLOUR".to_string(), + excluded_from_search: false, + } + } +} + +fn main() { + let graph_representations: [&str; 4] = [ + "0-1 1-2 2-0 3", + "1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7", + "1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6", + "1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7", + ]; + + for graph_representation in graph_representations { + let mut graph: HashMap = HashMap::new(); + let mut neighbours: HashMap> = HashMap::new(); + + for element in graph_representation.split_whitespace() { + if element.contains("-") { + let parts: Vec<&str> = element.split("-").collect(); + let id1: i32 = parts[0].parse().unwrap(); + let id2: i32 = parts[1].parse().unwrap(); + + if !graph.contains_key(&id1) { + graph.insert(id1, Node::new(id1, 0, "NO_COLOUR".to_string())); + } + //let node1 = graph.get(&id1).unwrap().clone(); // No need to clone + + if !graph.contains_key(&id2) { + graph.insert(id2, Node::new(id2, 0, "NO_COLOUR".to_string())); + } + //let node2 = graph.get(&id2).unwrap().clone(); // No need to clone + + neighbours.entry(id1).or_insert(HashSet::new()).insert(id2); + neighbours.entry(id2).or_insert(HashSet::new()).insert(id1); + } else { + let id: i32 = element.parse().unwrap(); + if !graph.contains_key(&id) { + graph.insert(id, Node::new(id, 0, "NO_COLOUR".to_string())); + } + } + } + + for _ in 0..graph.len() { + let mut max_node_id: i32 = -1; + let mut max_saturation: i32 = -1; + + for (&key, value) in &graph { + if !value.excluded_from_search && value.saturation > max_saturation { + max_saturation = value.saturation; + max_node_id = key; + } + } + + let mut colours_used: HashSet = HashSet::new(); + if let Some(neighbors) = neighbours.get(&max_node_id) { + for &neighbour in neighbors { + if let Some(neighbor_node) = graph.get(&neighbour) { + colours_used.insert(neighbor_node.colour.clone()); + } + } + } + + let mut min_colour = String::new(); + for &colour in &ALL_COLOURS { + if !colours_used.contains(colour) { + min_colour = colour.to_string(); + break; + } + } + + if let Some(node) = graph.get_mut(&max_node_id) { + node.excluded_from_search = true; + node.colour = min_colour.clone(); + } + + if let Some(neighbors) = neighbours.get(&max_node_id) { + for &neighbour in neighbors { + if let Some(neighbor_node) = graph.get_mut(&neighbour) { + if neighbor_node.colour == "NO_COLOUR" { + neighbor_node.saturation = colours_used.len() as i32; + } + } + } + } + } + + let mut graph_colours: HashSet = HashSet::new(); + for (&key, value) in &graph { + graph_colours.insert(value.colour.clone()); + print!("Node {}: colour = {}", key, value.colour); + + if let Some(neighbors) = neighbours.get(&key) { + if !neighbors.is_empty() { + print!("{}", " ".repeat(8 - value.colour.len())); + print!("neighbours = "); + for &neighbour in neighbors { + print!("{} ", neighbour); + } + } + } + println!(); + } + println!("Number of colours used: {}", graph_colours.len()); + println!(); + } +} diff --git a/Task/Gray-code/SETL/gray-code.setl b/Task/Gray-code/SETL/gray-code.setl new file mode 100644 index 0000000000..e5d368056b --- /dev/null +++ b/Task/Gray-code/SETL/gray-code.setl @@ -0,0 +1,29 @@ +program gray_code; + loop for n in [0..31] do + print( + lpad(str n, 2) + ": " + + lpad(bits n, 5) + " => " + + lpad(bits(g := gray_encode(n)), 5) + " => " + + lpad(bits(d := gray_decode(g)), 5) + ": " + + lpad(str d, 2) + ); + end loop; + + proc gray_encode(n); + return n bit_xor (n div 2); + end proc; + + proc gray_decode(n); + loop + init r := 0; + step n div:= 2; + until n=0 do r bit_xor:= n; + end loop; + return r; + end proc; + + op bits(n); + b := '' +/ [[str (n mod 2), n div:=2](1) : until n=0]; + return reverse(b); + end op; +end program; diff --git a/Task/Grayscale-image/M2000-Interpreter/grayscale-image.m2000 b/Task/Grayscale-image/M2000-Interpreter/grayscale-image.m2000 index 229762871a..ed33411db2 100644 --- a/Task/Grayscale-image/M2000-Interpreter/grayscale-image.m2000 +++ b/Task/Grayscale-image/M2000-Interpreter/grayscale-image.m2000 @@ -1,201 +1,202 @@ Module P6P5 { - Function Bitmap { - def x as long, y as long, Import as boolean, P5 as boolean - If match("NN") then { - Read x, y - } else.if Match("N") Then { - \\ is a file? - Read f as long - buffer whitespace as byte - if not Eof(f) then { - get #f, whitespace :P6$=eval$(whitespace) - get #f, whitespace : P6$+=eval$(whitespace) - def boolean getW=true, getH=true, getV=true - def long v - \\ str$("P6") has 2 bytes. "P6" has 4 bytes - P5=p6$=str$("P5") - If p6$=str$("P6") or P5 Then { - do { - get #f, whitespace - if Eval$(whitespace)=str$("#") then { - do {get #f, whitespace} until eval(whitespace)=10 - } else { - select case eval(whitespace) - case 32, 9, 13, 10 - { if getW and x<>0 then { - getW=false - } else.if getH and y<>0 then { - getH=false - } else.if getV and v<>0 then { - getV=false - } - } - case 48 to 57 - {if getW then { - x*=10 - x+=eval(whitespace, 0)-48 - } else.if getH then { - y*=10 - y+=eval(whitespace, 0)-48 - } else.if getV then { - v*=10 - v+=eval(whitespace, 0)-48 - } - } - End Select - } - iF eof(f) then Error "Not a ppm file" - } until getV=false - } else Error "Not a P6 ppm or P5 ppm file" - Import=True - } - } else Error "No proper arguments" - if x<1 or y<1 then Error "Wrong dimensions" - structure rgb { - red as byte - green as byte - blue as byte - } - m=len(rgb)*x mod 4 - if m>0 then m=4-m ' add some bytes to raster line - m+=len(rgb) *x - Structure rasterline { - { - pad as byte*m - } - hline as rgb*x - } - Structure Raster { - magic as integer*4 - w as integer*4 - h as integer*4 - { - linesB as byte*len(rasterline)*y - } - lines as rasterline*y - } - Buffer Clear Image1 as Raster - Return Image1, 0!magic:="cDIB", 0!w:=Hex$(x,2), 0!h:=Hex$(y, 2) - if not Import then Return Image1, 0!lines:=Str$(String$(chrcode$(255), Len(rasterline)*y)) - Buffer Clear Pad as Byte*4 - SetPixel=Lambda Image1, Pad,aLines=Len(Raster)-Len(Rasterline), blines=-Len(Rasterline) (x, y, c) ->{ - where=alines+3*x+blines*y - if c>0 then c=color(c) - c-! - Return Pad, 0:=c as long - Return Image1, 0!where:=Eval(Pad, 2) as byte, 0!where+1:=Eval(Pad, 1) as byte, 0!where+2:=Eval(Pad, 0) as byte - } - GetPixel=Lambda Image1,aLines=Len(Raster)-Len(Rasterline), blines=-Len(Rasterline) (x,y) ->{ - where=alines+3*x+blines*y - =color(Eval(image1, where+2 as byte), Eval(image1, where+1 as byte), Eval(image1, where as byte)) - } - GetPixelGray=Lambda Image1,aLines=Len(Raster)-Len(Rasterline), blines=-Len(Rasterline) (x,y) ->{ - where=alines+3*x+blines*y - grayval=round(0.2126*Eval(image1, where+2 as byte) + 0.7152*Eval(image1, where+1 as byte) + 0.0722*Eval(image1, where as byte), 0) - =color(grayval,grayval,grayval) - } - StrDib$=Lambda$ Image1, Raster -> { - =Eval$(Image1, 0, Len(Raster)) - } - CopyImage=Lambda Image1 (image$) -> { - if left$(image$,12)=Eval$(Image1, 0, 24 ) Then { - Return Image1, 0:=Image$ - } Else Error "Can't Copy Image" - } - Export2File=Lambda Image1, x, y (f) -> { - Print #f, "P6";chr$(10);"# Created using M2000 Interpreter";chr$(10); - Print #f, x;" ";y;" 255";chr$(10); - x2=x-1 : where=0 : rasterline=x*3 - m=rasterline mod 4 : if m<>0 then rasterline+=4-m - Buffer pad as byte*3 - For y1=y-1 to 0 { - where=rasterline*y1 - For x1=0 to x2 { - Return pad, 0:=eval$(image1, 0!linesB!where, 3) - Push Eval(pad, 2) : Return pad, 2:=Eval(pad, 0), 0:=Number - Put #f, pad : where+=3 - } - } - } - Export2FileGray=Lambda Image1, x, y (f) -> { - Print #f, "P5";chr$(10);"# Created using M2000 Interpreter";chr$(10); - Print #f, x;" ";y;" 255";chr$(10); - x2=x-1 : where=0 : rasterline=x*3 - m=rasterline mod 4 : if m<>0 then rasterline+=4-m - Buffer pad as byte*3 - Buffer bytepad as byte - const R=0.2126, G=0.7152, B=0.0722 - For y1=y-1 to 0 { - where=rasterline*y1 - For x1=0 to x2 { - Return pad, 0:=eval$(image1, 0!linesB!where, 3) - Return bytepad, 0:=round(R*Eval(pad, 2) + G*Eval(pad, 1) + B*Eval(pad, 0), 0) - Put #f, bytepad : where+=3 - } - } - } - if Import then { - x0=x-1 : where=0 - Buffer Pad1 as byte*3 - Buffer Pad2 as byte - local rasterline=x*3 - m=rasterline mod 4 : if m<>0 then rasterline+=4-m - For y1=y-1 to 0 { - where=rasterline*y1 - For x1=0 to x0 { - if p5 then - Get #f, Pad2: m=eval(Pad2,0) : Return pad1, 0:=m, 1:=m, 2:=m - else - Get #f, Pad1 : Push Eval(pad1, 2) : Return pad1, 2:=Eval(pad1, 0), 0:=Number - End if - Return Image1, 0!linesB!where:=Eval$(Pad1) : where+=3 - } - } - } - Group Bitmap { - SetPixel=SetPixel - GetPixel=GetPixel - Image$=StrDib$ - Copy=CopyImage - ToFile=Export2File - ToFileGray=Export2FileGray - GetPixelGray=GetPixelGray - } - =Bitmap - } - Cls 5,0 - A=Bitmap(15,10) - B=Bitmap(15,10) - c1=color(100, 200, 255) - c2=color(180, 250, 128) - For i=0 to 8 - Call A.SetPixel(i, i, c1) - Call A.SetPixel(9, i,c2) - Next - Call A.SetPixel(i,i,c1) - // make a new one GrayScale (but 24bit) as B - For i=0 to 14 { For J=0 to 9 {Call B.SetPixel(i, j, A.GetPixelGray(i,j))}} - // place image A at 200 pixel from left margin, 100 pixel from top margin - Copy 200*twipsX, 100*twipsY use A.Image$(), 0, 400 ' zoom 400%, angle 0 - // place image B at 400 pixel from left margin, 100 pixel from top margin - Copy 400*twipsX, 100*twipsY use B.Image$(), 0, 400 ' zoom 400% - Try { - Open "P6example.ppm" For Output as #f - Call A.Tofile(f) - Close #f - Open "P5example.ppm" For Output as #f - Call A.TofileGray(f) - Close #f - Open "P5example.ppm" For Input as #f - C=Bitmap(f) - close #f - Copy 600*twipsX, 100*twipsY use C.Image$(), 0, 400 ' zoom 400% - Open "P6example.ppm" For Input as #f - C=Bitmap(f) - close #f - // use of Top clause to make the border color transparent at rotation - Copy 800*twipsX, 100*twipsY top C.Image$(), 30, 400 ' zoom 400%, angle 30 degree - } - Print "Done" + Class Bitmap { + { // from version 14 + Var x As long, y As long, Import As boolean, P5 As boolean + If match("NN") Then + Read x, y + Else.if Match("N") Then + Read f As long + buffer whitespace As Byte + if not Eof(f) Then + get #f, whitespace :P6$=eval$(whitespace) + get #f, whitespace : P6$+=eval$(whitespace) + boolean getW=true, getH=true, getV=true + long v + P5=p6$=str$("P5") + If p6$=str$("P6") or P5 Then + do + get #f, whitespace + if Eval$(whitespace)=str$("#") Then + do + get #f, whitespace + until eval(whitespace)=10 + Else + select case eval(whitespace) + case 32, 9, 13, 10 + { + if getW and x<>0 Then + getW=false + Else.if getH and y<>0 Then + getH=false + Else.if getV and v<>0 Then + getV=false + End If + } + case 48 To 57 + { + if getW Then + x*=10 + x+=eval(whitespace, 0)-48 + Else.if getH Then + y*=10 + y+=eval(whitespace, 0)-48 + Else.if getV Then + v*=10 + v+=eval(whitespace, 0)-48 + End If + } + End Select + End If + iF eof(f) Then Error "Not a ppm file" + until getV=false + Else + Error "Not a P6 ppm or P5 ppm file" + End If + Import=True + End if + Else + Error "No proper arguments" + End If + if x<1 or y<1 Then Error "Wrong dimensions" + Buffer Clear Pad1 As Byte*3 + structure rgb { + red As Byte + green As Byte + blue As Byte + } + m=len(rgb)*x mod 4 + if m>0 Then m=4-m ' add some bytes To raster line + m+=len(rgb) *x + Structure rasterline { + { + pad As Byte*m + } + hline As rgb*x + } + Structure Raster { + magic As integer*4 + w As integer*4 + h As integer*4 + { + linesB As Byte*len(rasterline)*y + } + lines As rasterline*y + } + Buffer Clear Image1 As Raster + Return Image1, 0!magic:="cDIB", 0!w:=Hex$(x,2), 0!h:=Hex$(y, 2) + if not Import Then Return Image1, 0!lines:=Str$(String$(chrcode$(255), Len(rasterline)*y)) + Buffer Clear Pad As Byte*4 + aLines=Len(Raster)-Len(Rasterline)-Raster("linesB") + blines=-Len(Rasterline) + if Import Then + x0=x-1 : where=0 + Buffer Pad1 As Byte*3 + Buffer Pad2 As Byte + local rasterline=x*3 + m=rasterline mod 4 : if m<>0 Then rasterline+=4-m + For y1=y-1 To 0 + where=rasterline*y1 + For x1=0 To x0 + if p5 Then + Get #f, Pad2: m=eval(Pad2,0) : Return pad1, 0:=m, 1:=m, 2:=m + Else + Get #f, Pad1 : Push Eval(pad1, 2) : Return pad1, 2:=Eval(pad1, 0), 0:=Number + End if + Image1|linesB[where]=Pad1[0, 3] : where+=3 + Next + Next + End if + } + SetPixel=Lambda Image1, Pad, aLines, blines (x, y, c) ->{ + if c>0 Then c=color(c) + c-! + Return Pad, 0:=c As long + Push pad[2] : pad[2]=pad[0]: pad[0]=Number + Image1|linesB[alines+3*x+blines*y]=Pad[0, 3] + } + GetPixel=Lambda Image1,aLines, blines, Pad1 (x,y) ->{ + Pad1[0]=Image1|linesB[alines+3*x+blines*y, 3] + =color(Pad1[2], Pad1[1],Pad1[0]) + } + GetPixelGray=Lambda Image1,aLines, blines, Pad1 (x,y) ->{ + Pad1[0]=Image1|linesB[alines+3*x+blines*y, 3] + grayval=round(0.2126*Pad1[2] + 0.7152*Pad1[1] + 0.0722*Pad1[0], 0) + =color(grayval,grayval,grayval) + } + Image$=Lambda$ Image1, Raster ->Eval$(Image1, 0, Len(Raster)) + Copy=Lambda Image1 (image$) -> { + if left$(image$,12)=Image1[0, 24] Then + Return Image1, 0:=Image$ + Else + Error "Can't Copy Image" + End if + } + ToFile=Lambda Image1, x, y (f) -> { + Print #f, "P6";chr$(10);"# Created using M2000 Interpreter";chr$(10); + Print #f, x;" ";y;" 255";chr$(10); + x2=x-1 : where=0 : rasterline=x*3 + m=rasterline mod 4 : if m<>0 Then rasterline+=4-m + Buffer pad As Byte*3 + For y1=y-1 To 0 + where=rasterline*y1 + For x1=0 To x2 + pad[0]=image1|linesB[where, 3] + Push pad[2] : pad[2]=pad[0]: pad[0]=Number + Put #f, pad : where+=3 + Next + Next + } + ToFileGray=Lambda Image1, x, y (f) -> { + Print #f, "P5";chr$(10);"# Created using M2000 Interpreter";chr$(10); + Print #f, x;" ";y;" 255";chr$(10); + x2=x-1 : where=0 : rasterline=x*3 + m=rasterline mod 4 : if m<>0 Then rasterline+=4-m + Buffer pad As Byte*3 + Buffer bytepad As Byte + const R=0.2126, G=0.7152, B=0.0722 + For y1=y-1 To 0 + where=rasterline*y1 + For x1=0 To x2 + Return pad, 0:=eval$(image1, 0!linesB!where, 3) + Return bytepad, 0:=round(R*Eval(pad, 2) + G*Eval(pad, 1) + B*Eval(pad, 0), 0) + Put #f, bytepad : where+=3 + Next + Next + } + } + Cls 5,0 + A=Bitmap(15,10) + B=Bitmap(15,10) + c1=color(100, 200, 255) + c2=color(180, 250, 128) + For i=0 To 8 + Call A.SetPixel(i, i, c1) + Call A.SetPixel(9, i,c2) + Next + Call A.SetPixel(i,i,c1) + // make a new one GrayScale (but 24bit) As B + For i=0 To 14 { For J=0 To 9 {Call B.SetPixel(i, j, A.GetPixelGray(i,j))}} + // place image A at 200 pixel from left margin, 100 pixel from top margin + Copy 200*twipsX, 100*twipsY use A.Image$(), 0, 800 ' zoom 800%, angle 0 + // place image B at 400 pixel from left margin, 100 pixel from top margin + Copy 400*twipsX, 100*twipsY use B.Image$(), 0, 800 ' zoom 800% + Try { + Open "P6example.ppm" For Output As #f + Call A.Tofile(f) + Close #f + Open "P5example.ppm" For Output As #f + Call A.TofileGray(f) + Close #f + Open "P5example.ppm" For Input As #f + C=Bitmap(f) + close #f + Copy 600*twipsX, 100*twipsY use C.Image$(), 0, 800 ' zoom 800% + Open "P6example.ppm" For Input As #f + C=Bitmap(f) + close #f + // use of Top clause To make the border color transparent at rotation + Copy 800*twipsX, 100*twipsY top C.Image$(), 30, 800 ' zoom 800%, angle 30 degree + } + Print "Done" } P6P5 diff --git a/Task/Greatest-subsequential-sum/Ballerina/greatest-subsequential-sum.ballerina b/Task/Greatest-subsequential-sum/Ballerina/greatest-subsequential-sum.ballerina new file mode 100644 index 0000000000..3ee409c7ea --- /dev/null +++ b/Task/Greatest-subsequential-sum/Ballerina/greatest-subsequential-sum.ballerina @@ -0,0 +1,42 @@ +import ballerina/io; + +function gss(int[] s) returns [int[], int] { + int best = 0; + int strt = 0; + int end = 0; + int sum = 0; + int sumStart = 0; + foreach var [i, x] in s.enumerate() { + sum += x; + if sum > best { + best = sum; + strt = sumStart; + end = i + 1; + } else if sum < 0 { + sum = 0; + sumStart = i + 1; + } + } + return [s.slice(strt, end), best]; +} + +function A(any[] a) returns string { + return re `,`.replaceAll(a.toString(), ", "); +} + +public function main() { + var tests = [ + [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1], + [-1, 1, 2, -5, -6], + [], + [-1, -2, -1] + ]; + foreach var test in tests { + io:println("Input: ", A(test)); + var res = gss(test); + var subSeq = res[0]; + int sum = res[1]; + io:println("Sub seq: ", A(subSeq)); + io:println("Sum: ", sum, "\n"); + } +} diff --git a/Task/Greatest-subsequential-sum/EasyLang/greatest-subsequential-sum.easy b/Task/Greatest-subsequential-sum/EasyLang/greatest-subsequential-sum.easy index acb989f2c7..90385e92e1 100644 --- a/Task/Greatest-subsequential-sum/EasyLang/greatest-subsequential-sum.easy +++ b/Task/Greatest-subsequential-sum/EasyLang/greatest-subsequential-sum.easy @@ -1,4 +1,4 @@ -proc max_subseq . seq[] start stop maxsum . +proc max_subseq &seq[] &start &stop &maxsum . maxsum = 0 i = 1 start = 1 @@ -18,6 +18,4 @@ proc max_subseq . seq[] start stop maxsum . a[] = [ -1 -2 3 5 6 -2 -1 4 -4 2 -1 ] max_subseq a[] a b sum print "Max sum = " & sum -for i = a to b - write a[i] & " " -. +for i = a to b : write a[i] & " " diff --git a/Task/Greatest-subsequential-sum/M2000-Interpreter/greatest-subsequential-sum-1.m2000 b/Task/Greatest-subsequential-sum/M2000-Interpreter/greatest-subsequential-sum-1.m2000 new file mode 100644 index 0000000000..1eb7221eed --- /dev/null +++ b/Task/Greatest-subsequential-sum/M2000-Interpreter/greatest-subsequential-sum-1.m2000 @@ -0,0 +1,26 @@ +module Greatest_subsequential_sum { + showGSS=lambda (a)->{ + function Greatest_subsequential_sum(a as array){ + s=a#sum() + =a + p=len(a)-1 + if p<0 then exit + for i=0 to p + for j=i to p + k= a#slice(i, j) + m=k#sum() + if m>s then =k: s=m + next + next + } + = "("+a#str$(",")+") -> ("+ Greatest_subsequential_sum(a)#str$(",")+")" + } + open "out.txt" for output as#f + print #f, showGSS((-1 , 2 , -1)) + print #f, showGSS((-1, 2, -1, 3, -1)) + print #f, showGSS((-1, 1, 2, -5, -6)) + print #f, showGSS((-1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1)) + close #f + win notepad, dir$+"out.txt" +} +Greatest_subsequential_sum diff --git a/Task/Greatest-subsequential-sum/M2000-Interpreter/greatest-subsequential-sum-2.m2000 b/Task/Greatest-subsequential-sum/M2000-Interpreter/greatest-subsequential-sum-2.m2000 new file mode 100644 index 0000000000..a16c08d534 --- /dev/null +++ b/Task/Greatest-subsequential-sum/M2000-Interpreter/greatest-subsequential-sum-2.m2000 @@ -0,0 +1,36 @@ +module Greatest_subsequential_sum (filename) { + showGSS=lambda (a)->{ + function Greatest_subsequential_sum(a as array){ + var best = 0 + var start = 0 + var end = 0 + var sum = 0 + var sumStart = 0 + var i = 0 + s=each(a) + while s { + sum +=array(s) + if (sum > best) then { + best = sum + start = sumStart + end = i + 1 + } else.if (sum < 0) then { + sum = 0 + sumStart = i + 1 + } + i++ + } + =a#slice(start, end-1) + } + = "("+a#str$(",")+") -> ("+ Greatest_subsequential_sum(a)#str$(",")+")" + } + open filename for output as#f + print #f, showGSS((-1 , 2 , -1)) + print #f, showGSS((-1, 2, -1, 3, -1)) + print #f, showGSS((-1, 1, 2, -5, -6)) + print #f, showGSS((-1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1)) + close #f + if filename<>"" then win notepad, dir$+filename +} +Greatest_subsequential_sum "" ' to screen +Greatest_subsequential_sum "out.txt" diff --git a/Task/Greedy-algorithm-for-Egyptian-fractions/JavaScript/greedy-algorithm-for-egyptian-fractions.js b/Task/Greedy-algorithm-for-Egyptian-fractions/JavaScript/greedy-algorithm-for-egyptian-fractions.js new file mode 100644 index 0000000000..7c80a0f77e --- /dev/null +++ b/Task/Greedy-algorithm-for-Egyptian-fractions/JavaScript/greedy-algorithm-for-egyptian-fractions.js @@ -0,0 +1,222 @@ +// Egyptian Fractions implementation in JavaScript +// Using BigInt for arbitrary precision integers + +function gcd(a, b) { + if (b === 0n) { + return a; + } + return gcd(b, a % b); +} + +class Frac { + constructor(n, d) { + // Handle different input types (number or BigInt) + const num = typeof n === 'number' ? BigInt(n) : n; + const denom = typeof d === 'number' ? BigInt(d) : d; + + if (denom === 0n) { + throw new Error("Parameter d may not be zero."); + } + + let nn = num; + let dd = denom; + + if (nn === 0n) { + dd = 1n; + } else if (dd < 0n) { + nn = -nn; + dd = -dd; + } + + const g = gcd(nn < 0n ? -nn : nn, dd).valueOf(); + + if (g > 0n) { + nn = nn / g; + dd = dd / g; + } + + this.num = nn; + this.denom = dd; + } + + plus(rhs) { + return new Frac( + this.num * rhs.denom + this.denom * rhs.num, + this.denom * rhs.denom + ); + } + + unaryMinus() { + return new Frac(-this.num, this.denom); + } + + minus(rhs) { + return this.plus(rhs.unaryMinus()); + } + + compareTo(rhs) { + // We'll compare by cross multiplication to avoid floating point issues + const leftSide = this.num * rhs.denom; + const rightSide = rhs.num * this.denom; + + if (leftSide < rightSide) return -1; + if (leftSide > rightSide) return 1; + return 0; + } + + equals(obj) { + if (!(obj instanceof Frac)) { + return false; + } + return this.compareTo(obj) === 0; + } + + toString() { + if (this.denom === 1n) { + return this.num.toString(); + } + return `${this.num}/${this.denom}`; + } + + toNumber() { + // Convert fraction to a regular number (potentially with loss of precision) + return Number(this.num) / Number(this.denom); + } + + toEgyptian() { + if (this.num === 0n) { + return [this]; + } + + const fracs = []; + + if ((this.num < 0n ? -this.num : this.num) >= (this.denom < 0n ? -this.denom : this.denom)) { + // Handle improper fractions + const div = new Frac(this.num / this.denom, 1n); + const rem = this.minus(div); + fracs.push(div); + this._toEgyptian(rem.num, rem.denom, fracs); + } else { + this._toEgyptian(this.num, this.denom, fracs); + } + + return fracs; + } + + _toEgyptian(n, d, fracs) { + if (n === 0n) { + return; + } + + // Calculate ceiling of d/n + let div = d / n; + if (d % n !== 0n) { + div = div + 1n; + } + + fracs.push(new Frac(1n, div)); + + // Calculate next fraction's numerator and denominator + let n3 = -(d % n); + if (n3 < 0n) { + n3 = n3 + n; + } + + const d3 = d * div; + const f = new Frac(n3, d3); + + if (f.num === 1n) { + fracs.push(f); + return; + } + + this._toEgyptian(f.num, f.denom, fracs); + } +} + +// Main function +function main() { + const fracs = [ + new Frac(43, 48), + new Frac(5, 121), + new Frac(2014, 59) + ]; + + for (const frac of fracs) { + const list = frac.toEgyptian(); + const first = list[0]; + + if (first.denom === 1n) { + process.stdout.write(`${frac} -> [${first}] + `); + } else { + process.stdout.write(`${frac} -> ${first}`); + } + + for (let i = 1; i < list.length; ++i) { + process.stdout.write(` + ${list[i]}`); + } + + console.log(); + } + + for (const r of [98, 998]) { + if (r === 98) { + console.log("\nFor proper fractions with 1 or 2 digits:"); + } else { + console.log("\nFor proper fractions with 1, 2 or 3 digits:"); + } + + let maxSize = 0; + let maxSizeFracs = []; + let maxDen = 0n; + let maxDenFracs = []; + + // Create sieve array + const sieve = Array(r + 1).fill().map(() => Array(r + 2).fill(false)); + + for (let i = 1; i < r; ++i) { + for (let j = i + 1; j < r + 1; ++j) { + if (sieve[i][j]) continue; + + const f = new Frac(i, j); + const list = f.toEgyptian(); + const listSize = list.length; + + if (listSize > maxSize) { + maxSize = listSize; + maxSizeFracs = [f]; + } else if (listSize === maxSize) { + maxSizeFracs.push(f); + } + + const listDen = list[list.length - 1].denom; + + if (listDen > maxDen) { + maxDen = listDen; + maxDenFracs = [f]; + } else if (listDen === maxDen) { + maxDenFracs.push(f); + } + + if (i < r / 2) { + let k = 2; + while (true) { + if (j * k > r + 1) break; + sieve[i * k][j * k] = true; + k++; + } + } + } + } + + console.log(` largest number of items = ${maxSize}`); + console.log(`fraction(s) with this number : ${maxSizeFracs}`); + + const md = maxDen.toString(); + console.log(` largest denominator = ${md.length} digits, ${md.substring(0, 20)}...${md.substring(md.length - 20)}`); + console.log(`fraction(s) with this denominator : ${maxDenFracs}`); + } +} + +// Run the main function +main(); diff --git a/Task/Greyscale-bars-Display/EasyLang/greyscale-bars-display.easy b/Task/Greyscale-bars-Display/EasyLang/greyscale-bars-display.easy index cd8133e96a..0d55e19187 100644 --- a/Task/Greyscale-bars-Display/EasyLang/greyscale-bars-display.easy +++ b/Task/Greyscale-bars-Display/EasyLang/greyscale-bars-display.easy @@ -6,9 +6,8 @@ for row = 0 to 3 if row mod 2 = 1 c = 1 - c . - color3 c c c - move sz * i 75 - row * 25 - rect sz + 1 25 + gcolor3 c c c + grect sz * i 75 - row * 25 sz + 1 25 sleep 0.02 . n *= 2 diff --git a/Task/HTTP/Elena/http.elena b/Task/HTTP/Elena/http.elena new file mode 100644 index 0000000000..b8a54ec4f4 --- /dev/null +++ b/Task/HTTP/Elena/http.elena @@ -0,0 +1,13 @@ +import net'http; + +public program() +{ + using(HttpClient client := HttpClient.open("http://www.google.com")) + { + HttpResponse response := client.get(); + + string content := response.readAsString(); + + Console.writeLine(content); + }; +} diff --git a/Task/HTTPS/Elena/https.elena b/Task/HTTPS/Elena/https.elena new file mode 100644 index 0000000000..f383e964fb --- /dev/null +++ b/Task/HTTPS/Elena/https.elena @@ -0,0 +1,14 @@ +import net'http; +import mbedtls'registration; + +public program() +{ + using(HttpClient client := HttpClient.open("https://www.google.com")) + { + HttpResponse response := client.get(); + + string content := response.readAsString(); + + Console.writeLine(content); + }; +} diff --git a/Task/Hailstone-sequence/Ballerina/hailstone-sequence.ballerina b/Task/Hailstone-sequence/Ballerina/hailstone-sequence.ballerina new file mode 100644 index 0000000000..775dc1646d --- /dev/null +++ b/Task/Hailstone-sequence/Ballerina/hailstone-sequence.ballerina @@ -0,0 +1,34 @@ +import ballerina/io; + +function hailstone(int m) returns int[] { + int n = m; + int[] h = [n]; + while n != 1 { + n = n % 2 == 0 ? n / 2 : 3 * n + 1; + h.push(n); + } + return h; +} + +public function main() { + int[] h = hailstone(27); + int len = h.length(); + io:println("For the Hailstone sequence starting with n = 27:"); + io:println(" Number of elements = ", len); + io:println(" First four elements = ", h.slice(0, 4)); + io:println(" Final four elements = ", h.slice(len - 4)); + + io:println("\nThe Hailstone sequence for n < 100,000 with the longest length is:"); + int longest = 0; + int longlen = 0; + foreach int n in 1...99999 { + h = hailstone(n); + len = h.length(); + if len > longlen { + longest = n; + longlen = len; + } + } + io:println(` Longest = ${longest}`); + io:println(` Length = ${longlen}`); +} diff --git a/Task/Hailstone-sequence/EasyLang/hailstone-sequence.easy b/Task/Hailstone-sequence/EasyLang/hailstone-sequence.easy index a5606e817c..ff201550a8 100644 --- a/Task/Hailstone-sequence/EasyLang/hailstone-sequence.easy +++ b/Task/Hailstone-sequence/EasyLang/hailstone-sequence.easy @@ -1,4 +1,4 @@ -proc hailstone n . list[] . +proc hailstone n &list[] . list[] = [ ] while n <> 1 list[] &= n @@ -12,19 +12,15 @@ proc hailstone n . list[] . . hailstone 27 l[] write "27 has length " & len l[] & " with " -for i to 4 - write l[i] & " " -. +for i to 4 : write l[i] & " " write "... " -for i = len l[] - 3 to len l[] - write l[i] & " " -. +for i = len l[] - 3 to len l[] : write l[i] & " " print "" for i = 1 to 100000 hailstone i l[] if len l[] >= max_iter max_i = i max_iter = len l[] - end -end + . +. print max_i & " has length " & max_iter diff --git a/Task/Hailstone-sequence/Odin/hailstone-sequence.odin b/Task/Hailstone-sequence/Odin/hailstone-sequence.odin new file mode 100644 index 0000000000..dbe6f83782 --- /dev/null +++ b/Task/Hailstone-sequence/Odin/hailstone-sequence.odin @@ -0,0 +1,65 @@ +package main + +import "core:fmt" + +collatz :: proc(array:^[dynamic]int,n:int){ + i:=1 + n:=n + for n!=1{ + + if (n%2==0){ + n=n/2 + append(&array^,n) + } + else{ + n=3*n+1 + append(&array^,n) + } + + } +} + +main :: proc() { + n:=27 + + max:=0 + max_length:=0 + + dummy:[dynamic]int + defer delete(dummy) + append(&dummy,n) + collatz(&dummy,n) + + + fmt.println("the first four of sequence for 27: ") + for jj:=0;jj<4;jj+=1{ + fmt.println(dummy[jj]) + } + fmt.println("the last four of sequence for 27: ") + for jj:=0;jj<4;jj+=1{ + fmt.println(dummy[len(dummy)-4+jj]) + } + fmt.println("length of sequence for 27") + fmt.println(len(dummy)) + + + for (len(dummy)>0){ + pop(&dummy) + } + + for ii:=1;ii<100000;ii+=1{ + append(&dummy,ii) + collatz(&dummy,ii) + if(len(dummy)>max_length){ + max = ii + max_length=len(dummy) + } + for (len(dummy)>0){ + pop(&dummy) + } + } + fmt.println("Max number: ") + fmt.println(max) + fmt.println("Max length: ") + fmt.println(max_length) +} diff --git a/Task/Halt-and-catch-fire/R/halt-and-catch-fire-1.r b/Task/Halt-and-catch-fire/R/halt-and-catch-fire-1.r new file mode 100644 index 0000000000..39a97b302c --- /dev/null +++ b/Task/Halt-and-catch-fire/R/halt-and-catch-fire-1.r @@ -0,0 +1 @@ +stop() diff --git a/Task/Halt-and-catch-fire/R/halt-and-catch-fire-2.r b/Task/Halt-and-catch-fire/R/halt-and-catch-fire-2.r new file mode 100644 index 0000000000..1e5b3ea0c8 --- /dev/null +++ b/Task/Halt-and-catch-fire/R/halt-and-catch-fire-2.r @@ -0,0 +1 @@ +array()[,] diff --git a/Task/Hamming-numbers/REXX/hamming-numbers-1.rexx b/Task/Hamming-numbers/REXX/hamming-numbers-1.rexx deleted file mode 100644 index cc53b7ad15..0000000000 --- a/Task/Hamming-numbers/REXX/hamming-numbers-1.rexx +++ /dev/null @@ -1,20 +0,0 @@ -/*REXX program computes Hamming numbers: 1 ──► 20, # 1691, and the one millionth. */ -numeric digits 100 /*ensure enough decimal digits. */ -call hamming 1, 20 /*show the 1st ──► twentieth Hamming #s*/ -call hamming 1691 /*show the 1,691st Hamming number. */ -call hamming 1000000 /*show the 1 millionth Hamming number.*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -hamming: procedure; parse arg x,y; if y=='' then y= x; w= length(y) - #2= 1; #3= 1; #5= 1; @.= 0; @.1= 1 - do n=2 for y-1 - @.n= min(2*@.#2, 3*@.#3, 5*@.#5) /*pick the minimum of 3 Hamming numbers*/ - if 2*@.#2 == @.n then #2= #2 + 1 /*number already defined? Use next #. */ - if 3*@.#3 == @.n then #3= #3 + 1 /* " " " " " " */ - if 5*@.#5 == @.n then #5= #5 + 1 /* " " " " " " */ - end /*n*/ /* [↑] maybe assign next 3 Hamming#s. */ - do j=x to y; say 'Hamming('right(j, w)") =" @.j - end /*j*/ - - say right( 'length of last Hamming number =' length(@.y), 70); say - return diff --git a/Task/Hamming-numbers/REXX/hamming-numbers-2.rexx b/Task/Hamming-numbers/REXX/hamming-numbers-2.rexx deleted file mode 100644 index bccf09bbe0..0000000000 --- a/Task/Hamming-numbers/REXX/hamming-numbers-2.rexx +++ /dev/null @@ -1,26 +0,0 @@ -/*REXX program computes Hamming numbers: 1 ──► 20, # 1691, and the one millionth.*/ -call hamming 1, 20 /*show the 1st ──► twentieth Hamming #s*/ -call hamming 1691 /*show the 1,691st Hamming number. */ -call hamming 1000000 /*show the 1 millionth Hamming number.*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -hamming: procedure; arg x,y; if y=='' then y= x; w= length(y); L= length(y-1); p= 2**L - numeric digits max(9, p + p%4 + p%16) /*ensure enough decimal digits. */ - #2= 1; #3= 1; #5= 1; @.= 0; @.1= 1 - do n=2 for y-1 - _2= @.#2 + @.#2 /*this is faster than: @.#2 * 2 */ - _3= @.#3 + @.#3 + @.#3 /* " " " " @,#3 * 3 */ - _5= @.#5 * 5 - m= _2 /*assume a minimum (of the 3 Hammings).*/ - if _3 < m then m= _3 /*is this number less than the minimum?*/ - if _5 < m then m= _5 /* " " " " " " " */ - @.n= m /*now, assign the next Hamming number.*/ - if _2 == m then #2= #2 + 1 /*number already defined? Use next #.*/ - if _3 == m then #3= #3 + 1 /* " " " " " " */ - if _5 == m then #5= #5 + 1 /* " " " " " " */ - end /*n*/ /* [↑] maybe assign next Hamming #'s. */ - do j=x to y; say 'Hamming('right(j, w)") =" @.j - end /*j*/ - - say right( 'length of last Hamming number =' length(@.y), 70); say - return diff --git a/Task/Hamming-numbers/REXX/hamming-numbers-3.rexx b/Task/Hamming-numbers/REXX/hamming-numbers-3.rexx deleted file mode 100644 index ed4dfa5cbb..0000000000 --- a/Task/Hamming-numbers/REXX/hamming-numbers-3.rexx +++ /dev/null @@ -1,26 +0,0 @@ -/*REXX program computes Hamming numbers: 1 ──► 20, # 1691, and the one millionth.*/ -call hamming 1, 20 /*show the 1st ──► twentieth Hamming #s*/ -call hamming 1691 /*show the 1,691st Hamming number. */ -call hamming 1000000 /*show the 1 millionth Hamming number.*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -hamming: procedure; arg x,y; if y=='' then y= x; w= length(y); L= length(y-1); p= 2**L - numeric digits max(9, p + p%4 + p%16) /*ensure enough decimal digits. */ - #2= 1; #3= 1; #5= 1; @.= 0; @.1= 1 - do n=2 for y-1 - _2= @.#2 + @.#2 /*this is faster than: @.#2 * 2 */ - _3= @.#3 + @.#3 + @.#3 /* " " " " @,#3 * 3 */ - _5= @.#5 * 5 - m= _2 /*assume a minimum (of the 3 Hammings).*/ - if _3 < m then m= _3 /*is this number less than the minimum?*/ - if _5 < m then m= _5 /* " " " " " " " */ - @.n= format(m,,,,0) /*now, assign the next Hamming number.*/ - if _2 == m then #2= #2 + 1 /*number already defined? Use next #.*/ - if _3 == m then #3= #3 + 1 /* " " " " " " */ - if _5 == m then #5= #5 + 1 /* " " " " " " */ - end /*n*/ /* [↑] maybe assign next Hamming #'s. */ - do j=x to y; say 'Hamming('right(j, w)") =" @.j / 1 - end /*j*/ - - say right( 'length of last Hamming number =' length(@.y / 1), 70); say - return diff --git a/Task/Hamming-numbers/REXX/hamming-numbers-4.rexx b/Task/Hamming-numbers/REXX/hamming-numbers-4.rexx deleted file mode 100644 index 3d590eb3a0..0000000000 --- a/Task/Hamming-numbers/REXX/hamming-numbers-4.rexx +++ /dev/null @@ -1,73 +0,0 @@ -include Settings - -say version; say 'Hamming numbers'; say -call Hammings 1e6 -call ShowFirstN 20 -call ShowNth 1691 -call ShowNth 1e6 -call Hammings 1e7 -call ShowNth 1e7 -exit - -Hammings: -procedure expose hamm. -arg xx -call Time('r') -xx = xx/1 -say 'Collect Hamming numbers up to the' xx'th' -/* Ensure enough digits */ -numeric digits 2**(Length(xx)+1) -/* Dijkstra */ -hamm.hamming.1 = 1 -x2 = 2; x3 = 3; x5 = 5; i2 = 1; i3 = 1; i5 = 1 -do yy = 2 - h = x2 - if x3 < h then - h = x3 - if x5 < h then - h = x5 - hamm.hamming.yy = h - if yy = xx then - leave - if x2 = h then do - i2 = i2+1; x2 = hamm.hamming.i2+hamm.hamming.i2 - end - if x3 = h then do - i3 = i3+1; x3 = hamm.hamming.i3+hamm.hamming.i3+hamm.hamming.i3 - end - if x5 = h then do - i5 = i5+1; x5 = hamm.hamming.i5*5 - end -end -hamm.0 = yy -say Time('e')/1 'seconds' -say -return - -ShowFirstN: -procedure expose hamm. -arg xx -call Time('r') -xx = xx/1 -say 'First' xx 'Hamming numbers are' -do i = 1 to xx - call Charout ,Right(hamm.hamming.i,5) - if i//10 = 0 then - say -end -say Time('e')/1 'seconds' -say -return - -ShowNth: -procedure expose hamm. -arg xx -xx = xx/1 -call Time('r') -say xx'th Hamming Number is' -say hamm.hamming.xx '('Length(hamm.hamming.xx) 'digits)' -say Time('e')/1 'seconds' -say -return - -include Abend diff --git a/Task/Hamming-numbers/REXX/hamming-numbers.rexx b/Task/Hamming-numbers/REXX/hamming-numbers.rexx new file mode 100644 index 0000000000..2b39f1cf89 --- /dev/null +++ b/Task/Hamming-numbers/REXX/hamming-numbers.rexx @@ -0,0 +1,40 @@ +-- 22 Mar 2025 +include Settings + +say 'HAMMING NUMBERS' +say version +say +call Hammings 1000000 +call ShowFirstN 20 +call ShowNth 1691 +call ShowNth 1000000 +call Hammings 10000000 +call ShowNth 10000000 +say Time('e')/1 'seconds' +exit + +ShowFirstN: +procedure expose hamm. +arg xx +xx = xx/1 +say 'First' xx 'Hamming numbers are' +do i = 1 to xx + call Charout ,Right(hamm.i,5) + if i//10 = 0 then + say +end +say +return + +ShowNth: +procedure expose hamm. +arg xx +xx = xx/1 +say xx'th Hamming number is' +say hamm.xx '('Length(hamm.xx) 'digits)' +say +return + +include Sequences +include Functions +include Abend diff --git a/Task/Harmonic-series/EasyLang/harmonic-series.easy b/Task/Harmonic-series/EasyLang/harmonic-series.easy index 75a56234c7..fbf03db1cf 100644 --- a/Task/Harmonic-series/EasyLang/harmonic-series.easy +++ b/Task/Harmonic-series/EasyLang/harmonic-series.easy @@ -1,4 +1,4 @@ -numfmt 5 2 +numfmt 2 5 print "The first twenty harmonic numbers are:" for n = 1 to 20 h += 1 / n diff --git a/Task/Harmonic-series/Fortran/harmonic-series.f b/Task/Harmonic-series/Fortran/harmonic-series.f new file mode 100644 index 0000000000..2ab5783463 --- /dev/null +++ b/Task/Harmonic-series/Fortran/harmonic-series.f @@ -0,0 +1,83 @@ +program harmonic_numbers + use :: iso_fortran_env, only: int64, output_unit + implicit none + integer, parameter :: real64 = selected_real_kind(15, 307) + + type :: fraction + integer(int64) :: numerator + integer(int64) :: denominator + end type fraction + + integer :: i, target_int + type(fraction) :: h_exact + real(real64) :: sum_h, h_decimal + character(len=200) :: fmt_str + + ! Print first 20 harmonic numbers as fractions + write(output_unit, '(a)') "## First 20 Harmonic Numbers" + write(output_unit, '(a)') "**Fractional Form**" + h_exact = fraction(0_int64, 1_int64) + do i = 1, 20 + h_exact = add_reciprocal(h_exact, i) + write(output_unit, '(i2, ": ", i0, "/", i0)') i, h_exact%numerator, h_exact%denominator + end do + + ! Print decimal approximations + write(output_unit, '(/, a)') "**Decimal Approximations**" + h_exact = fraction(0_int64, 1_int64) + do i = 1, 20 + h_exact = add_reciprocal(h_exact, i) + h_decimal = real(h_exact%numerator, real64) / real(h_exact%denominator, real64) + write(output_unit, '(i2, ": ", f0.12)') i, h_decimal + end do + + ! Find positions where harmonic numbers exceed integers 1-10 + write(output_unit, '(/, a)') "## Positions Where H? First Exceeds Integers" + write(output_unit, '(a)') "| Target | Position (n) | Decimal Approximation |" + write(output_unit, '(a)') "|--------|--------------|------------------------|" + write(fmt_str, '(a)') '(a, i2, a, T10, A, i0,T25, a, f0.6, T50,a)' + + do target_int = 1, 10 + sum_h = 0._real64 + i = 0 + do + i = i + 1 + sum_h = sum_h + 1.0_real64 / real(i, real64) + if (sum_h > real(target_int, real64)) then + if (target_int <= 5 .or. target_int >= 6) then + write(output_unit, FMT_STR) "| **", target_int, "**","| ", i, & + "| ", real(sum_h, real64), "|" + end if + exit + end if + end do + end do + +contains + + function add_reciprocal(h, n) result(new_h) + type(fraction), intent(in) :: h + integer, intent(in) :: n + type(fraction) :: new_h + integer(int64) :: common_denominator, new_numerator, divisor + + common_denominator = h%denominator * int(n, int64) + new_numerator = h%numerator * int(n, int64) + h%denominator + divisor = gcd(new_numerator, common_denominator) + + new_h%numerator = new_numerator / divisor + new_h%denominator = common_denominator / divisor + end function add_reciprocal + + recursive function gcd(a, b) result(greatest_common_divisor) + integer(int64), intent(in) :: a, b + integer(int64) :: greatest_common_divisor + + if (b == 0) then + greatest_common_divisor = a + else + greatest_common_divisor = gcd(b, mod(a, b)) + end if + end function gcd + +end program harmonic_numbers diff --git a/Task/Hello-world-Graphical/Autohotkey-V2/hello-world-graphical.ahk b/Task/Hello-world-Graphical/AutoHotKey-V2/hello-world-graphical.ahk similarity index 100% rename from Task/Hello-world-Graphical/Autohotkey-V2/hello-world-graphical.ahk rename to Task/Hello-world-Graphical/AutoHotKey-V2/hello-world-graphical.ahk diff --git a/Task/Hello-world-Graphical/EasyLang/hello-world-graphical.easy b/Task/Hello-world-Graphical/EasyLang/hello-world-graphical.easy index 9c9925f5d9..ec655ec617 100644 --- a/Task/Hello-world-Graphical/EasyLang/hello-world-graphical.easy +++ b/Task/Hello-world-Graphical/EasyLang/hello-world-graphical.easy @@ -1,2 +1,2 @@ -move 10 20 -text "Goodbye, World!" +gcolor 700 +gtext 10 60 "Goodbye, World!" diff --git a/Task/Hello-world-Graphical/Odin/hello-world-graphical.odin b/Task/Hello-world-Graphical/Odin/hello-world-graphical.odin new file mode 100644 index 0000000000..18c4fd4bd0 --- /dev/null +++ b/Task/Hello-world-Graphical/Odin/hello-world-graphical.odin @@ -0,0 +1,27 @@ +package main + +import "core:fmt" +import "core:c" +import "base:runtime" + +import "core:sys/windows" + + +main :: proc () { + + + lptextt:="Goodbye, World!" + lptextw:= windows.utf8_to_wstring(lptextt, context.temp_allocator) + lptext:= transmute([^]u16)lptextw + + lptextt2:="Title" + lptextw2:= windows.utf8_to_wstring(lptextt2, context.temp_allocator) + lptext2:= transmute([^]u16)lptextw2 + + lastid:u32 + lastid= windows.MB_ICONWARNING + // change last value from 0 to lastid to show warning + dummy:=windows.MessageBoxW(nil,lptext,lptext2,0) + + +} diff --git a/Task/Hello-world-Graphical/Uxntal/hello-world-graphical.uxnatl b/Task/Hello-world-Graphical/Uxntal/hello-world-graphical.uxnatl new file mode 100644 index 0000000000..43d633e179 --- /dev/null +++ b/Task/Hello-world-Graphical/Uxntal/hello-world-graphical.uxnatl @@ -0,0 +1,240 @@ +|00 @System [ + &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 + &debug $1 &state $1 ] + +|20 @Screen [ + &vector $2 &width $2 &height $2 &auto $2 &x $2 &y $2 &addr $2 &pixel $1 + &sprite $1 ] + +|100 + +@on-reset ( -> ) + ( size ) + #00a8 .Screen/width DEO2 + #0020 .Screen/height DEO2 + + ( theme ) + #3ce9 .System/r DEO2 + #0b75 .System/g DEO2 + #2b59 .System/b DEO2 + + #001c .Screen/x DEO2 + #000a .Screen/y DEO2 + + ;my-string draw-text + BRK + +@draw-text ( text* -- ) + [ LIT2 15 -Screen/auto ] DEO + &>while ( -- ) + LDAk #00 SWP DUP2 + ( addr ) #20 SUB #50 SFT2 ;font/glyphs ADD2 .Screen/addr DEO2 + ( move ) ;font/widths ADD2 LDA #00 SWP .Screen/x DEI2 ADD2 + ( draw ) [ LIT2 01 -Screen/sprite ] DEOk DEO + .Screen/x DEO2 + INC2 LDAk ?&>while + POP2 JMP2r + +@my-string "Goodbye 20 "World! 0a00 + +@font + &widths [ + 0800 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0808 0808 0808 0808 0808 0808 0808 0808 + 0808 0808 0808 0808 0808 0808 0808 0808 + 0808 0808 0808 0808 0808 0808 0808 0808 + 0808 0808 0808 0808 0808 0808 0808 0808 + 0808 0808 0808 0808 0808 0808 0808 0808 + 0808 0808 0808 0808 0808 0808 0808 0800 ] + &glyphs [ ( starting from 0x20 ) + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 1818 1818 1818 1800 1818 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0066 6666 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 6c6c 6cfe 6c6c fe6c 6c6c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0010 107c d6d0 d07c 1616 d67c 1010 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 66d6 6c0c 1818 3036 6b66 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 386c 6c38 76dc cccc dc76 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0018 1818 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0c18 3030 3030 3030 180c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 3018 0c0c 0c0c 0c0c 1830 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 006c 38fe 386c 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0018 187e 1818 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 1818 3000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 00fe 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 1818 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0606 0c0c 1818 3030 6060 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6ce def6 e6c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 1838 7818 1818 1818 187e 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c606 0c18 3060 c0fe 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c606 3c06 06c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 060e 1e36 66c6 fe06 0606 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 fec0 c0c0 fc06 0606 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 3c60 c0c0 fcc6 c6c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 fe06 060c 0c18 1830 3030 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6c6 7cc6 c6c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6c6 c67e 0606 0c78 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0018 1800 0000 1818 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0018 1800 0000 1818 3000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0006 0c18 3060 3018 0c06 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00fe 0000 fe00 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0060 3018 0c06 0c18 3060 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6c6 0c18 1800 1818 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 ced6 d6d6 d6ce c07e 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6c6 c6fe c6c6 c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 fcc6 c6c6 fcc6 c6c6 c6fc 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6c0 c0c0 c0c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 f8cc c6c6 c6c6 c6c6 ccf8 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 fec0 c0c0 f8c0 c0c0 c0fe 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 fec0 c0c0 f8c0 c0c0 c0c0 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6c0 c0de c6c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c6c6 c6c6 fec6 c6c6 c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 3c18 1818 1818 1818 183c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 1e0c 0c0c 0c0c 0ccc cc78 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c6c6 ccd8 f0f0 d8cc c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c0c0 c0c0 c0c0 c0c0 c0fe 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 82c6 eefe d6c6 c6c6 c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c6c6 c6e6 f6de cec6 c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6c6 c6c6 c6c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 fcc6 c6c6 c6fc c0c0 c0c0 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c6c6 c6c6 c6c6 de7c 0600 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 fcc6 c6c6 c6fc f0d8 ccc6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7cc6 c0c0 7c06 06c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 ff18 1818 1818 1818 1818 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c6c6 c6c6 c6c6 c6c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c6c6 c6c6 c66c 6c6c 3838 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c6c6 c6c6 c6d6 feee c682 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c6c6 6c6c 3838 6c6c c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c3c3 6666 3c18 1818 1818 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 fe06 060c 1830 60c0 c0fe 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 3c30 3030 3030 3030 303c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 6060 3030 1818 0c0c 0606 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 3c0c 0c0c 0c0c 0c0c 0c3c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0018 3c66 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 00fe 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 3018 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 007c 067e c6c6 c67e 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c0c0 c0fc c6c6 c6c6 c6fc 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 007c c6c0 c0c0 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0606 067e c6c6 c6c6 c67e 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 007c c6c6 fec0 c07c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 1e30 30fc 3030 3030 3030 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 007e c6c6 c6c6 c67e 0606 7c00 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c0c0 c0fc c6c6 c6c6 c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 1818 0038 1818 1818 183c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0606 000e 0606 0606 0606 6666 3c00 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 c0c0 c0c6 ccd8 f0d8 ccc6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 3818 1818 1818 1818 183c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00fc d6d6 d6d6 d6d6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00fc c6c6 c6c6 c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 007c c6c6 c6c6 c67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00fc c6c6 c6c6 c6fc c0c0 c000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 007e c6c6 c6c6 c67e 0606 0600 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00de f0e0 c0c0 c0c0 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 007e c0c0 7c06 06fc 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 3030 30fc 3030 3030 301e 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00c6 c6c6 c6c6 c67e 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00c6 c6c6 6c6c 3838 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00c6 c6d6 d6d6 d67c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00c6 c66c 386c c6c6 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00c6 c6c6 c6c6 c67e 0606 7c00 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 00fe 0c18 3060 c0fe 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 1c30 3030 6030 3030 301c 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 1818 1818 1818 1818 1818 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 7018 1818 0c18 1818 1870 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0073 dbce 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 ] diff --git a/Task/Hello-world-Newline-omission/Ballerina/hello-world-newline-omission.ballerina b/Task/Hello-world-Newline-omission/Ballerina/hello-world-newline-omission.ballerina new file mode 100644 index 0000000000..e53d30ec3d --- /dev/null +++ b/Task/Hello-world-Newline-omission/Ballerina/hello-world-newline-omission.ballerina @@ -0,0 +1,5 @@ +import ballerina/io; + +public function main() { + io:print("Goodbye, World!"); +} diff --git a/Task/Hello-world-Newline-omission/Uxntal/hello-world-newline-omission.uxnatl b/Task/Hello-world-Newline-omission/Uxntal/hello-world-newline-omission.uxnatl index 20a2d61d1e..38f81a985d 100644 --- a/Task/Hello-world-Newline-omission/Uxntal/hello-world-newline-omission.uxnatl +++ b/Task/Hello-world-Newline-omission/Uxntal/hello-world-newline-omission.uxnatl @@ -1,13 +1,17 @@ -|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1 -|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 +|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1 -|0100 - ;message - &loop - LDAk .Console/write DEO - INC2 LDAk ?&loop - POP2 - #80 .System/state DEO -BRK +|100 -@message "Goodbye, 20 "World! 00 +@on-reset ( -> ) + ;my-string print-text + BRK + +@print-text ( str* -- ) + &while + LDAk .Console/write DEO + INC2 LDAk ?&while + POP2 + JMP2r + +@my-string + "Hello 20 "World! 00 diff --git a/Task/Hello-world-Standard-error/AArch64-Assembly/hello-world-standard-error.aarch64 b/Task/Hello-world-Standard-error/AArch64-Assembly/hello-world-standard-error-1.aarch64 similarity index 100% rename from Task/Hello-world-Standard-error/AArch64-Assembly/hello-world-standard-error.aarch64 rename to Task/Hello-world-Standard-error/AArch64-Assembly/hello-world-standard-error-1.aarch64 diff --git a/Task/Hello-world-Standard-error/AArch64-Assembly/hello-world-standard-error-2.aarch64 b/Task/Hello-world-Standard-error/AArch64-Assembly/hello-world-standard-error-2.aarch64 new file mode 100644 index 0000000000..e693ea2dcc --- /dev/null +++ b/Task/Hello-world-Standard-error/AArch64-Assembly/hello-world-standard-error-2.aarch64 @@ -0,0 +1,16 @@ +.global _start + +.text +_start: + mov x8, #64 //64 is write + mov x0, #2 //2 is stderr + adr x1, msg //mov address of msg into x1 + mov x2, #(msgend - msg) //msgend minus msg is the length of message + svc #0 //system call + mov x8, #93 //93 is exit + mov x0, #0 //0 is the exit code. + svc #0 //system call + +msg: + .ascii "Goodbye, World!\n" +msgend: diff --git a/Task/Hello-world-Standard-error/ARM-Assembly/hello-world-standard-error.arm b/Task/Hello-world-Standard-error/ARM-Assembly/hello-world-standard-error.arm index 0f817f7232..1eba4d34a7 100644 --- a/Task/Hello-world-Standard-error/ARM-Assembly/hello-world-standard-error.arm +++ b/Task/Hello-world-Standard-error/ARM-Assembly/hello-world-standard-error.arm @@ -1,7 +1,7 @@ /* ARM assembly Raspberry PI */ /* program hellowordLP.s */ .data -szMessage: .asciz "Goodbye world. \n " @ error message +szMessage: .ascii "Goodbye world. \n " @ error message .equ LGMESSAGE, . - szMessage @ compute length of message .text diff --git a/Task/Hello-world-Standard-error/Ballerina/hello-world-standard-error.ballerina b/Task/Hello-world-Standard-error/Ballerina/hello-world-standard-error.ballerina new file mode 100644 index 0000000000..59c24efda3 --- /dev/null +++ b/Task/Hello-world-Standard-error/Ballerina/hello-world-standard-error.ballerina @@ -0,0 +1,5 @@ +import ballerina/io; + +public function main() { + io:fprintln(io:stderr, "Goodbye, World!"); +} diff --git a/Task/Hello-world-Standard-error/Crystal/hello-world-standard-error.cr b/Task/Hello-world-Standard-error/Crystal/hello-world-standard-error.cr new file mode 100644 index 0000000000..59324c7847 --- /dev/null +++ b/Task/Hello-world-Standard-error/Crystal/hello-world-standard-error.cr @@ -0,0 +1 @@ +STDERR.puts "Goodbye, World!" diff --git a/Task/Hello-world-Standard-error/Objeck/hello-world-standard-error.objeck b/Task/Hello-world-Standard-error/Objeck/hello-world-standard-error.objeck new file mode 100644 index 0000000000..4646f8c9cd --- /dev/null +++ b/Task/Hello-world-Standard-error/Objeck/hello-world-standard-error.objeck @@ -0,0 +1,5 @@ +class Goodbye { + function : Main(args : String[]) ~ Nil { + "Goodbye, World!"->ErrorLine(); + } +} diff --git a/Task/Hello-world-Standard-error/Uxntal/hello-world-standard-error.uxnatl b/Task/Hello-world-Standard-error/Uxntal/hello-world-standard-error.uxnatl new file mode 100644 index 0000000000..0e2f4bc50e --- /dev/null +++ b/Task/Hello-world-Standard-error/Uxntal/hello-world-standard-error.uxnatl @@ -0,0 +1,17 @@ +|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1 + +|100 + +@on-reset ( -> ) + ;my-string print-error + BRK + +@print-error ( str* -- ) + &while + LDAk .Console/error DEO + INC2 LDAk ?&while + POP2 + JMP2r + +@my-string + "Goodbye 20 "World! 0a00 diff --git a/Task/Hello-world-Text/AArch64-Assembly/hello-world-text.aarch64 b/Task/Hello-world-Text/AArch64-Assembly/hello-world-text-1.aarch64 similarity index 100% rename from Task/Hello-world-Text/AArch64-Assembly/hello-world-text.aarch64 rename to Task/Hello-world-Text/AArch64-Assembly/hello-world-text-1.aarch64 diff --git a/Task/Hello-world-Text/AArch64-Assembly/hello-world-text-2.aarch64 b/Task/Hello-world-Text/AArch64-Assembly/hello-world-text-2.aarch64 new file mode 100644 index 0000000000..390ac3628e --- /dev/null +++ b/Task/Hello-world-Text/AArch64-Assembly/hello-world-text-2.aarch64 @@ -0,0 +1,16 @@ +.global _start + +.text +_start: + mov x8, #64 //64 is write + mov x0, #1 //1 is stdout + adr x1, msg //mov address of msg into x1 + mov x2, #(msgend - msg) //msgend minus msg is the length of message + svc #0 //system call + mov x8, #93 //93 is exit + mov x0, xzr //0 is the exit code. xzr is the zero register + svc #0 //system call + +msg: + .ascii "Hello world!\n" +msgend: diff --git a/Task/Hello-world-Text/AArch64-Assembly/hello-world-text-3.aarch64 b/Task/Hello-world-Text/AArch64-Assembly/hello-world-text-3.aarch64 new file mode 100644 index 0000000000..1cea6a1d2c --- /dev/null +++ b/Task/Hello-world-Text/AArch64-Assembly/hello-world-text-3.aarch64 @@ -0,0 +1,21 @@ +.global _start +.text +_start: + adr x0, msg // load x0 with address of message + bl writez // call the function that writes null-terminated string to stdout + mov x8, #93 // 93 is syscall exit + mov x0, xzr // exit code = 0. Exit normal. + svc #0 // syscall + // If using as a function in C declare it as +writez: // extern long writez(char *str); + mov x1, x0 // address of str needs to be in x1 for syscall + sub x0, x0, #1 // decrement x0, because the next statement increments it. + 0: ldrb w2, [x0, #1]! // increment x0, load byte value at x0 in w2 + cbnz w2, 0b // if w2 is not zero jump back to 0: label + sub x2, x0, x1 // subtract x1 from x0, load into x2. length of str + mov x0, #1 // mov into x0 1. stdout + mov x8, #64 // mov into x8 64. write + svc #0 // syscall + ret // return from function. + // return value (x0) is number of characters written. +msg: .asciz "Hello world!\n" // .asciz means null-terminated string. Assembler adds the 0 diff --git a/Task/Hello-world-Text/OPL/hello-world-text.opl b/Task/Hello-world-Text/OPL/hello-world-text.opl new file mode 100644 index 0000000000..9ecaf7f843 --- /dev/null +++ b/Task/Hello-world-Text/OPL/hello-world-text.opl @@ -0,0 +1,4 @@ +PROC main: + PRINT "Hello, world!" + GET +ENDP diff --git a/Task/Hello-world-Text/Uxntal/hello-world-text.uxnatl b/Task/Hello-world-Text/Uxntal/hello-world-text.uxnatl deleted file mode 100644 index 7cef15e4e0..0000000000 --- a/Task/Hello-world-Text/Uxntal/hello-world-text.uxnatl +++ /dev/null @@ -1,22 +0,0 @@ -( hello-world.tal ) -|00 @System [ &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1 ] -|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ] - -( program ) -|0100 @on-reset ( -> ) - ;hello print-str - HALT -BRK - -@print-str ( str* -- ) - &while - LDAk .Console/write DEO - INC2 LDAk ?&while - POP2 -JMP2r - -@HALT ( -- ) - #01 .System/halt DEO -JMP2r - -@hello "Hello 20 "world! 0a 00 diff --git a/Task/Heronian-triangles/EasyLang/heronian-triangles.easy b/Task/Heronian-triangles/EasyLang/heronian-triangles.easy index 6cfcf65e3d..2a218f6902 100644 --- a/Task/Heronian-triangles/EasyLang/heronian-triangles.easy +++ b/Task/Heronian-triangles/EasyLang/heronian-triangles.easy @@ -1,30 +1,22 @@ func gcd x y . - if y = 0 - return x - . + if y = 0 : return x return gcd y (x mod y) . global ta[] tb[] tc[] . -proc mktbl . . - for c = 1 to 200 - for b = 1 to c - for a = 1 to b - s = (a + b + c) / 2 - ar = sqrt (s * (s - a) * (s - b) * (s - c)) - if ar > 0 and ar = floor ar - if gcd gcd b c a = 1 - ta[] &= a - tb[] &= b - tc[] &= c - . - . - . +proc mktbl . + for c = 1 to 200 : for b = 1 to c : for a = 1 to b + s = (a + b + c) / 2 + ar = sqrt (s * (s - a) * (s - b) * (s - c)) + if ar > 0 and ar = floor ar and gcd gcd b c a = 1 + ta[] &= a + tb[] &= b + tc[] &= c . . . mktbl # -proc get i . a b c per ar . +proc get i &a &b &c &per &ar . a = ta[i] b = tb[i] c = tc[i] @@ -36,7 +28,7 @@ func wgt i . get i a b c per ar return ar * 1000000 + per * 1000 + a . -proc sort . . +proc sort . for i = 1 to len ta[] - 1 for j = i + 1 to len ta[] if wgt j < wgt i diff --git a/Task/Hex-words/Crystal/hex-words.cr b/Task/Hex-words/Crystal/hex-words.cr new file mode 100644 index 0000000000..c1aa6e6a4a --- /dev/null +++ b/Task/Hex-words/Crystal/hex-words.cr @@ -0,0 +1,10 @@ +def report (a) + puts + a.each {|hexword| puts "%6s %8d %d" % hexword} + puts "Total count of these words: #{a.size}" +end + +hexwords = File.read_lines("unixdict.txt").reject{|w| w.size < 4 || w.matches?(/[^abcdef]/) } +res = hexwords.map {|hw| {hw, hw.to_i(16), 1 + (hw.to_i(16) - 1) % 9} }.sort_by(&.last) +report res +report res.reject {|hw| hw[0].chars.uniq.size < 4}.sort_by {|w| -w[1] } diff --git a/Task/Hex-words/EasyLang/hex-words.easy b/Task/Hex-words/EasyLang/hex-words.easy index 78f5e8d383..909936e5fd 100644 --- a/Task/Hex-words/EasyLang/hex-words.easy +++ b/Task/Hex-words/EasyLang/hex-words.easy @@ -2,9 +2,7 @@ func ishex w$ . c$ = "" for c$ in strchars w$ h = strcode c$ - if h < 97 or h > 102 - break 1 - . + if h < 97 or h > 102 : break 1 . return if c$ = "" . @@ -17,9 +15,7 @@ func digsum num . return s . func digroot x . - while x > 9 - x = digsum x - . + while x > 9 : x = digsum x return x . func dec w$ . @@ -34,7 +30,7 @@ func comp a$ b$ . . return if digroot dec a$ < digroot dec b$ . -proc sort . . +proc sort . for i = len w$[] - 1 downto 1 for j = 1 to i if comp w$[j] w$[j + 1] = 1 @@ -43,7 +39,7 @@ proc sort . . . . . -proc init . . +proc init . repeat s$ = input until s$ = "" @@ -54,7 +50,7 @@ proc init . . . init sort -proc show . . +proc show . for w$ in w$[] w = dec w$ print digroot w & " " & w$ & " " & w @@ -69,15 +65,11 @@ func dist w$ . for c$ in strchars w$ d[strcode c$ - 96] = 1 . - for e in d[] - s += e - . + for e in d[] : s += e return s . for w$ in w$[] - if dist w$ > 3 - w2$[] &= w$ - . + if dist w$ > 3 : w2$[] &= w$ . swap w$[] w2$[] part2 = 1 diff --git a/Task/Hex-words/R/hex-words.r b/Task/Hex-words/R/hex-words.r new file mode 100644 index 0000000000..32cd03bc0f --- /dev/null +++ b/Task/Hex-words/R/hex-words.r @@ -0,0 +1,43 @@ +library(stringr) + +unixdict <- read.table("unixdict.txt", col.names="words") +hexwords <- subset(unixdict, str_detect(words,"^[a-f]{4,}$")) +hexwords$decimal <- strtoi(hexwords$words, 16L) + +#Method 1 for calculating digital root: casting to a string (slower, but accurate) +dig_root <- function(n){ + while(n>9){ + vec_str <- str_split_1(as.character(n),"") + dig_sum <- sum(as.numeric(vec_str)) + n <- dig_sum + } + return(n) +} + +#Method 2: using modulus operators recursively (can be inaccurate for very large n) +dig_root <- function(n){ + if(n>9){ + return(dig_root(n%%10+dig_root(n%/%10))) + } + return(n) +} + +hexwords$root <- sapply(hexwords$decimal, dig_root) + +hexwords <- sort_by(hexwords, ~root) +rownames(hexwords) <- NULL +print(hexwords) + +#The second part is impossible to do with a single regex AFAIK, so check strings by counting instances of each letter +chars <- letters[1:6] +counts_logical <- function(s){ + counts <- sapply(chars, function(char) str_count(s, char)) + sum(counts>0) +} + +hexwords$has4distinct <- sapply(hexwords$words, counts_logical)>3 + +hexwords_distinct <- subset(hexwords, has4distinct) +hexwords_distinct <- sort_by(hexwords_distinct, ~rev(decimal)) +rownames(hexwords_distinct) <- NULL +print(hexwords_distinct[,1:3]) diff --git a/Task/Hex-words/Rust/hex-words.rs b/Task/Hex-words/Rust/hex-words.rs new file mode 100644 index 0000000000..a398c0b0f0 --- /dev/null +++ b/Task/Hex-words/Rust/hex-words.rs @@ -0,0 +1,83 @@ +use std::collections::HashSet; +use std::fs::File; +use std::io::{BufRead, BufReader}; + +struct Item { + word: String, + number: i32, + digital_root: i32, +} + +fn display(items: &Vec) { + println!(" Word Decimal value Digital root"); + println!("----------------------------------------"); + for item in items { + println!("{:>7} {:>15} {:>12}", item.word, item.number, item.digital_root); + } + println!("\nTotal count: {}\n", items.len()); +} + +fn digital_root(mut number: i32) -> i32 { + let mut result = 0; + while number > 0 { + result += number % 10; + number /= 10; + } + if result <= 9 { + result + } else { + digital_root(result) + } +} + +fn contains_only(word: &str, acceptable: &HashSet) -> bool { + word.chars().all(|ch| acceptable.contains(&ch)) +} + +fn main() -> std::io::Result<()> { + let hex_digits: HashSet = ['a', 'b', 'c', 'd', 'e', 'f'].iter().cloned().collect(); + let mut items = Vec::new(); + + let file = File::open("unixdict.txt")?; + let reader = BufReader::new(file); + + for line in reader.lines() { + if let Ok(word) = line { + if word.len() >= 4 && contains_only(&word, &hex_digits) { + let value = i32::from_str_radix(&word, 16).unwrap(); + let root = digital_root(value); + items.push(Item { + word, + number: value, + digital_root: root, + }); + } + } + } + + items.sort_by(|a, b| { + if a.digital_root == b.digital_root { + a.word.cmp(&b.word) + } else { + a.digital_root.cmp(&b.digital_root) + } + }); + display(&items); + + let mut filtered_items = Vec::new(); + for item in &items { + let unique_chars: HashSet = item.word.chars().collect(); + if unique_chars.len() >= 4 { + filtered_items.push(Item { + word: item.word.clone(), + number: item.number, + digital_root: item.digital_root, + }); + } + } + + filtered_items.sort_by(|a, b| b.number.cmp(&a.number)); + display(&filtered_items); + + Ok(()) +} diff --git a/Task/Higher-order-functions/Pascal/higher-order-functions-3.pas b/Task/Higher-order-functions/Pascal/higher-order-functions-3.pas index 1c3acc304e..6a62902bc3 100644 --- a/Task/Higher-order-functions/Pascal/higher-order-functions-3.pas +++ b/Task/Higher-order-functions/Pascal/higher-order-functions-3.pas @@ -1,720 +1,380 @@ -UNIT MRF; -{$mode Delphi} {$H+} {$J-} {$R+} (*) https://www.freepascal.org/docs-html/prog/progch1.html (*) - +====================================================================== +(*) + Save to ShortNotation.inc + Use {$INCLUDE ShortNotation.inc} in order to load this file + Load before any other .inc file (*) - Free Pascal Compiler version 3.2.0 [2020/06/14] for x86_64 - The free and readable alternative at C/C++ speeds - compiles natively to almost any platform, including raspberry PI * - Can run independently from DELPHI / Lazarus +{$MACRO ON} +(*) Shorthand mainly for lambdas (anonymous functions) (*) - For debian Linux: apt -y install fpc - It contains a text IDE called fp + {$DEFINE Fn := function } + {$DEFINE Proc := procedure } + {$DEFINE spec := specialize } + {$DEFINE ref := reference } + {$DEFINE _ := begin } + {$DEFINE __ := end } - https://www.freepascal.org/advantage.var +(*) defs for WriteLn (*) + {$DEFINE nl := #13#10} + {$DEFINE tab := #9} +====================================================================== +(*) + Save to CompilerSwitches.inc + Use {$INCLUDE CompilerSwitches.inc} in order to load this file +(*) + +{$IFDEF FPC} + {$MODE OBJFPC} + {$M+} + {$LONGSTRINGS ON} + {$ASMMODE INTEL} + {$Q+} + {$RANGECHECKS ON} + {$S+} + {$TYPEDADDRESS ON} + {$MODESWITCH EXCEPTIONS} + {$MODESWITCH ADVANCEDRECORDS} + {$MODESWITCH TYPEHELPERS} + {$MODESWITCH FUNCTIONREFERENCES} + {$MODESWITCH ANONYMOUSFUNCTIONS} +{$ELSE} + {$APPTYPE CONSOLE} +{$ENDIF} + + +{$WARNINGS OFF W1033} +{$WARN 6058 OFF} +====================================================================== +unit MRF3 ; (*) -INTERFACE + (c) 2025 jpd - Free to use, experimental - USES - Math, + Free Pascal Compiler version 3.3.1 [2025/03/18] for x86_64 + + Map Reduce Filter version with chaining, generics and lambdas + + https://www.freepascal.org/advantage.var + + +(*) + +{$INCLUDE ShortNotation.inc} + +{$INCLUDE CompilerSwitches.inc} + +interface + +uses + + Generics.Collections, + Generics.Defaults, + StrUtils, SysUtils, - variants; - {$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined} // Use for variants + Variants + ; + +type + + V = Variant ; + L = specialize TList ; + + TMapperFunc = ref to Fn ( item: V ; index: Integer ): V ; + TPredicateFunc = ref to Fn ( item: V ; index: Integer ): Boolean ; + TFolderFunc = ref to Fn ( Acc: V ; item: V ; index: Integer ): V ; + TCompareFunc = ref to Fn ( const A, B: V ): Integer ; + + TCollPipe = record + private + FData: L ; + public + constructor Create( Data: L ) ; + Fn Count: Integer; + Fn GroupBy(KeyFunc: TMapperFunc): spec TDictionary; + Fn ForAll(Predicate: TPredicateFunc): Boolean; + Fn Map ( Func: TMapperFunc ) : TCollPipe ; + Fn Filter ( Func: TPredicateFunc ) : TCollPipe ; + Fn Reduce ( Func: TFolderFunc ; initial: V ): V ; + Fn Sort ( Compare: TCompareFunc ): TCollPipe ; + Fn Debug ( const Msg: String ) : TCollPipe ; + Fn ToArray: L ; + end ; + + Fn List( const Elements: array of V ): L ; + Fn Pipe( Data: L ): TCollPipe ; inline ; + proc DebugList(const List: L; const Msg: String); + Fn SortAndDebug(const List: L; Compare: TCompareFunc; const Msg: String): L; + + (*) Core FP Functions (*) + + Fn Map ( const Arr: L ; Func: TMapperFunc ): L ; + Fn Filter ( const Arr: L ; Func: TPredicateFunc ): L ; + Fn Reduce ( const Arr: L ; Func: TFolderFunc ; initial: V ): V ; + + + +implementation + + proc DebugList(const List: L; const Msg: String); + begin + Pipe(List).Debug(Msg); // Convert TList to TCollPipe once + end; + + Fn SortAndDebug(const List: L; Compare: TCompareFunc; const Msg: String): L; + _ + Result := Pipe(List) + .Sort(Compare) + .Debug(Msg) + .ToArray; + __; + + Fn TCollPipe.Count: Integer; + _ + Result := FData.Count; + __; + + Fn TCollPipe.GroupBy(KeyFunc: TMapperFunc): spec TDictionary; + var + i: Integer; + key: V; + group: L; + _ + Result := spec TDictionary.Create; + for i := 0 to FData.Count - 1 do + _ + key := KeyFunc(FData[i], i); + if not Result.TryGetValue(key, group) then + _ + group := L.Create; + Result.Add(key, group); + __; + group.Add(FData[i]); + __; + __; - TYPE + Fn TCollPipe.ForAll(Predicate: TPredicateFunc): Boolean; + var + i: Integer; + _ + Result := True; + for i := 0 to FData.Count - 1 do + _ + if not Predicate(FData[i], i) then + _ + Result := False; + Exit; + __; + __; + __; - Varyray = array of variant ; - FunA = FUNCTION ( x : variant ) : variant ; - FunB = PROCEDURE ( x : variant ) ; - FunC = FUNCTION ( x,y : variant ) : variant ; - FunD = FUNCTION ( x,y : longint ) : longint ; - FunE = FUNCTION ( x,y : variant ) : variant ; + Fn List( const Elements: array of V ): L ; + var elem: V ; + _ + Result := L.Create ; + for elem in Elements do + Result.Add( elem ) ; + __ ; - PROCEDURE Show ( x : variant ) ; - FUNCTION Reverse ( x : Varyray ) : Varyray ; - FUNCTION Head ( x : Varyray ) : variant ; - FUNCTION Last ( x : Varyray ) : variant ; - FUNCTION Tail ( x : Varyray ) : Varyray ; - FUNCTION Take ( y : variant ; x : Varyray ) : Varyray ; - FUNCTION Map ( f : FunA ; x: Varyray ) : Varyray ; overload ; - PROCEDURE Map ( f : FunB ; x: Varyray ) ; overload ; - FUNCTION Map ( f : FunC ; x, y: Varyray ) : Varyray ; overload ; - FUNCTION Map ( f : FunD ; x, y: Varyray ) : Varyray ; overload ; - FUNCTION Filter ( f : FunA ; x: Varyray ) : Varyray ; overload ; - FUNCTION Filter ( f : FunE ; y: variant; x: Varyray ) : Varyray ; overload ; - FUNCTION FoldL ( f : FunC ; x: Varyray ) : variant ; overload ; - FUNCTION FoldL ( f : FunD ; x: Varyray ) : variant ; overload ; - FUNCTION FoldL ( f : FunE ; y: variant; x: Varyray ) : variant ; overload ; - FUNCTION Reduce ( f : FunC ; x: Varyray ) : variant ; overload ; - FUNCTION Reduce ( f : FunD ; x: Varyray ) : variant ; overload ; - FUNCTION Reduce ( f : FunE ; y: variant; x: Varyray ) : variant ; overload ; - FUNCTION FoldR ( f : FunC ; x: Varyray ) : variant ; overload ; - FUNCTION FoldR ( f : FunD ; x: Varyray ) : variant ; overload ; -(*) FOR TESTING (*) - FUNCTION RandFillInt ( x: variant ) : variant ; - FUNCTION RandFillReal ( x: variant ) : variant ; + constructor TCollPipe.Create( Data: L ) ; + _ + FData := L.Create ; + FData.AddRange( Data ) ; + __ ; - FUNCTION AND_xy ( x, y: variant ) : variant ; - FUNCTION OR_xy ( x, y: variant ) : variant ; - FUNCTION AVG ( x: Varyray ) : variant ; - FUNCTION All ( f: FunA ; x: Varyray ) : variant ; - FUNCTION Any ( f: FunA ; x: Varyray ) : variant ; - FUNCTION Add ( x, y: variant ) : variant ; - FUNCTION Mult ( x, y: variant ) : variant ; - FUNCTION contain ( x, y: variant ) : variant ; - FUNCTION delete ( x, y: variant ) : variant ; - FUNCTION Add1 ( x: variant ) : variant ; - FUNCTION sine ( x: variant ) : variant ; - FUNCTION cosine ( x: variant ) : variant ; - FUNCTION cotangens ( x: variant ) : variant ; - FUNCTION Is_Even ( x: variant ) : variant ; - FUNCTION Is_Odd ( x: variant ) : variant ; + Fn TCollPipe.Map( Func: TMapperFunc ): TCollPipe ; + _ + Result := TCollPipe.Create( MRF3.Map( FData, Func ) ) ; + __ ; -IMPLEMENTATION + Fn TCollPipe.Filter( Func: TPredicateFunc ): TCollPipe ; + _ + Result := TCollPipe.Create( MRF3.Filter( FData, Func ) ) ; + __ ; - PROCEDURE Show ( x: variant ) ; - BEGIN write( x, ' ' ) ; END ; + Fn TCollPipe.Reduce( Func: TFolderFunc ; initial: V ): V ; + _ + Result := MRF3.Reduce( FData, Func, initial ) ; + __ ; - FUNCTION Reverse ( x : Varyray ) : Varyray ; - VAR - __ : varyray ; - k : integer ; + Fn TCollPipe.Sort( Compare: TCompareFunc ): TCollPipe; + var + NewList: L; + _ + NewList := L.Create; + NewList.AddRange(FData); + NewList.Sort(spec TComparer.Construct(Compare)); + Result := TCollPipe.Create(NewList); + __ ; - BEGIN - IF length ( x ) < Low ( x ) + 2 THEN Exit ; - Setlength ( __, length ( x ) ); + Fn TCollPipe.Debug( const Msg: String ): TCollPipe ; - FOR k := Low ( x ) to High ( x ) DO - __ [ k ] := x [ High ( x ) - k ] ; + var + i: Integer ; + s: String ; + _ + s := Msg + ' [ ' ; - result := __ ; + if FData.Count > 1 then + for i := 0 to FData.Count - 2 do + s := s + VarToStr( FData[ i ] ) + ', ' + else + i := -1 ; - Setlength ( __, 0 ); + Writeln( s + VarToStr( FData[ i + 1 ] ), ' ]' ) ; + Result := Self ; + __ ; - END; + Fn TCollPipe.ToArray: L ; + _ + Result := L.Create ; + Result.AddRange( FData ) ; + __ ; - FUNCTION Head ( x : Varyray ) : variant ; - BEGIN result := x [ Low ( x ) ] ; END; + Fn Pipe( Data: L ): TCollPipe ; + _ + Result := TCollPipe.Create( Data ) ; + __ ; - FUNCTION Last ( x : Varyray ) : variant ; - BEGIN result := x [ High ( x ) ] ; END; + Fn Map( const Arr: L ; Func: TMapperFunc ): L ; - FUNCTION Tail ( x : Varyray ) : Varyray ; + var i: Integer ; + _ + Result := L.Create ; + for i := 0 to Arr.Count - 1 do + Result.Add( Func( Arr[ i ], i ) ) ; + __ ; - VAR - __ : varyray ; - k : integer ; - BEGIN - Setlength ( __, High ( x ) ); + Fn Filter( const Arr: L ; Func: TPredicateFunc ): L ; - FOR k := Low ( x ) + 1 to High ( x ) DO - __ [ k - 1 ] := x [ k ] ; + var i: Integer ; + _ + Result := L.Create ; + for i := 0 to Arr.Count - 1 do + if Func( Arr[ i ], i ) then + Result.Add( Arr[ i ] ) ; + __ ; - result := __ ; - Setlength ( __, 0 ); - END; + Fn Reduce( const Arr: L ; Func: TFolderFunc ; initial: V ): V ; + var i: Integer ; + _ + Result := initial ; + for i := 0 to Arr.Count - 1 do + Result := Func( Result, Arr[ i ], i ) ; + __ ; +end. ( * ) unit MRF3 ( * ) - FUNCTION Take ( y : variant ; x : Varyray ) : Varyray ; +====================================================================== +program testMRF3; - VAR - __ : varyray ; - k : integer ; +{$include ShortNotation.inc} - BEGIN +{$INCLUDE CompilerSwitches.inc} +uses - Setlength ( __, y ); + Math, + MRF3, + StrUtils, + SysUtils, + Variants + ; - FOR k := Low ( x ) to y - 1 DO - __ [ k ] := x [ k ] ; - result := __ ; + Fn IsNumber( item: V ): Boolean ; - Setlength ( __, 0 ); + _ + Result := VarIsNumeric( item ) and not VarIsBool( item ) ; + __; - END; + Fn CompareVariants( const A, B: V ): Integer ; + _ - FUNCTION Map ( f: FunA ; x: Varyray ) : Varyray ; overload ; + if VarIsNumeric( A ) and VarIsNumeric( B ) then + Exit( CompareValue( Double( A ), Double( B ) ) ) ; - VAR + if VarIsStr( A ) and VarIsStr( B ) then + Exit( CompareText( A, B ) ) ; - Ar : array of variant ; - k : integer ; + (*) Fallback: priority ( booleans < numbers < strings < ) (*) - BEGIN + Result := ( Ord( VarIsStr( A ) ) - Ord( VarIsStr( B ) ) ); + __; - SetLength ( Ar, length ( x ) ) ; - result := Ar ; +(*) MAIN Line (*) - FOR k := Low ( Ar ) TO High ( Ar ) DO - Ar [ k ] := f ( x [ k ] ) ; + var + Data : L ; + Total: Double ; - result := Ar ; + _ + try + Writeln( '=== MRF3 Unit Test ===' ) ; - Setlength ( Ar, 0 ); + Data := List( [ 15, 2.5, 'Apple', True, 7, 'banana', False ] ) ; - END; + Pipe( Data ) + .Debug( 'Original:' ) + .Sort( @CompareVariants ) + .Debug( 'Sorted:' ) ; + Total := Pipe( Data ) + .Filter ( Fn ( item: V; index: Integer ) : Boolean + _ Result := IsNumber( item ) ; + __ + ) - PROCEDURE Map ( f: FunB ; x: Varyray ) ; overload ; + .Map ( Fn ( item: V; index: Integer ) : V + _ Result := Double( item ) * 2 ; + __ + ) - VAR + .Reduce ( Fn ( Acc: V; item: V; index: Integer ): V + _ Result := Double( Acc ) + Double( item ) ; + __ + , 0.0 + ) + ; - k : integer ; + Writeln( 'Numeric sum x2: ', Total:0:2 ) ; - BEGIN - FOR k := Low ( x ) TO High ( x ) DO f ( x [ k ] ) ; - END; + except + on E: Exception do + Writeln( 'Error: ', E.Message ) ; + end; + Readln; - - FUNCTION Map ( f: FunC ; x, y: Varyray ) : Varyray ; overload ; - - VAR - - Ar : array of variant ; - k : integer ; - - BEGIN - - SetLength ( Ar, min ( length ( x ) , length ( y ) ) ) ; - - FOR k := Low ( Ar ) TO High ( Ar ) DO - Ar [ k ] := f ( x [ k ] , y [ k ] ) ; - - result := Ar ; - - Setlength ( Ar, 0 ); - - END; - - - - FUNCTION Map ( f: FunD ; x, y: Varyray ) : Varyray ; overload ; - - VAR - - Ar : array of variant ; - k : integer ; - - BEGIN - - SetLength ( Ar, min ( length ( x ) , length ( y ) ) ) ; - - FOR k := Low ( Ar ) TO High ( Ar ) DO - Ar [ k ] := f ( x [ k ] , y [ k ] ) ; - - result := Ar ; - - Setlength ( Ar, 0 ); - - END; - - - - FUNCTION Map ( f: FunE ; x: variant; y: Varyray ) : Varyray ; overload ; - - VAR - - Ar : array of variant ; - k : integer ; - - BEGIN - - SetLength ( Ar, min ( length ( x ) , length ( y ) ) ) ; - - FOR k := Low ( Ar ) TO High ( Ar ) DO - Ar [ k ] := f ( x , y [ k ] ) ; - - result := Ar ; - - Setlength ( Ar, 0 ); - - END; - - - - FUNCTION Filter ( f: FunA ; x: Varyray ) : Varyray ; overload ; - - VAR - - Ar : array of variant ; - __ : variant ; - k : integer ; - len : integer ; - - BEGIN - - SetLength ( Ar, 0 ) ; - result := Ar ; - - FOR k := Low ( x ) TO High ( x ) DO - BEGIN - - __ := f ( x [ k ] ) ; - - IF __ <> False THEN - - BEGIN - - len := Length ( Ar ) ; - SetLength ( Ar, len + 1 ) ; - Ar [ len ] := __ ; - - END ; - - END ; - - result := Ar ; - - Setlength ( Ar, 0 ); - END; - - - - FUNCTION Filter ( f: FunE ; y: variant; x: Varyray ) : Varyray ; overload ; - - VAR - - Ar : array of variant ; - __ : variant ; - k : integer ; - len : integer ; - - BEGIN - - SetLength ( Ar, 0 ) ; - result := Ar ; - - FOR k := Low ( x ) TO High ( x ) DO - BEGIN - - __ := f ( y, x [ k ] ) ; - - IF __ <> False THEN - - BEGIN - - len := Length ( Ar ) ; - SetLength ( Ar, len + 1 ) ; - Ar [ len ] := __ ; - - END ; - - END ; - - result := Ar ; - - Setlength ( Ar, 0 ); - END; - - - - FUNCTION FoldL ( f: FunC ; x: Varyray ) : variant ; overload ; - - VAR - - k : integer ; - - BEGIN - - result := x [ Low ( x ) ] ; - - FOR k := Low ( x ) + 1 TO High ( x ) DO - result := f ( result , x [ k ] ) ; - - END ; - - - - FUNCTION FoldL ( f: FunD ; x: Varyray ) : variant ; overload ; - - VAR - - k : integer ; - - BEGIN - - result := x [ Low ( x ) ] ; - - FOR k := Low ( x ) + 1 TO High ( x ) DO - result := f ( result , x [ k ] ) ; - - END ; - - - - FUNCTION FoldL ( f: FunE ; y: variant; x: Varyray ) : variant ; overload ; - - VAR - - k : integer ; - - BEGIN - - - FOR k := Low ( x ) TO High ( x ) DO - result := f ( y , x [ k ] ) ; - - END ; - - - - FUNCTION Reduce ( f: FunC ; x: Varyray ) : variant ; overload ; - BEGIN result := FoldL ( f , x ) ; END ; - - - - FUNCTION Reduce ( f: FunD ; x: Varyray ) : variant ; overload ; - BEGIN result := FoldL ( f , x ) ; END ; - - - - FUNCTION Reduce ( f: FunE ; y: variant; x: Varyray ) : variant ; overload ; - BEGIN result := FoldL ( f , y, x ) ; END ; - - - - FUNCTION FoldR ( f: FunC ; x: Varyray ) : variant ; overload ; - - VAR - - k : integer ; - - BEGIN - - result := x [ High ( x ) ] ; - - FOR k := High ( x ) - 1 DOWNTO Low ( x ) DO - result := f ( result, x [ k ] ) ; - - END ; - - - - FUNCTION FoldR ( f: FunD ; x: Varyray ) : variant ; overload ; - - VAR - - k : integer ; - - BEGIN - - - result := x [ High ( x ) ]; - - FOR k := High ( x ) - 1 DOWNTO Low ( x ) DO - result := f ( result, x [ k ] ) ; - - END ; - - - - (*) TEST Functions (*) - -(*) - - Special thanks to PascalDragon , winni & BobDog ( FreePascal.org ), - who explained the specifics of the compiler. - -(*) - - - FUNCTION Add ( x, y: variant ) : variant ; - BEGIN result := x + y ; END ; - - - - FUNCTION Add1 ( x: variant ) : variant ; - BEGIN result := x + 1 ; END ; - - - - FUNCTION AND_xy ( x, y: variant ) : variant ; - BEGIN result := ( x and y ) = True ; END ; - - - - FUNCTION AVG ( x: Varyray ) : variant ; - - VAR - - k : integer ; - - BEGIN - - result := 0.0 ; - - FOR k := Low ( x ) TO High ( x ) DO - result := result + ( x [ k ] - result ) / ( k + 1 ); - - END ; - - - - FUNCTION Cosine ( x: variant ) : variant ; - BEGIN result := cos ( x ); END ; - - - - FUNCTION Cotangens ( x: variant ) : variant ; - - BEGIN - - IF ( x = 0 ) Then Exit ( 'Inf'); - - result := cot ( x ); - - END ; - - - - FUNCTION Is_Even ( x: variant ) : variant ; - - BEGIN - - IF ( ( x mod 2 ) = 0 ) THEN - result := x - ELSE - result := False - - END; - - - - FUNCTION Mult( x, y: variant ) : variant ; - BEGIN result := x * y ; END ; - - - - FUNCTION Contain ( x, y: variant ) : variant ; - BEGIN result := x = y ; END ; - - - - FUNCTION Delete ( x, y: variant ) : variant ; - - BEGIN - - IF ( x = y ) THEN Exit ( False ) ; - - result := y; - - END ; - - - FUNCTION Is_Odd ( x: variant ) : variant ; - - BEGIN - - IF ( ( x mod 2 ) <> 0 ) THEN - result := x - ELSE - result := False - - END; - - - - FUNCTION OR_xy ( x, y: variant ) : variant ; - BEGIN result := ( x or y ) = True; END ; - - - - FUNCTION RandFillInt ( x: variant ) : variant ; - BEGIN result := Random ( 100 ) ; END ; - - - - FUNCTION RandFillReal ( x: variant ) : variant ; - - VAR - tmp : real = 100.0 ; - - BEGIN result := ( Random ( ) ) * tmp ; END ; - - - - FUNCTION sine ( x: variant ) : variant ; - BEGIN result := sin ( x ); END ; - - - - FUNCTION All ( f: FunA ; x: Varyray ) : variant ; - - VAR - - k : integer ; - - BEGIN - - result := True ; - - FOR k := Low ( x ) TO High ( x ) DO - result := AND_xy ( result , f ( x [ k ] ) ) ; - - END ; - - - - FUNCTION Any ( f: FunA ; x: Varyray ) : variant ; - - VAR - - k : integer ; - - BEGIN - - result := False ; - - FOR k := Low ( x ) TO High ( x ) DO - result := OR_xy ( result , f ( x [ k ] ) ) ; - - END ; -END. - - -(*) === How to use in a program === (*) - - -program testMRF.pas; -{$mode Delphi} {$H+} {$J-} {$R+} (*) https://www.freepascal.org/docs-html/prog/progch1.html (*) -USES - MRF, - Math, - SysUtils, - Variants; - {$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined} // Use for variants - -VAR - - a,b,c : array of variant ; - - Acc : variant ; - -BEGIN - - Randomize ; - - setlength ( a, 6 ) ; - setlength ( b, 4 ) ; - setlength ( c, 6 ) ; - - a := Map ( RandFillInt , a ) ; - Map ( show , a ) ; - writeln ; - - b := Map ( RandFillInt , b ) ; - Map ( show , b ) ; - writeln ; - - c := Map ( RandFillInt , c ) ; - Map ( show , c ) ; - writeln ; - - Acc := FoldL ( add , a ) ; - WriteLn ( 'Sum = ' , Acc ) ; - writeln ; - - Acc := Reduce ( contain , 31, a ) ; - WriteLn ( 'contains = ' , Acc ) ; - writeln ; - - c := Filter ( delete , 31, a ) ; - WriteLn ( 'del c :' ) ; - Map ( show , c ) ; - writeln ; - - a := Reverse ( c ) ; - WriteLn ( 'reverse c :' ) ; - Map ( show , a ) ; - writeln ; - - Acc := avg ( b ) ; - WriteLn ( 'avg = ' , Acc ) ; - writeln ; - - c := Map ( cotangens , b ) ; - writeln ( 'cot : ' ) ; - Map ( show , c ) ; - writeln ; - - Acc := FoldR ( min , b ) ; - WriteLn ( 'min = ' , Acc ); - writeln ; - - Acc := FoldR ( max , b ) ; - WriteLn ( 'max = ' , Acc ); - writeln ; - - Map ( show , b ) ; - Acc := All ( Is_Odd , b ) ; - writeln ; - WriteLn ( 'All Is_Odd = ' , Acc ) ; - writeln ; - - Map ( show , b ) ; - Acc := Any ( Is_Even , b ) ; - writeln ; - WriteLn ( 'Any Is_Even = ' , Acc ) ; - writeln ; - - Acc := Head ( b ) ; - WriteLn ( 'Head = ' , Acc ) ; - - Acc := Last ( b ) ; - WriteLn ( 'Last = ' , Acc ) ; - - Map ( show , b ) ; - a := Tail ( b ) ; - writeln ; - WriteLn ( 'Tail of b :' ) ; - Map ( show , a ) ; - writeln ; - - Map ( show , b ) ; - a := Take ( 2, b ) ; - writeln ; - WriteLn ( 'Take 2 from b :' ) ; - Map ( show , a ) ; - writeln ; - - setlength ( c, 0 ) ; - setlength ( b, 0 ) ; - setlength ( a, 0 ) ; - - - -END. +end. (*) program testMRF3 (*) +====================================================================== diff --git a/Task/Higher-order-functions/REXX/higher-order-functions-2.rexx b/Task/Higher-order-functions/REXX/higher-order-functions-2.rexx deleted file mode 100644 index 95629ca316..0000000000 --- a/Task/Higher-order-functions/REXX/higher-order-functions-2.rexx +++ /dev/null @@ -1,12 +0,0 @@ -/*REXX program demonstrates the passing of a name of a function to another function. */ -call function 'fact' , 6; say right( 'fact{'$"} = ", 30) result -call function 'square' , 13; say right( 'square{'$"} = ", 30) result -call function 'cube' , 3; say right( 'cube{'$"} = ", 30) result -call function 'reverse', 721; say right( 'reverse{'$"} = ", 30) result -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -cube: return $**3 -fact: procedure expose $; !=1; do j=2 to $; !=!*j; end; return ! -function: arg ?.; parse arg ,$; signal value (?.) -reverse: return 'REVERSE'($) -square: return $**2 diff --git a/Task/Higher-order-functions/REXX/higher-order-functions-1.rexx b/Task/Higher-order-functions/REXX/higher-order-functions.rexx similarity index 69% rename from Task/Higher-order-functions/REXX/higher-order-functions-1.rexx rename to Task/Higher-order-functions/REXX/higher-order-functions.rexx index 11f07018d9..2a618f1913 100644 --- a/Task/Higher-order-functions/REXX/higher-order-functions-1.rexx +++ b/Task/Higher-order-functions/REXX/higher-order-functions.rexx @@ -1,7 +1,8 @@ include Settings -Main: -say version; say 'Higher-order functions'; say +say 'HIGHER-ORDER FUNCTIONS - 2 Mar 2025' +say version +say call Calculate '1/x',6 call Calculate 'Sqrt(x)',2 call Calculate 'Sin(x)',1 @@ -14,14 +15,9 @@ exit Calculate: procedure parse arg ff,xx -say ff 'for x='xx 'makes' Evaluate(ff,xx)+0 +say ff 'for x='xx 'makes' Eval(ff,xx)+0 return -Evaluate: -procedure -parse arg f,x -interpret 'return' f - include Functions include Constants include Abend diff --git a/Task/Hilbert-curve/EasyLang/hilbert-curve.easy b/Task/Hilbert-curve/EasyLang/hilbert-curve.easy index 2ec0f3ac60..648255ff81 100644 --- a/Task/Hilbert-curve/EasyLang/hilbert-curve.easy +++ b/Task/Hilbert-curve/EasyLang/hilbert-curve.easy @@ -1,9 +1,16 @@ order = 64 -linewidth 32 / order +glinewidth 32 / order scale = 100 / order - 100 / (order * order) -proc hilbert x y lg i1 i2 . . +xp = 0 / 0 +yp = xp +proc xline x y . + if xp = xp : gline xp yp x y + xp = x + yp = y +. +proc hilbert x y lg i1 i2 . if lg = 1 - line (order - x) * scale (order - y) * scale + xline (order - x) * scale (order - y) * scale return . lg = lg div 2 diff --git a/Task/Hofstadter-Conway-$10-000-sequence/EasyLang/hofstadter-conway-$10-000-sequence.easy b/Task/Hofstadter-Conway-$10-000-sequence/EasyLang/hofstadter-conway-$10-000-sequence.easy index 4a4c98272d..e865796ed7 100644 --- a/Task/Hofstadter-Conway-$10-000-sequence/EasyLang/hofstadter-conway-$10-000-sequence.easy +++ b/Task/Hofstadter-Conway-$10-000-sequence/EasyLang/hofstadter-conway-$10-000-sequence.easy @@ -1,4 +1,4 @@ -numfmt 4 0 +numfmt 0 4 a[] = [ 1 1 ] x = 1 n = 2 @@ -12,9 +12,7 @@ for p = 1 to 19 a[] &= x f = x / n max = higher max f - if f >= 0.55 - mallow = n - . + if f >= 0.55 : mallow = n . print "max between 2^" & p & " and 2^" & p + 1 & " was " & max . diff --git a/Task/Hofstadter-Figure-Figure-sequences/EasyLang/hofstadter-figure-figure-sequences.easy b/Task/Hofstadter-Figure-Figure-sequences/EasyLang/hofstadter-figure-figure-sequences.easy index 5cd6bf9baf..cb073d5c52 100644 --- a/Task/Hofstadter-Figure-Figure-sequences/EasyLang/hofstadter-figure-figure-sequences.easy +++ b/Task/Hofstadter-Figure-Figure-sequences/EasyLang/hofstadter-figure-figure-sequences.easy @@ -1,5 +1,5 @@ global rs[] ss[] . -procdecl RS_append . . +procdecl RS_append . func R n . while n > len rs[] RS_append @@ -12,7 +12,7 @@ func S n . . return ss[n] . -proc RS_append . . +proc RS_append . n = len rs[] r = R n + S n s = S len ss[] diff --git a/Task/Hofstadter-Q-sequence/EasyLang/hofstadter-q-sequence.easy b/Task/Hofstadter-Q-sequence/EasyLang/hofstadter-q-sequence.easy index 4a1d578fcb..20beb55cac 100644 --- a/Task/Hofstadter-Q-sequence/EasyLang/hofstadter-q-sequence.easy +++ b/Task/Hofstadter-Q-sequence/EasyLang/hofstadter-q-sequence.easy @@ -1,20 +1,16 @@ -proc hofstadter limit . q[] . +proc hofstadter limit &q[] . q[] = [ 1 1 ] for n = 3 to limit q[] &= q[n - q[n - 1]] + q[n - q[n - 2]] . . -proc count . q[] cnt . +proc count &q[] &cnt . for i = 2 to len q[] - if q[i] < q[i - 1] - cnt += 1 - . + if q[i] < q[i - 1] : cnt += 1 . . hofstadter 100000 hofq[] -for i = 1 to 10 - write hofq[i] & " " -. +for i = 1 to 10 : write hofq[i] & " " print "" print hofq[1000] count hofq[] cnt diff --git a/Task/Home-primes/REXX/home-primes-1.rexx b/Task/Home-primes/REXX/home-primes-1.rexx deleted file mode 100644 index a984657af5..0000000000 --- a/Task/Home-primes/REXX/home-primes-1.rexx +++ /dev/null @@ -1,46 +0,0 @@ -/*REXX program finds and displays the home prime of a range of positive integers. */ -numeric digits 20 /*ensure handling of larger integers. */ -parse arg LO HI . /*obtain optional arguments from the CL*/ -if LO=='' | LO=="," then LO= 2 /*Not specified? Then use the default.*/ -if HI=='' | HI=="," then HI= 20 /* " " " " " " */ -@hpc= 'home prime chain for ' /*a literal used in two SAY statements.*/ - w= length(HI) /*HI width, used for output alignment. */ - do j=max(2, LO) to HI /*find home primes for an integer range*/ - pf= factr(j); f= words(pf) /*get prime factors; number of factors.*/ - if f==1 then do; say @hpc j": " j ' is prime.'; iterate; end /*J is prime*/ - xxx.1= j /*save J in the first array element. */ - do n=2 until #==1 /*keep processing until we find a prime*/ - xxx.n= space(pf, 0) /*obtain factors of a concatenated p.f.*/ - pf= factr(xxx.n); #= words(pf) /*assign factors to PF; # of factors. */ - end /*n*/ - ee= n /*save EE as the final (last) prime. */ - n= n - 1; z= n /*adjust N (for DO loop); assign N to Z*/ - $= /*nullify the string of home primes. */ - do m=1 for n /*build a list ($) of " " */ - $= $ 'HP'xxx.m"("z') ─► ' /*concatenate to string of " " */ - z= z - 1 /*decrease the index counter by unity. */ - end /*m*/ /* [↑] the index counter is decreasing*/ - - say @hpc right(j, w)":" $ xxx.ee ' is prime.' /*show string of home primes.*/ - end /*n*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -factr: procedure; parse arg x 1 d,$ /*set X, D to argument 1; $ to null.*/ - if x==1 then return '' /*handle the special case of X = 1. */ - do while x//2==0; $= $ 2; x= x% 2; end /*append all the 2 factors of new X.*/ - do while x//3==0; $= $ 3; x= x% 3; end /* " " " 3 " " " " */ - do while x//5==0; $= $ 5; x= x% 5; end /* " " " 5 " " " " */ - do while x//7==0; $= $ 7; x= x% 7; end /* " " " 7 " " " " */ - q= 1; r= 0 /*R: will be iSqrt(x). ___*/ - do while q<=x; q=q*4; end /*these two lines compute integer √ X */ - do while q>1; q=q%4; _= d-r-q; r= r%2; if _>=0 then do; d= _; r= r+q; end; end - - do k=11 by 6 to r /*insure that J isn't divisible by 3.*/ - parse var k '' -1 _ /*obtain the last decimal digit of K. */ - if _\==5 then do while x//k==0; $=$ k; x=x%k; end /*maybe reduce by K.*/ - if _ ==3 then iterate /*Is next Y is divisible by 5? Skip.*/ - y= k+2; do while x//y==0; $=$ y; x=x%y; end /*maybe reduce by Y.*/ - end /*k*/ - /* [↓] The $ list has a leading blank.*/ - if x==1 then return $ /*Is residual=unity? Then don't append.*/ - return $ x /*return $ with appended residual. */ diff --git a/Task/Home-primes/REXX/home-primes-2.rexx b/Task/Home-primes/REXX/home-primes-2.rexx deleted file mode 100644 index 7e9d82baa9..0000000000 --- a/Task/Home-primes/REXX/home-primes-2.rexx +++ /dev/null @@ -1,40 +0,0 @@ -include Settings - -say version; say 'Home Primes'; say -numeric digits 22 -do i = 1 to 48 - call Home i -end -exit - -Home: -procedure expose fact. glob. work. -arg xx -call Time('r') -yy = xx/1 -/* Collect chain */ -n = 0 -do while Factors(yy) > 1 - n = n+1; work.n = yy; yy = '' - do i = 1 to fact.0 - yy = yy||fact.factor.i - end -end -/* Show results */ -if n = 0 then - call Charout ,'HP'xx '= ' -else do - do i = 1 to n - call Charout ,'HP'work.i'('n-i+1') = ' - end -end -call Charout ,yy -say -say Time('e')/1 'seconds' -say -return - -include Abend -include Functions -include Numbers -include Sequences diff --git a/Task/Home-primes/REXX/home-primes.rexx b/Task/Home-primes/REXX/home-primes.rexx new file mode 100644 index 0000000000..7be1fef20a --- /dev/null +++ b/Task/Home-primes/REXX/home-primes.rexx @@ -0,0 +1,48 @@ +-- 25 Apr 2025 +include Settings + +say 'HOME PRIMES' +say version +say +numeric digits 50 +do i = 1 to 48 + call Home i +end +exit + +Home: +procedure expose fact. glob. work. +arg xx +call Time('r') +if xx = 1 then + call charout ,'HP1 = 1' +else do + yy = xx/1 +-- Collect chain + n = 0 + do while Factors(yy) > 1 + n = n+1; work.n = yy; yy = '' + do i = 1 to fact.0 + yy = yy||fact.i + end + end +-- Show results + if n = 0 then + call Charout ,'HP'xx '= ' + else do + do i = 1 to n + call Charout ,'HP'work.i'('n-i+1') = ' + end + end + call Charout ,yy +end +say +call Timer +say +return + +include Helper +include Abend +include Functions +include Numbers +include Sequences diff --git a/Task/Horners-rule-for-polynomial-evaluation/REXX/horners-rule-for-polynomial-evaluation-2.rexx b/Task/Horners-rule-for-polynomial-evaluation/REXX/horners-rule-for-polynomial-evaluation-2.rexx index b74d9bd5cb..98fb4c679f 100644 --- a/Task/Horners-rule-for-polynomial-evaluation/REXX/horners-rule-for-polynomial-evaluation-2.rexx +++ b/Task/Horners-rule-for-polynomial-evaluation/REXX/horners-rule-for-polynomial-evaluation-2.rexx @@ -1,5 +1,8 @@ include Settings -say version; say 'Polynomial Horner''s rule'; say + +say 'POLYNOMIAL HORNER''S RULE - 2 Mar 2025' +say version +say call Evaluate '6 -4 7 -19',3 call Evaluate '2',4 call Evaluate '2 3',0 diff --git a/Task/Humble-numbers/EasyLang/humble-numbers.easy b/Task/Humble-numbers/EasyLang/humble-numbers.easy index 294a66c460..035ba4e445 100644 --- a/Task/Humble-numbers/EasyLang/humble-numbers.easy +++ b/Task/Humble-numbers/EasyLang/humble-numbers.easy @@ -1,19 +1,9 @@ fastfunc humble i . - if i <= 1 - return 1 - . - if i mod 2 = 0 - return humble (i / 2) - . - if i mod 3 = 0 - return humble (i / 3) - . - if i mod 5 = 0 - return humble (i / 5) - . - if i mod 7 = 0 - return humble (i / 7) - . + if i <= 1 : return 1 + if i mod 2 = 0 : return humble (i / 2) + if i mod 3 = 0 : return humble (i / 3) + if i mod 5 = 0 : return humble (i / 5) + if i mod 7 = 0 : return humble (i / 7) return 0 . fastfunc next_humble n . @@ -28,12 +18,8 @@ while cnt < 5193 n = next_humble n arr[log10 n + 1] += 1 cnt += 1 - if cnt <= 50 - write n & " " - . + if cnt <= 50 : write n & " " . print "" print "" -for i to 9 - print arr[i] & " with " & i & " digits" -. +for i to 9 : print arr[i] & " with " & i & " digits" diff --git a/Task/Humble-numbers/REXX/humble-numbers-1.rexx b/Task/Humble-numbers/REXX/humble-numbers-1.rexx deleted file mode 100644 index c4f9c240cd..0000000000 --- a/Task/Humble-numbers/REXX/humble-numbers-1.rexx +++ /dev/null @@ -1,44 +0,0 @@ -/*REXX program computes and displays humble numbers, also will display counts of sizes.*/ -parse arg n m . /*obtain optional arguments from the CL*/ -if n=='' | n=="," then n= 50 /*Not specified? Then use the default.*/ -if m=='' | m=="," then m= 60 /* " " " " " " */ -numeric digits 1 + max(20, m) /*be able to handle some big numbers. */ -$.= 0 /*a count array for X digit humble #s*/ -call humble n; list= /*call HUMBLE sub; initialize the list.*/ - do j=1 for n; list= list @.j /*append a humble number to the list.*/ - end /*j*/ - -if list\='' then do; say "A list of the first " n ' humble numbers are:' - say strip(list) /*elide the leading blank in the list. */ - end -say -call humble -m /*invoke subroutine for counting nums. */ -if $.1==0 then exit /*if no counts, then we're all finished*/ -total= 0 /*initialize count of humble numbers. */ -$.1= $.1 + 1 /*adjust count for absent 1st humble #.*/ -say ' The digit counts of humble numbers:' -say ' ═════════════════════════════════════════' - do c=1 while $.c>0; s= left('s', length($.c)>1) /*count needs pluralization?*/ - say right( commas($.c), 30) ' have ' right(c, 2) " digit"s - total= total + $.c /* ◄─────────────────────────────────┐ */ - end /*k*/ /*bump humble number count (so far)──┘ */ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: procedure; arg _; do i=length(_)-3 to 1 by -3; _=insert(',', _, i); end; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -humble: procedure expose @. $.; parse arg x; if x==0 then return - y= abs(x); a= y; noCount= x>0; if x<0 then y= 999999999 - #2= 1; #3= 1; #5= 1; #7= 1 /*define the initial humble constants. */ - $.= 0; @.= 0; @.1= 1 /*initialize counts and humble numbers.*/ - do h=2 for y-1 - @.h= min(2*@.#2,3*@.#3,5*@.#5,7*@.#7) /*pick the minimum of 4 humble numbers.*/ - m= @.h /*M: " " " " " " */ - if 2*@.#2 == m then #2 = #2 + 1 /*Is number already defined? Use next #*/ - if 3*@.#3 == m then #3 = #3 + 1 /* " " " " " " "*/ - if 5*@.#5 == m then #5 = #5 + 1 /* " " " " " " "*/ - if 7*@.#7 == m then #7 = #7 + 1 /* " " " " " " "*/ - if noCount then iterate /*Not counting digits? Then iterate. */ - L= length(m); if L>a then leave /*Are we done with counting? Then quit*/ - $.L= $.L + 1 /*bump the digit count for this number.*/ - end /*h*/ /*the humble numbers are in the @ array*/ - return /* " count results " " " $ " */ diff --git a/Task/Humble-numbers/REXX/humble-numbers-2.rexx b/Task/Humble-numbers/REXX/humble-numbers-2.rexx deleted file mode 100644 index c57d584992..0000000000 --- a/Task/Humble-numbers/REXX/humble-numbers-2.rexx +++ /dev/null @@ -1,86 +0,0 @@ -include Settings - -say version; say 'Humble numbers'; say -call Humbles 50 -call ShowFirstN 50 -call Humbles 1e7 -call ShowDistribution -exit - -Humbles: -procedure expose humb. -arg xx -call Time('r') -xx = xx/1 -say 'Collect humble numbers up to the' xx'th' -/* Ensure enough digits */ -numeric digits 2**(Length(xx)+1) -/* Dijkstra */ -humb.humble.1 = 1 -x2 = 2; x3 = 3; x5 = 5; x7 = 7; i2 = 1; i3 = 1; i5 = 1; i7 = 1 -do yy = 2 - h = x2 - if x3 < h then - h = x3 - if x5 < h then - h = x5 - if x7 < h then - h = x7 - humb.humble.yy = h - if yy = xx then - leave - if x2 = h then do - i2 = i2+1; x2 = humb.humble.i2+humb.humble.i2 - end - if x3 = h then do - i3 = i3+1; x3 = humb.humble.i3+humb.humble.i3+humb.humble.i3 - end - if x5 = h then do - i5 = i5+1; x5 = humb.humble.i5*5 - end - if x7 = h then do - i7 = i7+1; x7 = humb.humble.i7*7 - end -end -humb.0 = yy -say Time('e')/1 'seconds' -say -return - -ShowFirstN: -procedure expose humb. -arg xx -call Time('r') -xx = xx/1 -say 'First' xx 'humble numbers are' -do i = 1 to xx - call Charout ,Right(humb.humble.i,4) - if i//10 = 0 then - say -end -say Time('e')/1 'seconds' -say -return - -ShowDistribution: -procedure expose humb. -call Time('r') -say 'Digit distribution for the first' humb.0 'humble numbers' -d. = 0 -do i = 1 to humb.0 - l = Length(humb.humble.i); d.l = d.l + 1; d.0 = Max(l,d.0) -end -l = Copies('-',17) -say l -say 'Dg Count Cum' -say l -c = 0 -do i = 1 to d.0-1 - c = c + d.i - say Right(i,2) Right(d.i,6) Right(c,7) -end -say l -say Time('e')/1 'seconds' -return - -include Abend diff --git a/Task/Humble-numbers/REXX/humble-numbers.rexx b/Task/Humble-numbers/REXX/humble-numbers.rexx new file mode 100644 index 0000000000..be90435bee --- /dev/null +++ b/Task/Humble-numbers/REXX/humble-numbers.rexx @@ -0,0 +1,48 @@ +-- 22 Mar 2025 +include Settings + +say 'HUMBLE NUMBERS' +say version +say +call Humbles 50 +call ShowFirstN 50 +call Humbles 10000000 +call ShowDistribution +say Time('e')/1 'seconds' +exit + +ShowFirstN: +procedure expose humb. +arg xx +xx = xx/1 +say 'First' xx 'humble numbers are' +do i = 1 to xx + call Charout ,Right(humb.i,4) + if i//10 = 0 then + say +end +say +return + +ShowDistribution: +procedure expose humb. +say 'Digit distribution for the first' humb.0 'humble numbers' +d. = 0 +do i = 1 to humb.0 + l = Length(humb.i); d.l = d.l + 1; d.0 = Max(l,d.0) +end +l = Copies('-',17) +say l +say 'Dg Count Cum' +say l +c = 0 +do i = 1 to d.0-1 + c = c + d.i + say Right(i,2) Right(d.i,6) Right(c,7) +end +say l +return + +include Abend +include Functions +include Sequences diff --git a/Task/I-before-E-except-after-C/Nu/i-before-e-except-after-c-1.nu b/Task/I-before-E-except-after-C/Nu/i-before-e-except-after-c-1.nu new file mode 100644 index 0000000000..2c9926743c --- /dev/null +++ b/Task/I-before-E-except-after-C/Nu/i-before-e-except-after-c-1.nu @@ -0,0 +1,32 @@ +# Fetch and process the word list +let words = open unixdict.txt | lines | where { ($in | str length) > 3 } + +# Function to count matches for a pattern +def count-pattern [pattern: string] { + $words | where $it =~ $pattern | length +} + +# Count occurrences for "I before E" rule +let ie_not_c = (count-pattern "(^|[^c])ie") # ie not preceded by c +let ei_not_c = (count-pattern "(^|[^c])ei") # ei not preceded by c + +# Count occurrences for "E before I" rule +let cei = (count-pattern "cei") # ei preceded by c +let cie = (count-pattern "cie") # ie preceded by c + +# Check plausibility (more than 2x occurrences of opposite) +let rule1_plausible = ($ie_not_c > ($ei_not_c * 2)) +let rule2_plausible = ($cei > ($cie * 2)) + +# Output results +print [ + $"Analyzing 'I before E when not preceded by C':" + $" correct for : ($ie_not_c)" + $" not correct for : ($ei_not_c)" + $" Plausible: ($rule1_plausible)" + $"" + $"Analyzing 'E before I when preceded by C':" + $" correct for : ($cei)" + $" not correct for : ($cie)" + $" Plausible: ($rule2_plausible)" + ] diff --git a/Task/I-before-E-except-after-C/Nu/i-before-e-except-after-c-2.nu b/Task/I-before-E-except-after-C/Nu/i-before-e-except-after-c-2.nu new file mode 100644 index 0000000000..4519c2d750 --- /dev/null +++ b/Task/I-before-E-except-after-C/Nu/i-before-e-except-after-c-2.nu @@ -0,0 +1,48 @@ +# Fetch and filter words +let words = open unixdict.txt | lines | where { $in | str length | $in > 3 } + +# Define patterns and their processing in a functional way +let patterns = [ + { name: "ie_not_c", pattern: "(^|[^c])ie", desc: "I before E when not preceded by C" } + { name: "ei_not_c", pattern: "(^|[^c])ei", desc: null } + { name: "cei", pattern: "cei", desc: "E before I when preceded by C" } + { name: "cie", pattern: "cie", desc: null } +] + +# Count matches for each pattern functionally +let counts = $patterns | + each { |p| + $p | upsert count ($words | where $it =~ $p.pattern | length) + } + +# Calculate plausibility using match +let results = $counts | + each { |row| + match $row.name { + "ie_not_c" => { + let opposite = ($counts | where name == "ei_not_c" | get count.0) + $row | upsert plausible ($row.count > ($opposite * 2)) + } + "cei" => { + let opposite = ($counts | where name == "cie" | get count.0) + $row | upsert plausible ($row.count > ($opposite * 2)) + } + _ => $row + } + } + +# Format and print results functionally +$results | + where desc != null | + each { |rule| + let opposite = ($results | where name == (if $rule.name == "ie_not_c" { "ei_not_c" } else { "cie" }) | get 0) + [ + $"Analyzing '($rule.desc)':" + $" correct for : ($rule.count)" + $" not correct for : ($opposite.count)" + $" Plausible: ($rule.plausible)" + "" + ] + } | + flatten | + print $in diff --git a/Task/IBAN/EasyLang/iban.easy b/Task/IBAN/EasyLang/iban.easy index 20ac406d24..161c31d836 100644 --- a/Task/IBAN/EasyLang/iban.easy +++ b/Task/IBAN/EasyLang/iban.easy @@ -47,7 +47,7 @@ func isvalid hiban$ . . return if mod97 t$ = 1 . -proc check s$ . . +proc check s$ . write s$ & " is " if isvalid s$ = 1 print "valid" diff --git a/Task/Identity-matrix/EasyLang/identity-matrix.easy b/Task/Identity-matrix/EasyLang/identity-matrix.easy index d1552ef970..b85b3166c1 100644 --- a/Task/Identity-matrix/EasyLang/identity-matrix.easy +++ b/Task/Identity-matrix/EasyLang/identity-matrix.easy @@ -1,4 +1,4 @@ -proc idmat lng . mat[][] . +proc idmat lng &mat[][] . len mat[][] lng for i to lng len mat[i][] lng diff --git a/Task/Identity-matrix/Excel/identity-matrix.excel b/Task/Identity-matrix/Excel/identity-matrix-1.excel similarity index 100% rename from Task/Identity-matrix/Excel/identity-matrix.excel rename to Task/Identity-matrix/Excel/identity-matrix-1.excel diff --git a/Task/Identity-matrix/Excel/identity-matrix-2.excel b/Task/Identity-matrix/Excel/identity-matrix-2.excel new file mode 100644 index 0000000000..f72b963773 --- /dev/null +++ b/Task/Identity-matrix/Excel/identity-matrix-2.excel @@ -0,0 +1 @@ +=MUNIT(A2) diff --git a/Task/Im-a-software-engineer-get-me-out-of-here/Python/im-a-software-engineer-get-me-out-of-here.py b/Task/Im-a-software-engineer-get-me-out-of-here/Python/im-a-software-engineer-get-me-out-of-here.py new file mode 100644 index 0000000000..c3f70e7ca3 --- /dev/null +++ b/Task/Im-a-software-engineer-get-me-out-of-here/Python/im-a-software-engineer-get-me-out-of-here.py @@ -0,0 +1,175 @@ +from collections import deque +from dataclasses import dataclass +from typing import List + +@dataclass(frozen=True) +class CellWithCost: + fromRow: int + fromCol: int + cost: int + +ZERO = CellWithCost(0, 0, 0) + +@dataclass +class Cell: + row: int + col: int + + def __repr__(self): + return f"({self.row}, {self.col})" + +GMOOH = ( + ".........00000.........\n" + "......00003130000......\n" + "....000321322221000....\n" + "...00231222432132200...\n" + "..0041433223233211100..\n" + "..0232231612142618530..\n" + ".003152122326114121200.\n" + ".031252235216111132210.\n" + ".022211246332311115210.\n" + "00113232262121317213200\n" + "03152118212313211411110\n" + "03231234121132221411410\n" + "03513213411311414112320\n" + "00427534125412213211400\n" + ".013322444412122123210.\n" + ".015132331312411123120.\n" + ".003333612214233913300.\n" + "..0219126511415312570..\n" + "..0021321524341325100..\n" + "...00211415413523200...\n" + "....000122111322000....\n" + "......00001120000......\n" + ".........00000.........\n" +).strip().splitlines() +HEIGHT, WIDTH = len(GMOOH), len(GMOOH[0]) + +directions = [ + Cell(1, -1), Cell(1, 0), Cell(1, 1), + Cell(0, -1), Cell(0, 1), + Cell(-1, -1), Cell(-1, 0), Cell(-1, 1) +] +routes: List[List[CellWithCost]] = [] + +#### Helper functions #### + +def digit(ch: str) -> int: + return int(ch) if ch.isdigit() else -1 + +#### End of helper functions #### + +def searchFromCell(startRow: int, startCol: int): + global routes + + routes = [[ZERO for _ in range(WIDTH)] for _ in range(HEIGHT)] + routes[startRow][startCol] = CellWithCost(startRow, startCol, 0) + + queue = deque() + row, col, cost = startRow, startCol, 0 + + while True: + step = digit(GMOOH[row][col]) + for d in directions: + nr = row + step * d.row + nc = col + step * d.col + + if 0 <= nr < HEIGHT and 0 <= nc < WIDTH and digit(GMOOH[nr][nc]) >= 0: + current = routes[nr][nc] + if current == ZERO or current.cost > cost + 1: + routes[nr][nc] = CellWithCost(row, col, cost+1) + if digit(GMOOH[nr][nc]) > 0: + queue.append(CellWithCost(nr, nc, cost+1)) + if not queue: + break + + nextCell = queue.popleft() + row, col, cost = nextCell.fromRow, nextCell.fromCol, nextCell.cost + +def createRouteToCell(endRow: int, endCol: int) -> List[Cell]: + route: deque[Cell] = deque() + route.append(Cell(endRow, endCol)) + + while True: + cw = routes[endRow][endCol] + if cw.cost == 0: + break + endRow, endCol = cw.fromRow, cw.fromCol + route.appendleft(Cell(endRow, endCol)) + + return list(route) + +def showShortestRoutes(): + minCost = float("inf") + bestCells: List[Cell] = [] + + for r in range(HEIGHT): + for c in range(WIDTH): + if digit(GMOOH[r][c]) == 0: + cw = routes[r][c] + if cw != ZERO: + if cw.cost < minCost: + minCost = cw.cost + bestCells.clear() + if cw.cost == minCost: + bestCells.append(Cell(r, c)) + + plural = "s" if len(bestCells) != 1 else "" + isAre = "are" if len(bestCells) != 1 else "is" + + print(f"There {isAre} {len(bestCells)} shortest route{plural} of {minCost} days to safety:") + for cell in bestCells: + print(createRouteToCell(cell.row, cell.col)) + +def showUnreachableCells(): + unreachable: List[Cell] = [] + for r in range(HEIGHT): + for c in range(WIDTH): + if digit(GMOOH[r][c]) == 0 and routes[r][c] == ZERO: + unreachable.append(Cell(r, c)) + + print("The following cells are unreachable:") + print(unreachable) + +def showCellsWithLongestRoute(): + maxCost = -1 + worstCells: List[Cell] = [] + + for r in range(HEIGHT): + for c in range(WIDTH): + if digit(GMOOH[r][c]) >= 0: + cw = routes[r][c] + if cw != ZERO: + if cw.cost > maxCost: + maxCost = cw.cost + worstCells.clear() + if cw.cost == maxCost: + worstCells.append(Cell(r, c)) + + plural = "s" if len(worstCells) != 1 else "" + isAre = "are" if len(worstCells) != 1 else "is" + + print(f"There {isAre} {len(worstCells)} cell{plural} that require {maxCost} days to receive reinforcements from HQ:") + for cell in worstCells: + print(createRouteToCell(cell.row, cell.col)) + +if __name__ == "__main__": + searchFromCell(11, 11) + showShortestRoutes() + print() + + searchFromCell(21, 11) + print("The shortest route from (21, 11) to (1, 11):") + print(createRouteToCell(1, 11)) + print() + + searchFromCell(1, 11) + print("The shortest route from (1, 11) to (21, 11):") + print(createRouteToCell(21, 11)) + print() + + searchFromCell(11, 11) + showUnreachableCells() + print() + + showCellsWithLongestRoute() diff --git a/Task/Image-noise/EasyLang/image-noise.easy b/Task/Image-noise/EasyLang/image-noise.easy index 002181b964..0c5e24aab9 100644 --- a/Task/Image-noise/EasyLang/image-noise.easy +++ b/Task/Image-noise/EasyLang/image-noise.easy @@ -1,24 +1,19 @@ -proc pset x y c . . - color c - move x / 3.2 y / 3.2 - rect 0.3 0.3 +proc pset x y c . + gcolor c + grect x / 3.2 y / 3.2 0.3 0.3 . on animate fr += 1 if systime - t0 >= 1 - move 10 78 - color -2 - rect 80 20 - color -1 - move 10 80 - text fr / (systime - t0) & " fps" + gcolor -2 + grect 10 78 80 20 + gcolor -1 + gtext 10 80 fr / (systime - t0) & " fps" t0 = systime fr = 0 . col[] = [ 000 999 ] - for x = 0 to 319 - for y = 0 to 199 - pset x y col[random 2] - . + for x = 0 to 319 : for y = 0 to 199 + pset x y col[random 2] . . diff --git a/Task/Include-a-file/Bracmat/include-a-file.bracmat b/Task/Include-a-file/Bracmat/include-a-file.bracmat index e2454aa96a..abe7c136ab 100644 --- a/Task/Include-a-file/Bracmat/include-a-file.bracmat +++ b/Task/Include-a-file/Bracmat/include-a-file.bracmat @@ -1 +1 @@ -get$"module" +get$"filename" diff --git a/Task/Increasing-gaps-between-consecutive-Niven-numbers/EasyLang/increasing-gaps-between-consecutive-niven-numbers.easy b/Task/Increasing-gaps-between-consecutive-Niven-numbers/EasyLang/increasing-gaps-between-consecutive-niven-numbers.easy index 3383503a31..20c527d2c5 100644 --- a/Task/Increasing-gaps-between-consecutive-Niven-numbers/EasyLang/increasing-gaps-between-consecutive-niven-numbers.easy +++ b/Task/Increasing-gaps-between-consecutive-Niven-numbers/EasyLang/increasing-gaps-between-consecutive-niven-numbers.easy @@ -12,7 +12,7 @@ func divisible n d . . return if n mod d = 0 . -numfmt 0 8 +numfmt 8 0 previous = 1 print " Gap index Gap Niven index Niven number" print " --------- --- ----------- ------------" diff --git a/Task/Increment-a-numerical-string/Crystal/increment-a-numerical-string.cr b/Task/Increment-a-numerical-string/Crystal/increment-a-numerical-string.cr new file mode 100644 index 0000000000..f04b621930 --- /dev/null +++ b/Task/Increment-a-numerical-string/Crystal/increment-a-numerical-string.cr @@ -0,0 +1,5 @@ +"-123".succ # => "-124" + +require "big" + +"-123".to_big_i.succ.to_s # => "-122" diff --git a/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-1.tcl b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-1.tcl new file mode 100644 index 0000000000..4d393681e7 --- /dev/null +++ b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-1.tcl @@ -0,0 +1,10 @@ +# n is string +set n "1234" + +# integer rep added to n +# o is calculated integer +set o [expr $n + 1] + +# n is string, +# o used as string adds string representation to o +puts stdout "$n incrememented is $o" diff --git a/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-2.tcl b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-2.tcl new file mode 100644 index 0000000000..b8aca0da50 --- /dev/null +++ b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-2.tcl @@ -0,0 +1,6 @@ +# n has integer representation incremented +# n string rep updates when value changes +incr n 5 + +# n string rep used +puts stdout "n is now $n" diff --git a/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-3.tcl b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-3.tcl new file mode 100644 index 0000000000..55917fbae9 --- /dev/null +++ b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-3.tcl @@ -0,0 +1,5 @@ +# string +set j "4.3e11" + +# prints j as string +puts stdout "j: $j" diff --git a/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-4.tcl b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-4.tcl new file mode 100644 index 0000000000..61971b9a45 --- /dev/null +++ b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-4.tcl @@ -0,0 +1,4 @@ +# double fp temp calculated +# converts to string +# j not updated +puts stdout "j: [expr $j]" diff --git a/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-5.tcl b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-5.tcl new file mode 100644 index 0000000000..e5842d0384 --- /dev/null +++ b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-5.tcl @@ -0,0 +1,2 @@ +# j is still string "4.2e11" +puts stdout "j: $j" diff --git a/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-6.tcl b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-6.tcl new file mode 100644 index 0000000000..15f691bbb9 --- /dev/null +++ b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string-6.tcl @@ -0,0 +1 @@ +puts stdout "$j * $n = [expr $j * $n]" diff --git a/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string.tcl b/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string.tcl deleted file mode 100644 index d09f03800e..0000000000 --- a/Task/Increment-a-numerical-string/Tcl/increment-a-numerical-string.tcl +++ /dev/null @@ -1,2 +0,0 @@ -set str 1234 -incr str diff --git a/Task/Index-finite-lists-of-positive-integers/C-sharp/index-finite-lists-of-positive-integers.cs b/Task/Index-finite-lists-of-positive-integers/C-sharp/index-finite-lists-of-positive-integers.cs new file mode 100644 index 0000000000..68e2d6b4c1 --- /dev/null +++ b/Task/Index-finite-lists-of-positive-integers/C-sharp/index-finite-lists-of-positive-integers.cs @@ -0,0 +1,107 @@ +using System.Numerics; + +for (var i = 0; i < 5; i++) +{ + var length = Random.Shared.Next(3, 6); + List list = []; + + for (var j = 0; j < length; j++) + { + list.Add(Random.Shared.Next(1_000_000)); + } + + var r = Rank(list); + Console.WriteLine($"rank({string.Join(", ", list)}) = {r}"); + Console.WriteLine($"unrank({r}) = {string.Join(", ", Unrank(r))}"); + list.Add(length); + Console.WriteLine($" Count of bits in list = {list.Sum(m => Math.Log2((double)m)):0.0}"); + Console.WriteLine($" Count of bits in rank = {Math.Log2((double)r):0.0}"); +} + +for (var n = 0; n <= 10; n++) +{ + var list = Unrank(n, 3); + var m = Rank(list, 3); + Console.WriteLine($"{n}: [{string.Join(", ", list)}] : {m}"); +} + +const int DefaultBias = 10; + +static BigInteger Rank(List list, int bias = DefaultBias) +{ + list.ForEach(m => ArgumentOutOfRangeException.ThrowIfNegativeOrZero(m, nameof(list))); + if (list.Count == 0) return 0; + BigInteger n = 0; + List digits = []; + var first = true; + + foreach (var m in list) + { + if (!first) digits.Add(bias - 1); + first = false; + digits.AddRange(ToBijectiveBase(m - 1, bias - 1)); + } + + return 1 + FromBijectiveBase(digits, bias); +} + +static List Unrank(BigInteger n, int bias = DefaultBias) +{ + if (n-- == 0) return []; + var list = ToBijectiveBase(n, bias); + var i = 0; + List result = []; + List digits = []; + BigInteger m; + + while (i < list.Count) + { + while (i < list.Count && list[i] != bias - 1) + { + digits.Add(list[i]); + i++; + } + + if (i < list.Count) + { + m = FromBijectiveBase(digits, bias - 1); + result.Add(m + 1); + digits.Clear(); + i++; + } + } + + m = FromBijectiveBase(digits, bias - 1); + result.Add(m + 1); + return result; +} + +static BigInteger FromBijectiveBase(IEnumerable digits, int @base) +{ + BigInteger n = 0; + + foreach (var i in digits) + { + var a = i + 1; + if (a == @base) { a = 0; n++; } + n = n * @base + a; + } + + return n; +} + +static List ToBijectiveBase(BigInteger n, int @base) +{ + List list = []; + + while (n > 0) + { + var q = (n + (@base - 1)) / @base - 1; + var a = n - q * @base; + list.Add((int)a - 1); + n = q; + } + + list.Reverse(); + return list; +} diff --git a/Task/Input-loop/JavaScript/input-loop.js b/Task/Input-loop/JavaScript/input-loop-1.js similarity index 100% rename from Task/Input-loop/JavaScript/input-loop.js rename to Task/Input-loop/JavaScript/input-loop-1.js diff --git a/Task/Input-loop/JavaScript/input-loop-2.js b/Task/Input-loop/JavaScript/input-loop-2.js new file mode 100644 index 0000000000..a33323829c --- /dev/null +++ b/Task/Input-loop/JavaScript/input-loop-2.js @@ -0,0 +1,21 @@ +const readline = require("readline"); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +function askQuestion(query) { + return new Promise(resolve => rl.question(query, resolve)); +} + +async function main() { + while (true) { + const input = await askQuestion("Type something: "); + // do whatever you want with the input string + // remember to break the loop if you need + } + rl.close(); +} + +main(); diff --git a/Task/Integer-sequence/Uxntal/integer-sequence.uxnatl b/Task/Integer-sequence/Uxntal/integer-sequence.uxnatl new file mode 100644 index 0000000000..fdc8e1419c --- /dev/null +++ b/Task/Integer-sequence/Uxntal/integer-sequence.uxnatl @@ -0,0 +1,23 @@ +%comma { [ LIT2 ", -Console/write ] DEO } +%space { [ LIT2 20 -Console/write ] DEO } + +|18 @Console/write + +|100 + +#0001 +&loop + DUP2 print/dec comma space + INC2 !&loop + +BRK + +@print/dec ( short* -- ) + #000a SWP2 [ LITr ff ] + &get + SWP2k DIV2k MUL2 SUB2 STH + POP OVR2 DIV2 ORAk ?&get + POP2 POP2 + &put + STHr INCk ?{ POP JMP2r } + [ LIT "0 ] ADD .Console/write DEO !&put diff --git a/Task/Interactive-programming-repl-/Crystal/interactive-programming-repl-.cr b/Task/Interactive-programming-repl-/Crystal/interactive-programming-repl-.cr new file mode 100644 index 0000000000..17ba1deb2d --- /dev/null +++ b/Task/Interactive-programming-repl-/Crystal/interactive-programming-repl-.cr @@ -0,0 +1,11 @@ +> crystal i +Crystal interpreter 1.15.1 [89944bf] (2025-02-04). +EXPERIMENTAL SOFTWARE: if you find a bug, please consider opening an issue in +https://github.com/crystal-lang/crystal/issues/new/ +icr:1> def f(s1, s2, sep) +icr:2> s1 + sep + sep + s2 +icr:3> end + => nil +icr:4> f "Rosetta", "Code", ":" + => "Rosetta::Code" +icr:5> diff --git a/Task/Inverted-syntax/Ruby/inverted-syntax.rb b/Task/Inverted-syntax/Ruby/inverted-syntax-1.rb similarity index 100% rename from Task/Inverted-syntax/Ruby/inverted-syntax.rb rename to Task/Inverted-syntax/Ruby/inverted-syntax-1.rb diff --git a/Task/Inverted-syntax/Ruby/inverted-syntax-2.rb b/Task/Inverted-syntax/Ruby/inverted-syntax-2.rb new file mode 100644 index 0000000000..5c8a4175de --- /dev/null +++ b/Task/Inverted-syntax/Ruby/inverted-syntax-2.rb @@ -0,0 +1,4 @@ +7 => a +:x in b + +p [a, b] # => [7, :x] diff --git a/Task/Isograms-and-heterograms/EasyLang/isograms-and-heterograms.easy b/Task/Isograms-and-heterograms/EasyLang/isograms-and-heterograms.easy index a4353fbc53..44a4a304a1 100644 --- a/Task/Isograms-and-heterograms/EasyLang/isograms-and-heterograms.easy +++ b/Task/Isograms-and-heterograms/EasyLang/isograms-and-heterograms.easy @@ -1,9 +1,7 @@ repeat s$ = input until s$ = "" - if len s$ > 1 - w$[] &= s$ - . + if len s$ > 1 : w$[] &= s$ . func[] letters w$ . len r[] 127 @@ -14,18 +12,14 @@ func[] letters w$ . return r[] . func cmp a b a$ b$ . - if a > b - return 1 - elif a = b - if len a$ > len b$ - return 1 - elif len a$ = len b$ and strcmp a$ b$ < 0 - return 1 - . + if a > b : return 1 + if a = b + if len a$ > len b$ : return 1 + if len a$ = len b$ and strcmp a$ b$ < 0 : return 1 . return 0 . -proc sort . d$[] d[] . +proc sort &d$[] &d[] . n = len d$[] for i = 1 to n - 1 for j = i + 1 to n @@ -36,14 +30,12 @@ proc sort . d$[] d[] . . . . -proc isograms . . +proc isograms . for w$ in w$[] cnt[] = letters w$ n = 0 for i to 127 - if cnt[i] = 1 - break 1 - . + if cnt[i] = 1 : break 1 if cnt[i] > 0 if n = 0 n = cnt[i] @@ -58,18 +50,14 @@ proc isograms . . . . sort r$[] n[] - for w$ in r$[] - print w$ - . + for w$ in r$[] : print w$ . -proc heterogram lng . . +proc heterogram lng . for w$ in w$[] if len w$ > lng cnt[] = letters w$ for i to 127 - if cnt[i] > 0 and cnt[i] <> 1 - break 1 - . + if cnt[i] > 0 and cnt[i] <> 1 : break 1 . if i > 127 r$[] &= w$ @@ -78,9 +66,7 @@ proc heterogram lng . . . . sort r$[] n[] - for w$ in r$[] - print w$ - . + for w$ in r$[] : print w$ . isograms print "" diff --git a/Task/Isqrt-integer-square-root-of-X/JavaScript/isqrt-integer-square-root-of-x.js b/Task/Isqrt-integer-square-root-of-X/JavaScript/isqrt-integer-square-root-of-x.js new file mode 100644 index 0000000000..c7e8fd19d3 --- /dev/null +++ b/Task/Isqrt-integer-square-root-of-X/JavaScript/isqrt-integer-square-root-of-x.js @@ -0,0 +1,36 @@ +function isqrt(x) { + let q = 1n; + while (q <= x) { + q *= 4n; + } + + let z = x; + let r = 0n; + + while (q > 1) { + q /= 4n; + let t = z - r - q; + r /= 2n; + + if (t >= 0) { + z = t; + r += q; + } + } + return r; +} + +const items = []; +for (let n = 0; n < 66; n++) { + items.push(isqrt(BigInt(n))); +} + +console.log(items.join(" ")); + +const items2 = []; + +for (let n = 1n; n < 204n; n+= 2n) { + items2.push(`${Intl.NumberFormat().format(isqrt(7n ** n))} = isqrt(7^${n})`); +} + +console.log(items2.join('\n')); diff --git a/Task/Isqrt-integer-square-root-of-X/REXX/isqrt-integer-square-root-of-x.rexx b/Task/Isqrt-integer-square-root-of-X/REXX/isqrt-integer-square-root-of-x.rexx index b311025c50..29fcc4a72c 100644 --- a/Task/Isqrt-integer-square-root-of-X/REXX/isqrt-integer-square-root-of-x.rexx +++ b/Task/Isqrt-integer-square-root-of-X/REXX/isqrt-integer-square-root-of-x.rexx @@ -1,46 +1,125 @@ -/*REXX program computes and displays the Isqrt (integer square root) of some integers.*/ -numeric digits 200 /*insure 'nuff decimal digs for results*/ -parse arg range power base . /*obtain optional arguments from the CL*/ -if range=='' | range=="," then range= 0..65 /*Not specified? Then use the default.*/ -if power=='' | power=="," then power= 1..73 /* " " " " " " */ -if base =='' | base =="," then base = 7 /* " " " " " " */ -parse var range rLO '..' rHI; if rHI=='' then rHI= rLO /*handle a range? */ -parse var power pLO '..' pHI; if pHI=='' then pHI= pLO /* " " " */ -$= - do j=rLO to rHI while rHI>0 /*compute Isqrt for a range of integers*/ - $= $ commas( Isqrt(j) ) /*append the Isqrt to a list for output*/ - end /*j*/ -$= strip($) /*elide the leading blank in the list. */ -say center(' Isqrt for numbers: ' rLO " ──► " rHI' ', length($), "─") -say strip($) /*$ has a leading blank for 1st number*/ -say -z= base ** pHI /*compute max. exponentiation product.*/ -Lp= max(30, length( commas( z) ) ) /*length of " " " */ -Lr= max(20, length( commas( Isqrt(z) ) ) ) /* " " " " " Isqrt of above.*/ -say 'index' center(base"**index", Lp) center('Isqrt', Lr) /*show a title.*/ -say '─────' copies("─", Lp) copies('─', Lr) /* " " header*/ +-- 8 May 2025 +Main: +include Settings - do j=pLO to pHI by 2 while pHI>0; x= base ** j - say center(j, 5) right( commas(x), Lp) right( commas( Isqrt(x) ), Lr) - end /*j*/ /* [↑] show a bunch of powers & Isqrt.*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Isqrt: procedure; parse arg x /*obtain the only passed argument X. */ - x= x % 1 /*convert possible real X to an integer*/ /* ◄■■■■■■■ optional. */ - q= 1 /*initialize the Q variable to unity.*/ - do until q>x /*find a Q that is greater than X. */ - q= q * 4 /*multiply Q by four. */ - end /*until*/ - r= 0 /*R: will be the integer sqrt of X. */ - do while q>1 /*keep processing while Q is > than 1*/ - q= q % 4 /*divide Q by four (no remainder). */ - t= x - r - q /*compute a temporary variable. */ - r= r % 2 /*divide R by two (no remainder). */ - if t >= 0 then do /*if T is non─negative ... */ - x= t /*recompute the value of X */ - r= r + q /* " " " " R */ - end - end /*while*/ - return r /*return the integer square root of X. */ +say 'ISQRT (INTEGER SQUARE ROOT)' +say version +say +call Task1 65 +call Task2 1,2,73,'Q' +call Task2 123,1,123,'Q' +call Task2 123,1,123,'I' +call Task2 123,1,123,'F' +call Task2 1234,1,1234,'Q' +call Task2 1234,1,1234,'I' +call Task2 1234,1,1234,'F' +call Task2 12345,1,12345,'Q' +call Task2 12345,1,12345,'I' +call Task2 12345,1,12345,'F' +exit + +Task1: +procedure +arg xx +call time('r') +say 'Integer square root for n = 0...'xx +do n = 0 to xx + call Charout ,QuadraticResidue(n)' ' +end +say +call Timer +return + +Task2: +procedure +arg xx,yy,zz,mm +call Time('r') +select + when mm = 'Q' then + t = 'Quadratic residue' + when mm = 'I' then + t = 'Integer division' + when mm = 'F' then + t = 'Floating square root' +end +say Right('n',5) Left('7^n',40) Left('Isqrt(7^n) using' t,60) +numeric digits zz +do n = xx by yy to zz + p = 7**n+0 + pl = Length(p) + select + when mm = 'Q' then + r = QuadraticResidue(p) + when mm = 'I' then + r = WikiPedia(p) + when mm = 'F' then + r = Std(Floor(Sqrt(p))/1) + end + rl = Length(r) + if pl > 20 then + p = Left(p,10)'...'Right(p,10) '['pl 'digits]' + else + p = p '['pl 'digits]' + if rl > 20 then + r = Left(r,10)'...'Right(r,10) '['rl 'digits]' + else + r = r '['rl 'digits]' + say Right(n,5) Left(p,40) Left(r,40) +end +call Timer +return + +QuadraticResidue: +procedure +arg xx +-- First power of 4 > x +q = 1 +do until q > xx + q = q*4 +end +-- Iterate back to 1 using integer division +zz = 0 +do while q > 1 + q = q%4; t = xx-zz-q; zz = zz%2 + if t >= 0 then do + xx = t; zz = zz+q + end +end +return zz + +WikiPedia: +procedure +arg xx +-- Reduce argument to 1...100 +e = Xpon(xx)%2; a = -2*e; a = xx'E'a +-- First guess and undo reduce +select + when a < 4 then + zz = 2'E'e + when a < 9 then + zz = 3'E'e + when a < 16 then + zz = 4'E'e + when a < 25 then + zz = 5'E'e + when a < 36 then + zz = 6'E'e + when a < 49 then + zz = 7'E'e + when a < 64 then + zz = 8'E'e + when a < 81 then + zz = 9'E'e + otherwise + zz = 10'E'e +end +-- Loop by integer division +z = (zz+xx%zz)%2 +do while z < zz + zz = z; z = (zz+xx%zz)%2 +end +return zz + +include Functions +include Helper +include Abend diff --git a/Task/Jacobi-symbol/EasyLang/jacobi-symbol.easy b/Task/Jacobi-symbol/EasyLang/jacobi-symbol.easy index cbfd3707d9..2e96c70109 100644 --- a/Task/Jacobi-symbol/EasyLang/jacobi-symbol.easy +++ b/Task/Jacobi-symbol/EasyLang/jacobi-symbol.easy @@ -5,28 +5,20 @@ func jacobi a n . while a mod 2 = 0 a /= 2 nn = n mod 8 - if nn = 3 or nn = 5 - res = -res - . + if nn = 3 or nn = 5 : res = -res . swap a n - if a mod 4 = 3 and n mod 4 = 3 - res = -res - . + if a mod 4 = 3 and n mod 4 = 3 : res = -res a = a mod n . - if n = 1 - return res - . + if n = 1 : return res return 0 . print " n/a 0 1 2 3 4 5 6 7 8 9" print " ---------------------------------" -numfmt 2 3 +numfmt 3 2 for n = 1 step 2 to 17 write n & " " - for a = 0 to 9 - write jacobi a n - . + for a = 0 to 9 : write jacobi a n print "" . diff --git a/Task/Jacobi-symbol/JavaScript/jacobi-symbol.js b/Task/Jacobi-symbol/JavaScript/jacobi-symbol.js new file mode 100644 index 0000000000..ad566e6dbe --- /dev/null +++ b/Task/Jacobi-symbol/JavaScript/jacobi-symbol.js @@ -0,0 +1,52 @@ +function jacobi(n, k) { + if (k <= 0 || k % 2 !== 1) { + throw new Error("k must be positive and odd"); + } + n %= k; + let t = 1; + while (n !== 0) { + while (n % 2 === 0) { + n /= 2; + const r = k % 8; + if (r === 3 || r === 5) { + t = -t; + } + } + [n, k] = [k, n]; // Swap n and k + if (n % 4 === 3 && k % 4 === 3) { + t = -t; + } + n %= k; + } + return k === 1 ? t : 0; +} + +function print_table(out, kmax, nmax) { + let header = "n\\k|"; + for (let k = 0; k <= kmax; ++k) { + header += " " + k.toString().padStart(2, ' '); + } + out.push(header); + + let separator = "----"; + for (let k = 0; k <= kmax; ++k) { + separator += "---"; + } + out.push(separator); + + for (let n = 1; n <= nmax; n += 2) { + let row = n.toString().padStart(2, ' ') + " |"; + for (let k = 0; k <= kmax; ++k) { + row += " " + jacobi(k, n).toString().padStart(2, ' '); + } + out.push(row); + } +} + +function main() { + const output = []; + print_table(output, 20, 21); + output.forEach(line => console.log(line)); +} + +main(); diff --git a/Task/Jaro-Winkler-distance/EasyLang/jaro-winkler-distance.easy b/Task/Jaro-Winkler-distance/EasyLang/jaro-winkler-distance.easy index 5337f2435e..a00f8e8e35 100644 --- a/Task/Jaro-Winkler-distance/EasyLang/jaro-winkler-distance.easy +++ b/Task/Jaro-Winkler-distance/EasyLang/jaro-winkler-distance.easy @@ -4,16 +4,12 @@ repeat words$[] &= s$ . func distance s1$ s2$ . - if len s1$ < len s2$ - swap s1$ s2$ - . + if len s1$ < len s2$ : swap s1$ s2$ s1$[] = strchars s1$ s2$[] = strchars s2$ len1 = len s1$[] len2 = len s2$[] - if len2 = 0 - return 0 - . + if len2 = 0 : return 0 delta = higher 0 (len1 div 2 - 1) len flag[] len2 for i to len1 @@ -27,11 +23,9 @@ func distance s1$ s2$ . . . . - m = len c1_match$[] - if m = 0 - return 1 - . i = 0 + m = len c1_match$[] + if m = 0 : return 1 for j to len2 if flag[j] = 1 i += 1 @@ -44,17 +38,15 @@ func distance s1$ s2$ . . return 1 - (jaro + comprefix * 0.1 * (1 - jaro)) . -proc sort . d[] d$[] . - for i = len d[] - 1 downto 1 - for j = 1 to i - if d[j] > d[j + 1] - swap d[j] d[j + 1] - swap d$[j] d$[j + 1] - . +proc sort &d[] &d$[] . + for i = len d[] - 1 downto 1 : for j = 1 to i + if d[j] > d[j + 1] + swap d[j] d[j + 1] + swap d$[j] d$[j + 1] . . . -proc closewords s$ maxdist . r$[] r[] . +proc closewords s$ maxdist &r$[] &r[] . r[] = [ ] r$[] = [ ] for w$ in words$[] @@ -69,9 +61,7 @@ proc closewords s$ maxdist . r$[] r[] . for s$ in [ "accomodate" "definately" "goverment" "occured" "publically" "recieve" "seperate" "untill" "wich" ] print s$ & " ->" closewords s$ 0.15 r$[] r[] - for i to lower 5 len r$[] - print r[i] & " " & r$[i] - . + for i to lower 5 len r$[] : print r[i] & " " & r$[i] print "" . # the content of unixdict.txt diff --git a/Task/Jensens-Device/M2000-Interpreter/jensens-device-1.m2000 b/Task/Jensens-Device/M2000-Interpreter/jensens-device-1.m2000 index 69bec218bc..607df6e793 100644 --- a/Task/Jensens-Device/M2000-Interpreter/jensens-device-1.m2000 +++ b/Task/Jensens-Device/M2000-Interpreter/jensens-device-1.m2000 @@ -1,8 +1,8 @@ Module Jensen`s_Device { - Def double i + double i=0 Report Lazy$(1/i) ' display the definition of the lazy function Function Sum (&i, lo, hi, &f()) { - def double temp + double temp=0 For i= lo to hi { temp+=f() } diff --git a/Task/Jensens-Device/M2000-Interpreter/jensens-device-2.m2000 b/Task/Jensens-Device/M2000-Interpreter/jensens-device-2.m2000 index c64df3b2cc..d803e70e80 100644 --- a/Task/Jensens-Device/M2000-Interpreter/jensens-device-2.m2000 +++ b/Task/Jensens-Device/M2000-Interpreter/jensens-device-2.m2000 @@ -1,7 +1,7 @@ Module Jensen`s_Device { - Def decimal i + decimal i=0 Function Sum (&any, lo, hi, &f()) { - def decimal temp + decimal temp=0 For any= lo to hi { temp+=f() } diff --git a/Task/Jensens-Device/M2000-Interpreter/jensens-device-3.m2000 b/Task/Jensens-Device/M2000-Interpreter/jensens-device-3.m2000 index a38409fe64..50758b2707 100644 --- a/Task/Jensens-Device/M2000-Interpreter/jensens-device-3.m2000 +++ b/Task/Jensens-Device/M2000-Interpreter/jensens-device-3.m2000 @@ -1,7 +1,7 @@ Module Jensen`s_Device { - Def single i + single i=0 Function Sum (&any, lo, hi, &f()) { - def single temp + single temp=0 For any= lo to hi { temp+=f() } diff --git a/Task/Jordan-P-lya-numbers/EasyLang/jordan-p-lya-numbers.easy b/Task/Jordan-P-lya-numbers/EasyLang/jordan-p-lya-numbers.easy index 11890bc255..6e9f6533b1 100644 --- a/Task/Jordan-P-lya-numbers/EasyLang/jordan-p-lya-numbers.easy +++ b/Task/Jordan-P-lya-numbers/EasyLang/jordan-p-lya-numbers.easy @@ -11,9 +11,7 @@ fastfunc jpnum m . repeat q = n div fac if n mod fac = 0 - if q = 1 - return 1 - . + if q = 1 : return 1 n = q else fac = fac / i @@ -22,13 +20,11 @@ fastfunc jpnum m . until i = 1 . limite -= 1 - if limite = 0 - return 0 - . + if limite = 0 : return 0 n = m . . -numfmt 0 5 +numfmt 5 0 write 1 c = 1 n = 2 @@ -37,9 +33,7 @@ repeat c += 1 if c <= 50 write n - if c mod 8 = 0 - print "" - . + if c mod 8 = 0 : print "" . sn = n . diff --git a/Task/JortSort/EasyLang/jortsort.easy b/Task/JortSort/EasyLang/jortsort.easy index eff2004f35..931ef807e7 100644 --- a/Task/JortSort/EasyLang/jortsort.easy +++ b/Task/JortSort/EasyLang/jortsort.easy @@ -1,10 +1,6 @@ -proc sort . d[] . - for i = 1 to len d[] - 1 - for j = i + 1 to len d[] - if d[j] < d[i] - swap d[j] d[i] - . - . +proc sort &d[] . + for i = 1 to len d[] - 1 : for j = i + 1 to len d[] + if d[j] < d[i] : swap d[j] d[i] . . func jortsort arr[] . diff --git a/Task/Juggler-sequence/FreeBASIC/juggler-sequence.basic b/Task/Juggler-sequence/FreeBASIC/juggler-sequence.basic new file mode 100644 index 0000000000..7105fa171b --- /dev/null +++ b/Task/Juggler-sequence/FreeBASIC/juggler-sequence.basic @@ -0,0 +1,87 @@ +#include "big_int/big_integer.bi" + +Type JugglerResult + length As Integer ' Sequence length + maxVal As BigInt ' Maximum value + maxIdx As Integer ' Index where maximum occurs +End Type + +Function BigIntSqrt(Byref n As BigInt) As BigInt + If n = 0 Then Return 0 + + Dim As BigInt x = n + Dim As BigInt y = (x + 1) \ 2 + While y < x + x = y + y = (x + n \ x) \ 2 + Wend + + Return x +End Function + +Function BigIntToStr(Byref n As BigInt) As String + If n = 0 Then Return "0" + + Dim As String result + Dim As BigInt tmp = n + Dim As BigInt ten = 10 + Dim As BigInt digit + + While tmp <> 0 + digit = tmp Mod 10 + result = Chr(Cint(digit) + Asc("0")) & result + tmp \= 10 + Wend + + Return result +End Function + +Function Juggler(n As Uinteger) As JugglerResult + Dim As JugglerResult result + Dim As BigInt a = n + + result.length = 0 + result.maxVal = a + result.maxIdx = 0 + + While a <> 1 + If (a Mod 2) = 0 Then + ' Even: floor(sqrt(a)) + a = BigIntSqrt(a) + Else + ' Odd: floor(a^(3/2)) = floor(sqrt(a³)) + Dim As BigInt a_cubed = a * a * a + a = BigIntSqrt(a_cubed) + End If + + result.length += 1 + + If a > result.maxVal Then + result.maxVal = a + result.maxIdx = result.length + End If + Wend + + Return result +End Function + +' Main program +Print "n l[n] h[n] i[n]" +Print String(31, "-") + +For n As Integer = 20 To 39 + Dim As JugglerResult result = Juggler(n) + Dim As String maxValStr = BigIntToStr(result.maxVal) + + Print Using "## ## "; n; result.length; + + If Len(maxValStr) < 14 Then + Print Space(14 - Len(maxValStr)); maxValStr; + Else + Print maxValStr; + End If + + Print Using " ##"; result.maxIdx +Next + +Sleep diff --git a/Task/Julia-set/EasyLang/julia-set.easy b/Task/Julia-set/EasyLang/julia-set.easy index 9a1fe358c3..44a8af429b 100644 --- a/Task/Julia-set/EasyLang/julia-set.easy +++ b/Task/Julia-set/EasyLang/julia-set.easy @@ -1,20 +1,17 @@ cx = -0.7 cy = 0.27015 -for y = 0 to 299 - for x = 0 to 299 - zx = (x - 150) / 100 - zy = (y - 150) / 150 - color3 0 0 0 - for iter = 0 to 127 - if zx * zx + zy * zy > 4 - color3 iter / 16 0 0 - break 1 - . - h = zx * zx - zy * zy + cx - zy = 2 * zx * zy + cy - zx = h +for y = 0 to 299 : for x = 0 to 299 + zx = (x - 150) / 100 + zy = (y - 150) / 150 + gcolor3 0 0 0 + for iter = 0 to 127 + if zx * zx + zy * zy > 4 + gcolor3 iter / 16 0 0 + break 1 . - move x / 3 y / 3 - rect 0.4 0.4 + h = zx * zx - zy * zy + cx + zy = 2 * zx * zy + cy + zx = h . + grect x / 3 y / 3 0.4 0.4 . diff --git a/Task/K-d-tree/C-sharp/k-d-tree.cs b/Task/K-d-tree/C-sharp/k-d-tree.cs new file mode 100644 index 0000000000..a757b7689c --- /dev/null +++ b/Task/K-d-tree/C-sharp/k-d-tree.cs @@ -0,0 +1,472 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; // For StringBuilder in Point.ToString + +//----------------------------------------------------------------------------- +// Point Struct +//----------------------------------------------------------------------------- + +/// +/// Represents a point in N-dimensional space. +/// TCoord must be a numeric type supporting comparison and conversion. +/// +/// The numeric type for coordinates (e.g., int, double, float). +public readonly struct Point : IEquatable> + where TCoord : struct, IComparable, IConvertible // Constraints for numeric operations & sorting +{ + private readonly TCoord[] _coords; + public int Dimensions { get; } + + /// + /// Initializes a new point with the specified coordinates. + /// The number of coordinates determines the dimension. + /// + /// The coordinates for the point. + /// Thrown if coords is null. + /// Thrown if coords is empty. + public Point(params TCoord[] coords) + { + if (coords == null) + throw new ArgumentNullException(nameof(coords)); + if (coords.Length == 0) + throw new ArgumentException("Coordinates cannot be empty.", nameof(coords)); + + _coords = (TCoord[])coords.Clone(); // Defensive copy + Dimensions = _coords.Length; + } + + /// + /// Initializes a new point by copying coordinates from an enumerable. + /// + /// The coordinates for the point. + /// Thrown if coords is null. + /// Thrown if coords results in an empty collection. + public Point(IEnumerable coords) + { + if (coords == null) + throw new ArgumentNullException(nameof(coords)); + + _coords = coords.ToArray(); + if (_coords.Length == 0) + throw new ArgumentException("Coordinates cannot be empty.", nameof(coords)); + + Dimensions = _coords.Length; + } + + + /// + /// Gets the coordinate value in the specified dimension. + /// + /// Dimension index (zero-based). + /// The coordinate value. + /// Thrown if index is out of bounds. + public TCoord Get(int index) + { + // Rely on array's built-in bounds checking for performance + // if (index < 0 || index >= Dimensions) + // throw new IndexOutOfRangeException($"Index {index} is out of range for dimension {Dimensions}."); + return _coords[index]; + } + + /// + /// Calculates the squared Euclidean distance between this point and another point. + /// + /// The other point. + /// The squared distance. + /// Thrown if points have different dimensions. + public double DistanceSquared(Point other) + { + if (Dimensions != other.Dimensions) + throw new ArgumentException("Points must have the same dimensions."); + + double distSq = 0; + for (int i = 0; i < Dimensions; ++i) + { + // Convert coordinates to double for calculation. + // This is a common approach when TCoord isn't guaranteed to be double. + // Using System.Numerics.INumber in .NET 7+ would allow direct arithmetic. + double d = Convert.ToDouble(Get(i)) - Convert.ToDouble(other.Get(i)); + distSq += d * d; + } + return distSq; + } + + /// + /// Returns a string representation of the point (e.g., "(1, 2, 3)"). + /// + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append('('); + for (int i = 0; i < Dimensions; ++i) + { + if (i > 0) + sb.Append(", "); + sb.Append(_coords[i]); + } + sb.Append(')'); + return sb.ToString(); + } + + // --- Equality Members --- + public bool Equals(Point other) + { + if (Dimensions != other.Dimensions) + return false; + // Using SequenceEqual for robust array comparison + return _coords.SequenceEqual(other._coords); + } + + public override bool Equals(object obj) + { + return obj is Point other && Equals(other); + } + + public override int GetHashCode() + { + int hashCode = Dimensions.GetHashCode(); + if (_coords != null) + { + foreach (var coord in _coords) + { + // Simple hash combining approach + hashCode = HashCode.Combine(hashCode, coord.GetHashCode()); + } + } + return hashCode; + } + + public static bool operator ==(Point left, Point right) + { + return left.Equals(right); + } + + public static bool operator !=(Point left, Point right) + { + return !(left == right); + } +} + + +//----------------------------------------------------------------------------- +// KdTree Class +//----------------------------------------------------------------------------- + +/// +/// C# k-d tree implementation for fast nearest neighbor searches. +/// +/// The numeric type for coordinates. +public class KdTree + where TCoord : struct, IComparable, IConvertible +{ + // Internal Node class + private class Node + { + public Point Point { get; } + public Node Left { get; set; } // Using properties with private setters if needed, or public fields + public Node Right { get; set; } + + public Node(Point point) + { + Point = point; + Left = null; + Right = null; + } + + // Helper to access coordinate for sorting/comparison + public TCoord Get(int index) => Point.Get(index); + + // Helper for distance calculation + public double DistanceSquared(Point pt) => Point.DistanceSquared(pt); + } + + // --- Fields --- + private readonly Node[] _nodes; // Store nodes contiguously for potential cache benefits + private readonly Node _root; + private readonly int _dimensions; + + // State for the nearest neighbor search + private Node _bestNode = null; + private double _bestDistSq = double.MaxValue; + private int _visitedCount = 0; + + + // --- Comparer for Sorting Nodes --- + private class NodeComparer : IComparer + { + private readonly int _dimensionIndex; + + public NodeComparer(int dimensionIndex) + { + _dimensionIndex = dimensionIndex; + } + + public int Compare(Node x, Node y) + { + // Comparison relies on the IComparable constraint + return x.Get(_dimensionIndex).CompareTo(y.Get(_dimensionIndex)); + } + } + + // --- Constructors --- + + /// + /// Builds a k-d tree from a collection of points. + /// + /// The points to add to the tree. + /// Thrown if points is null. + /// Thrown if points is empty or contains points with inconsistent dimensions. + public KdTree(IEnumerable> points) + { + if (points == null) throw new ArgumentNullException(nameof(points)); + + var pointList = points.ToList(); // Materialize the list + if (pointList.Count == 0) throw new ArgumentException("Point collection cannot be empty.", nameof(points)); + + _dimensions = pointList[0].Dimensions; + _nodes = new Node[pointList.Count]; + + for (int i = 0; i < pointList.Count; i++) + { + if (pointList[i].Dimensions != _dimensions) + throw new ArgumentException($"All points must have the same dimension ({_dimensions}). Point {i} has dimension {pointList[i].Dimensions}.", nameof(points)); + _nodes[i] = new Node(pointList[i]); + } + + _root = MakeTree(0, _nodes.Length, 0); + } + + /// + /// Builds a k-d tree by generating points using a function. + /// + /// A function that returns a Point. + /// The number of points to generate. + /// Thrown if pointGenerator is null. + /// Thrown if count is zero or negative. + /// Thrown if the generator produces points with inconsistent dimensions. + public KdTree(Func> pointGenerator, int count) + { + if (pointGenerator == null) throw new ArgumentNullException(nameof(pointGenerator)); + if (count <= 0) throw new ArgumentOutOfRangeException(nameof(count), "Count must be positive."); + + _nodes = new Node[count]; + Point firstPoint = pointGenerator(); + _dimensions = firstPoint.Dimensions; + _nodes[0] = new Node(firstPoint); + + for (int i = 1; i < count; i++) + { + Point p = pointGenerator(); + if (p.Dimensions != _dimensions) + throw new InvalidOperationException($"Generated points must have consistent dimensions ({_dimensions}). Point {i} has dimension {p.Dimensions}."); + _nodes[i] = new Node(p); + } + + _root = MakeTree(0, _nodes.Length, 0); + } + + + // --- Tree Building Method --- + private Node MakeTree(int begin, int end, int index) + { + if (end <= begin) + return null; // Base case: empty range + + // Calculate median index + int n = begin + (end - begin) / 2; + + // Sort the segment [begin, end) based on the current dimension 'index' + // This partitions the array around the median element at index 'n' + // Array.Sort sorts the range [begin, begin + length), so length is end - begin + Array.Sort(_nodes, begin, end - begin, new NodeComparer(index)); + + // Median element becomes the current node + Node currentNode = _nodes[n]; + + // Cycle to the next dimension for children + int nextIndex = (index + 1) % _dimensions; + + // Recursively build left and right subtrees + currentNode.Left = MakeTree(begin, n, nextIndex); + currentNode.Right = MakeTree(n + 1, end, nextIndex); + + return currentNode; + } + + // --- Public API --- + + /// + /// Gets the number of dimensions for points in this tree. + /// + public int Dimensions => _dimensions; + + /// + /// Returns true if the tree is empty. + /// + public bool IsEmpty => _nodes.Length == 0; + + /// + /// Returns the number of nodes visited during the last call to Nearest. + /// + public int Visited => _visitedCount; + + /// + /// Returns the squared distance between the query point and the nearest point found by the last call to Nearest. + /// Returns double.PositiveInfinity if Nearest hasn't been called or the tree is empty. + /// + public double DistanceSquared => _bestNode != null ? _bestDistSq : double.PositiveInfinity; + + /// + /// Returns the Euclidean distance between the query point and the nearest point found by the last call to Nearest. + /// Returns double.PositiveInfinity if Nearest hasn't been called or the tree is empty. + /// + public double Distance => _bestNode != null ? Math.Sqrt(_bestDistSq) : double.PositiveInfinity; + + + /// + /// Finds the nearest point in the tree to the given point. + /// + /// The query point. + /// The nearest point found in the tree. + /// Thrown if the tree is empty. + /// Thrown if the query point has different dimensions than the tree. + public Point Nearest(Point point) + { + if (_root == null) + throw new InvalidOperationException("Cannot search an empty tree."); + if (point.Dimensions != _dimensions) + throw new ArgumentException($"Query point dimension ({point.Dimensions}) must match tree dimension ({_dimensions})."); + + // Reset search state + _bestNode = null; + _bestDistSq = double.MaxValue; // Use MaxValue for initial comparison + _visitedCount = 0; + + // Start recursive search + Nearest(_root, point, 0); + + // _bestNode should not be null if _root wasn't null + return _bestNode.Point; + } + + // --- Recursive Nearest Neighbor Search --- + private void Nearest(Node node, Point point, int index) + { + if (node == null) + return; + + _visitedCount++; + + double dSq = node.DistanceSquared(point); + + // If this node is better than the current best, update best + if (_bestNode == null || dSq < _bestDistSq) + { + _bestDistSq = dSq; + _bestNode = node; + } + + // Perfect match found, can stop (early exit) + if (_bestDistSq == 0) + return; + + // Determine difference along the splitting dimension + // Convert coordinates to double for the difference calculation + double dx = Convert.ToDouble(node.Get(index)) - Convert.ToDouble(point.Get(index)); + + // Cycle dimension + int nextIndex = (index + 1) % _dimensions; + + // Decide which subtree to visit first (the one containing the point) + Node nearerNode = dx > 0 ? node.Left : node.Right; + Node furtherNode = dx > 0 ? node.Right : node.Left; + + // Search the nearer subtree first + Nearest(nearerNode, point, nextIndex); + + // Pruning: Check if the hypersphere crosses the splitting plane. + // If dx^2 >= bestDistSq, the other subtree cannot contain a closer point. + if (dx * dx >= _bestDistSq) + { + return; // Prune the further subtree + } + + // Hypersphere crosses the plane, search the further subtree + Nearest(furtherNode, point, nextIndex); + } +} + + +//----------------------------------------------------------------------------- +// Example Usage & Testing +//----------------------------------------------------------------------------- +public class Program +{ + static void TestWikipedia() + { + Console.WriteLine("Wikipedia example data:"); + var points = new Point[] { + new Point(2, 3), new Point(5, 4), new Point(9, 6), + new Point(4, 7), new Point(8, 1), new Point(7, 2) + }; + + var tree = new KdTree(points); + + var queryPoint = new Point(9, 2); + Point nearest = tree.Nearest(queryPoint); + + Console.WriteLine($"Query point: {queryPoint}"); + Console.WriteLine($"Nearest point: {nearest}"); + Console.WriteLine($"Distance: {tree.Distance:F6}"); // Format distance + Console.WriteLine($"Nodes visited: {tree.Visited}"); + Console.WriteLine("------------------------------------"); + } + + // Simple random point generator for 3D doubles + private static Random _random = new Random(); + public static Point RandomPointGenerator(double min, double max) + { + double range = max - min; + double x = min + _random.NextDouble() * range; + double y = min + _random.NextDouble() * range; + double z = min + _random.NextDouble() * range; + return new Point(x, y, z); + } + + static void TestRandom(int count) + { + Console.WriteLine($"Random data ({count} points):"); + + // Use the generator constructor + var tree = new KdTree(() => RandomPointGenerator(0, 1), count); + + // Generate a random query point + var queryPoint = RandomPointGenerator(0, 1); + Point nearest = tree.Nearest(queryPoint); + + Console.WriteLine($"Query point: {queryPoint}"); + Console.WriteLine($"Nearest point: {nearest}"); + Console.WriteLine($"Distance: {tree.Distance:F6}"); + Console.WriteLine($"Nodes visited: {tree.Visited}"); + Console.WriteLine("------------------------------------"); + } + + public static void Main(string[] args) + { + try + { + TestWikipedia(); + TestRandom(1000); + TestRandom(100000); // Reduced count for faster C# demo + // TestRandom(1000000); // Can take longer in C# due to sorting overhead vs nth_element + } + catch (Exception e) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.Error.WriteLine($"An error occurred: {e.Message}"); + Console.Error.WriteLine(e.StackTrace); + Console.ResetColor(); + } + } +} diff --git a/Task/K-d-tree/Dart/k-d-tree.dart b/Task/K-d-tree/Dart/k-d-tree.dart new file mode 100644 index 0000000000..b3d1451c28 --- /dev/null +++ b/Task/K-d-tree/Dart/k-d-tree.dart @@ -0,0 +1,220 @@ +import 'dart:math'; + +// Define Point as a list of doubles +typedef Point = List; + +// Extension method for calculating squared distance +extension PointExtension on Point { + double sqd(Point p) { + if (length != p.length) { + throw ArgumentError('Points must have the same dimension'); + } + double sum = 0.0; + for (int i = 0; i < length; i++) { + double diff = this[i] - p[i]; + sum += diff * diff; + } + return sum; + } +} + +class HyperRect { + final Point min; + final Point max; + + HyperRect(this.min, this.max); + + // Create a copy with new lists for min and max + HyperRect copy() => HyperRect(List.from(min), List.from(max)); +} + +class NearestNeighbor { + final Point? nearest; // Nullable Point + final double distSqd; + final int nodesVisited; + + NearestNeighbor(this.nearest, this.distSqd, this.nodesVisited); +} + +class KdNode { + final Point domElt; + final int split; + KdNode? left; // Nullable and mutable + KdNode? right; // Nullable and mutable + + KdNode(this.domElt, this.split, this.left, this.right); +} + +class KdTree { + final KdNode? n; // Root node (nullable) + final HyperRect bounds; + + // Constructor builds the tree + KdTree(List pts, this.bounds) + : n = _buildTree( + List.from(pts), + 0, + ); // Pass a copy to avoid modifying original + + // Static helper method for recursive tree building (like nk2) + static KdNode? _buildTree(List exset, int split) { + if (exset.isEmpty) { + return null; + } + + // Sort the list in-place based on the current split dimension + exset.sort((a, b) => a[split].compareTo(b[split])); + + int m = exset.length ~/ 2; // Integer division + final Point d = exset[m]; + + // Handle duplicate points at the median split value + // Find the last index of the element equal to the median along the split dimension + while (m + 1 < exset.length && exset[m + 1][split] == d[split]) { + m++; + } + + int s2 = split + 1; + if (s2 == d.length) { + s2 = 0; // Cycle through dimensions + } + + // Dart's sublist creates copies, which is suitable here + List leftSublist = exset.sublist(0, m); + List rightSublist = exset.sublist(m + 1); + + return KdNode( + d, + split, + _buildTree(leftSublist, s2), + _buildTree(rightSublist, s2), + ); + } + + // Public method to find the nearest neighbor + NearestNeighbor nearest(Point p) { + // Pass a copy of bounds because _nn might modify its HyperRect parameter + return _nn(n, p, bounds.copy(), double.infinity); + } + + // Private recursive helper for nearest neighbor search + NearestNeighbor _nn( + KdNode? kd, // Current node (nullable) + Point target, // Target point + HyperRect hr, // Hyper-rectangle for the current node's space + double maxDistSqd, // Current best squared distance found so far + ) { + if (kd == null) { + return NearestNeighbor(null, double.infinity, 0); + } + + int nodesVisited = 1; + final int s = kd.split; + final Point pivot = kd.domElt; + + // Create copies for left and right potential subspaces + final HyperRect leftHr = hr.copy(); + final HyperRect rightHr = hr.copy(); + + // Adjust bounds for children + leftHr.max[s] = pivot[s]; + rightHr.min[s] = pivot[s]; + + // Determine which branch is nearer + final bool targetInLeft = target[s] <= pivot[s]; + final KdNode? nearerKd = targetInLeft ? kd.left : kd.right; + final HyperRect nearerHr = targetInLeft ? leftHr : rightHr; + final KdNode? furtherKd = targetInLeft ? kd.right : kd.left; + final HyperRect furtherHr = targetInLeft ? rightHr : leftHr; + + // Recurse down the nearer branch + NearestNeighbor nearerResult = _nn(nearerKd, target, nearerHr, maxDistSqd); + Point? nearest = nearerResult.nearest; + double distSqd = nearerResult.distSqd; + nodesVisited += nearerResult.nodesVisited; + + // Update the maximum distance squared if a closer point was found + double maxDistSqd2 = (distSqd < maxDistSqd) ? distSqd : maxDistSqd; + + // Check the distance from the target to the splitting plane + double d = pivot[s] - target[s]; + d *= d; + + // If the splitting plane is further than the current nearest, no need to check further branch + if (d > maxDistSqd2) { + return NearestNeighbor(nearest, distSqd, nodesVisited); + } + + // Check distance from target to the pivot point itself + d = pivot.sqd(target); // Use extension method + if (d < distSqd) { + nearest = pivot; + distSqd = d; + maxDistSqd2 = distSqd; // Update max distance again + } + + // Recurse down the further branch if necessary + NearestNeighbor furtherResult = _nn( + furtherKd, + target, + furtherHr, + maxDistSqd2, + ); + nodesVisited += furtherResult.nodesVisited; + + // If the further branch found an even closer point + if (furtherResult.distSqd < distSqd) { + nearest = furtherResult.nearest; + distSqd = furtherResult.distSqd; + } + + return NearestNeighbor(nearest, distSqd, nodesVisited); + } +} + +// --- Helper Functions and Main --- + +final rand = Random(); + +Point randomPt(int dim) => List.generate(dim, (_) => rand.nextDouble()); + +List randomPts(int dim, int n) => List.generate(n, (_) => randomPt(dim)); + +void showNearest(String heading, KdTree kd, Point p) { + print('$heading:'); + print('Point : $p'); // Default List.toString() is fine + final result = kd.nearest(p); + print('Nearest neighbor : ${result.nearest}'); + print( + 'Distance : ${sqrt(result.distSqd)}', + ); // Use sqrt from dart:math + print('Nodes visited : ${result.nodesVisited}'); + print(''); // Empty line +} + +void main() { + // Note: Using List instead of MutableList + final points = [ + [2.0, 3.0], + [5.0, 4.0], + [9.0, 6.0], + [4.0, 7.0], + [8.0, 1.0], + [7.0, 2.0], + ]; + + var hr = HyperRect([0.0, 0.0], [10.0, 10.0]); + var kd = KdTree(points, hr); // Pass the original list + showNearest('WP example data', kd, [9.0, 2.0]); + + hr = HyperRect([0.0, 0.0, 0.0], [1.0, 1.0, 1.0]); + // Generate random points directly as List + kd = KdTree(randomPts(3, 1000), hr); + showNearest('1000 random 3D points', kd, randomPt(3)); + + // Use hr.copy() if you intend to modify hr later, otherwise it's not strictly needed + // The Kotlin code uses copy, so we replicate it here. + var hrCopy = hr.copy(); + kd = KdTree(randomPts(3, 400000), hrCopy); // Pass the copy + showNearest('400,000 random 3D points', kd, randomPt(3)); +} diff --git a/Task/K-d-tree/JavaScript/k-d-tree.js b/Task/K-d-tree/JavaScript/k-d-tree.js new file mode 100644 index 0000000000..fd28a1f18f --- /dev/null +++ b/Task/K-d-tree/JavaScript/k-d-tree.js @@ -0,0 +1,235 @@ +/** + * Class for representing a point. coordinate_type must be a numeric type. + */ +class Point { + constructor(coords) { + if (Array.isArray(coords)) { + this.coords = [...coords]; + } else if (coords instanceof Object) { + this.coords = Array.from(coords); + } + } + + /** + * Returns the coordinate in the given dimension. + * + * @param {number} index dimension index (zero based) + * @return {number} coordinate in the given dimension + */ + get(index) { + return this.coords[index]; + } + + /** + * Returns the distance squared from this point to another point. + * + * @param {Point} pt another point + * @return {number} distance squared from this point to the other point + */ + distance(pt) { + let dist = 0; + for (let i = 0; i < this.coords.length; ++i) { + const d = this.get(i) - pt.get(i); + dist += d * d; + } + return dist; + } + + toString() { + return `(${this.coords.join(', ')})`; + } +} + +/** + * JavaScript k-d tree implementation, based on the C++ version. + */ +class KDTree { + constructor(pointsOrGenerator, count) { + this.nodes = []; + this.dimensions = 0; + this.root = null; + this.best = null; + this.bestDist = 0; + this.visited = 0; + + if (typeof pointsOrGenerator === 'function' && typeof count === 'number') { + // Constructor with generator function + for (let i = 0; i < count; ++i) { + const point = pointsOrGenerator(); + if (i === 0) { + this.dimensions = point.coords.length; + } + this.nodes.push({ point, left: null, right: null }); + } + } else if (Array.isArray(pointsOrGenerator)) { + // Constructor with array of points + this.nodes = pointsOrGenerator.map(point => ({ point, left: null, right: null })); + if (this.nodes.length > 0) { + this.dimensions = this.nodes[0].point.coords.length; + } + } + + if (this.nodes.length > 0) { + this.root = this.makeTree(0, this.nodes.length, 0); + } + } + + /** + * Comparison function for sorting nodes by a specific dimension + */ + nodeCmp(a, b, index) { + return a.point.get(index) - b.point.get(index); + } + + /** + * Builds the tree recursively + */ + makeTree(begin, end, index) { + if (end <= begin) return null; + + const n = begin + Math.floor((end - begin) / 2); + + // Sort and find median + this.nodes.slice(begin, end).sort((a, b) => this.nodeCmp(a, b, index)); + + // Update index for the next level + const nextIndex = (index + 1) % this.dimensions; + + // Recursively build left and right subtrees + this.nodes[n].left = this.makeTree(begin, n, nextIndex); + this.nodes[n].right = this.makeTree(n + 1, end, nextIndex); + + return this.nodes[n]; + } + + /** + * Recursively finds the nearest node to the given point + */ + findNearest(root, point, index) { + if (!root) return; + + this.visited++; + const d = root.point.distance(point); + + if (!this.best || d < this.bestDist) { + this.bestDist = d; + this.best = root; + } + + if (this.bestDist === 0) return; + + const dx = root.point.get(index) - point.get(index); + const nextIndex = (index + 1) % this.dimensions; + + // Search the side of the splitting plane that contains the point + this.findNearest(dx > 0 ? root.left : root.right, point, nextIndex); + + // If the distance to the splitting plane is less than current best distance, + // we need to check the other side too + if (dx * dx >= this.bestDist) return; + + this.findNearest(dx > 0 ? root.right : root.left, point, nextIndex); + } + + /** + * Returns true if the tree is empty, false otherwise. + */ + empty() { + return this.nodes.length === 0; + } + + /** + * Returns the number of nodes visited by the last call to nearest(). + */ + getVisited() { + return this.visited; + } + + /** + * Returns the distance between the input point and return value + * from the last call to nearest(). + */ + getDistance() { + return Math.sqrt(this.bestDist); + } + + /** + * Finds the nearest point in the tree to the given point. + * It is not valid to call this function if the tree is empty. + * + * @param {Point} point a point + * @return {Point} the nearest point in the tree to the given point + */ + nearest(point) { + if (!this.root) { + throw new Error("Tree is empty"); + } + + this.best = null; + this.visited = 0; + this.bestDist = 0; + + this.findNearest(this.root, point, 0); + + return this.best.point; + } +} + +/** + * Recreates the Wikipedia example from the original code + */ +function testWikipedia() { + const points = [ + new Point([2, 3]), + new Point([5, 4]), + new Point([9, 6]), + new Point([4, 7]), + new Point([8, 1]), + new Point([7, 2]) + ]; + + const tree = new KDTree(points); + const searchPoint = new Point([9, 2]); + const nearest = tree.nearest(searchPoint); + + console.log("Wikipedia example data:"); + console.log("nearest point:", nearest.toString()); + console.log("distance:", tree.getDistance()); + console.log("nodes visited:", tree.getVisited()); +} + +/** + * Generates random points and finds the nearest neighbor + */ +function randomPointGenerator(min, max) { + return () => { + const x = min + Math.random() * (max - min); + const y = min + Math.random() * (max - min); + const z = min + Math.random() * (max - min); + return new Point([x, y, z]); + }; +} + +function testRandom(count) { + const rpg = randomPointGenerator(0, 1); + const tree = new KDTree(rpg, count); + const point = rpg(); + const nearest = tree.nearest(point); + + console.log(`Random data (${count} points):`); + console.log("point:", point.toString()); + console.log("nearest point:", nearest.toString()); + console.log("distance:", tree.getDistance()); + console.log("nodes visited:", tree.getVisited()); +} + +// Main execution +try { + testWikipedia(); + console.log(); + testRandom(1000); + console.log(); + testRandom(10000); // Using 10,000 instead of 1,000,000 for browser performance +} catch (e) { + console.error(e.message); +} diff --git a/Task/Kernighans-large-earthquake-problem/ALGOL-68/kernighans-large-earthquake-problem.alg b/Task/Kernighans-large-earthquake-problem/ALGOL-68/kernighans-large-earthquake-problem.alg index c1f9ddbb06..58658e9467 100644 --- a/Task/Kernighans-large-earthquake-problem/ALGOL-68/kernighans-large-earthquake-problem.alg +++ b/Task/Kernighans-large-earthquake-problem/ALGOL-68/kernighans-large-earthquake-problem.alg @@ -37,7 +37,8 @@ BEGIN # Kernighan's large earthquake problem - show lines from data.txt that # TRUE END ); - get( real value, ( result ) ) + get( real value, ( result ) ); + close( real value ) FI; result END # real field # ; diff --git a/Task/Kernighans-large-earthquake-problem/R/kernighans-large-earthquake-problem.r b/Task/Kernighans-large-earthquake-problem/R/kernighans-large-earthquake-problem.r new file mode 100644 index 0000000000..5d35645609 --- /dev/null +++ b/Task/Kernighans-large-earthquake-problem/R/kernighans-large-earthquake-problem.r @@ -0,0 +1,2 @@ +earthquakes <- read.table("data.txt", col.names=c("date", "name", "magnitude")) +subset(earthquakes, magnitude>6) diff --git a/Task/Keyboard-input-Flush-the-keyboard-buffer/Emacs-Lisp/keyboard-input-flush-the-keyboard-buffer.l b/Task/Keyboard-input-Flush-the-keyboard-buffer/Emacs-Lisp/keyboard-input-flush-the-keyboard-buffer.l new file mode 100644 index 0000000000..191e125091 --- /dev/null +++ b/Task/Keyboard-input-Flush-the-keyboard-buffer/Emacs-Lisp/keyboard-input-flush-the-keyboard-buffer.l @@ -0,0 +1 @@ +(discard-input) diff --git a/Task/Keyboard-input-Keypress-check/EasyLang/keyboard-input-keypress-check.easy b/Task/Keyboard-input-Keypress-check/EasyLang/keyboard-input-keypress-check.easy index fd54accdda..943a45880f 100644 --- a/Task/Keyboard-input-Keypress-check/EasyLang/keyboard-input-keypress-check.easy +++ b/Task/Keyboard-input-Keypress-check/EasyLang/keyboard-input-keypress-check.easy @@ -1,6 +1,5 @@ on key - clear - move 10 80 + gclear k$ = keybkey - text k$ + gtext 10 80 k$ . diff --git a/Task/Keyboard-input-Keypress-check/Emacs-Lisp/keyboard-input-keypress-check.l b/Task/Keyboard-input-Keypress-check/Emacs-Lisp/keyboard-input-keypress-check.l new file mode 100644 index 0000000000..d7752bc10d --- /dev/null +++ b/Task/Keyboard-input-Keypress-check/Emacs-Lisp/keyboard-input-keypress-check.l @@ -0,0 +1,21 @@ +(defun store-keypress () + "If a key has been pressed, store it as a variable. +Note that the variable created is a variable inside the scope of let and +will not be available as a variable outside the scope of let. However, +the function also returns the value of the variable, which can be used +outside the scope of let." + (let ((keypress)) + (if (input-pending-p) + (setq keypress (char-to-string (read-key)))))) + + +(defun store-keypress-multiple () + "If one or more keys have been pressed, store it/them as a variable. +Note that the variable created is a variable inside the scope of let and +will not be available as a variable outside the scope of let. However, +the function also returns the value of the variable, which can be used +outside the scope of let." + (let ((keypress)) + (while (input-pending-p) + (push (read-key) keypress)) + (setq keypress (concat (nreverse keypress))))) diff --git a/Task/Keyboard-input-Obtain-a-Y-or-N-response/EasyLang/keyboard-input-obtain-a-y-or-n-response.easy b/Task/Keyboard-input-Obtain-a-Y-or-N-response/EasyLang/keyboard-input-obtain-a-y-or-n-response.easy index ee2a05a539..7447fa013d 100644 --- a/Task/Keyboard-input-Obtain-a-Y-or-N-response/EasyLang/keyboard-input-obtain-a-y-or-n-response.easy +++ b/Task/Keyboard-input-Obtain-a-Y-or-N-response/EasyLang/keyboard-input-obtain-a-y-or-n-response.easy @@ -1,12 +1,10 @@ -move 10 80 -text "Press y or n" +gtext 10 80 "Press y or n" repeat sleep -1 ans$ = keybkey until ans$ = "y" or ans$ = "n" . -move 10 70 -text "-> " & ans$ +gtext 10 70 "-> " & ans$ # on key # diff --git a/Task/Keyboard-input-Obtain-a-Y-or-N-response/Emacs-Lisp/keyboard-input-obtain-a-y-or-n-response.l b/Task/Keyboard-input-Obtain-a-Y-or-N-response/Emacs-Lisp/keyboard-input-obtain-a-y-or-n-response.l new file mode 100644 index 0000000000..332abb1ffb --- /dev/null +++ b/Task/Keyboard-input-Obtain-a-Y-or-N-response/Emacs-Lisp/keyboard-input-obtain-a-y-or-n-response.l @@ -0,0 +1,5 @@ +(defun get-happiness () + "Asks for y or n response about happiness. +Returns t if happy; nil otherwise." + (discard-input) + (y-or-n-p "Are you happy?")) diff --git a/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-1.tcl b/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-1.tcl index ff75776be1..cf1c6cb11d 100644 --- a/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-1.tcl +++ b/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-1.tcl @@ -1,17 +1,31 @@ -proc yesno {{message "Press Y or N to continue"}} { - fconfigure stdin -blocking 0 - exec stty raw - read stdin ; # flush - puts -nonewline "${message}: " - flush stdout - while {![eof stdin]} { - set c [string tolower [read stdin 1]] - if {$c eq "y" || $c eq "n"} break +proc ask_yn {prompt} { + + puts "${prompt} ?" + set answer "" + set valid 0 + + while {! $valid} { + + gets stdin answer + + switch -nocase -glob $answer { + Y* { set valid 1; set answer Y } + N* { set valid 1; set answer N } + default {} + } + + if {!$valid} {puts "Choose either Y or N"} } - puts [string toupper $c] - exec stty -raw - fconfigure stdin -blocking 1 - return [expr {$c eq "y"}] + + return [expr $answer == Y] } -set yn [yesno "Do you like programming (Y/N)"] +set prompt "Is this correct? (Y/N)" + +set ans [ask_yn $prompt] + +if {$ans} { + puts "answer was Yes" +} else { + puts "answer was No" +} diff --git a/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-2.tcl b/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-2.tcl index e2f5af5829..ff75776be1 100644 --- a/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-2.tcl +++ b/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-2.tcl @@ -1,11 +1,17 @@ -proc yesno {message} { - toplevel .msg - pack [label .msg.l -text "$message\n (type Y/N)?"] - set ::yn "" - bind .msg {set ::yn "Y"} - bind .msg {set ::yn "N"} - vwait ::yn - destroy .msg +proc yesno {{message "Press Y or N to continue"}} { + fconfigure stdin -blocking 0 + exec stty raw + read stdin ; # flush + puts -nonewline "${message}: " + flush stdout + while {![eof stdin]} { + set c [string tolower [read stdin 1]] + if {$c eq "y" || $c eq "n"} break + } + puts [string toupper $c] + exec stty -raw + fconfigure stdin -blocking 1 + return [expr {$c eq "y"}] } -yesno "Do you like programming?" +set yn [yesno "Do you like programming (Y/N)"] diff --git a/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-3.tcl b/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-3.tcl new file mode 100644 index 0000000000..e2f5af5829 --- /dev/null +++ b/Task/Keyboard-input-Obtain-a-Y-or-N-response/Tcl/keyboard-input-obtain-a-y-or-n-response-3.tcl @@ -0,0 +1,11 @@ +proc yesno {message} { + toplevel .msg + pack [label .msg.l -text "$message\n (type Y/N)?"] + set ::yn "" + bind .msg {set ::yn "Y"} + bind .msg {set ::yn "N"} + vwait ::yn + destroy .msg +} + +yesno "Do you like programming?" diff --git a/Task/Knapsack-problem-0-1/EasyLang/knapsack-problem-0-1.easy b/Task/Knapsack-problem-0-1/EasyLang/knapsack-problem-0-1.easy index 0aa199a5a9..1fa0d21cb4 100644 --- a/Task/Knapsack-problem-0-1/EasyLang/knapsack-problem-0-1.easy +++ b/Task/Knapsack-problem-0-1/EasyLang/knapsack-problem-0-1.easy @@ -3,7 +3,7 @@ weight[] = [ 9 13 153 50 15 68 27 39 23 52 11 32 24 48 73 42 43 22 7 18 4 30 ] value[] = [ 150 35 200 160 60 45 60 40 30 10 70 30 15 10 40 70 75 80 20 12 50 10 ] max_w = 400 # -proc solve i maxw . items[] wres vres . +proc solve i maxw &items[] &wres &vres . if i = 0 wres = 0 vres = 0 @@ -24,6 +24,4 @@ proc solve i maxw . items[] wres vres . solve len weight[] max_w items[] w v print "weight: " & w & " value: " & v write "items:" -for item in items[] - write " " & name$[item] -. +for item in items[] : write " " & name$[item] diff --git a/Task/Knapsack-problem-Bounded/EasyLang/knapsack-problem-bounded.easy b/Task/Knapsack-problem-Bounded/EasyLang/knapsack-problem-bounded.easy index 90d510ec33..7baddc0633 100644 --- a/Task/Knapsack-problem-Bounded/EasyLang/knapsack-problem-bounded.easy +++ b/Task/Knapsack-problem-Bounded/EasyLang/knapsack-problem-bounded.easy @@ -6,7 +6,7 @@ maxweight = 400 # global valuesum[] maxv . # -proc solve i maxw v . items[] wres vres . +proc solve i maxw v &items[] &wres &vres . if i = 0 wres = 0 vres = 0 @@ -31,13 +31,11 @@ proc solve i maxw v . items[] wres vres . . . . -proc prepare . . - for i to len weight[] - for j to pieces[i] - n$[] &= name$[i] - w[] &= weight[i] - v[] &= value[i] - . +proc prepare . + for i to len weight[] : for j to pieces[i] + n$[] &= name$[i] + w[] &= weight[i] + v[] &= value[i] . swap name$[] n$[] swap weight[] w[] @@ -63,6 +61,4 @@ prepare solve len weight[] maxweight 0 items[] wsum vsum print "weight: " & wsum & " value: " & vsum print "items:" -for item in items[] - print " " & name$[item] -. +for item in items[] : print " " & name$[item] diff --git a/Task/Knapsack-problem-Continuous/Nim/knapsack-problem-continuous.nim b/Task/Knapsack-problem-Continuous/Nim/knapsack-problem-continuous.nim index f6e6f55e2b..84ead213cd 100644 --- a/Task/Knapsack-problem-Continuous/Nim/knapsack-problem-continuous.nim +++ b/Task/Knapsack-problem-Continuous/Nim/knapsack-problem-continuous.nim @@ -17,7 +17,7 @@ var items = @[Item(name: "beef", weight: 3.8, price: 36.0), Item(name: "salami", weight: 3.0, price: 95.0), Item(name: "sausage", weight: 5.9, price: 98.0) ] - ] + # Compute unit prices and sort items by decreasing unit price. for item in items.mitems: item.unitPrice = item.price / item.weight diff --git a/Task/Knapsack-problem-Unbounded/EasyLang/knapsack-problem-unbounded.easy b/Task/Knapsack-problem-Unbounded/EasyLang/knapsack-problem-unbounded.easy index 05c334295d..c87883db00 100644 --- a/Task/Knapsack-problem-Unbounded/EasyLang/knapsack-problem-unbounded.easy +++ b/Task/Knapsack-problem-Unbounded/EasyLang/knapsack-problem-unbounded.easy @@ -9,7 +9,7 @@ n = len names$[] len cnt[] n global best[] bestval . # -proc knapsack i val wgt vol . . +proc knapsack i val wgt vol . if i > n if val > bestval bestval = val diff --git a/Task/Knights-tour/EasyLang/knights-tour.easy b/Task/Knights-tour/EasyLang/knights-tour.easy index 18803ed091..e6511f1a37 100644 --- a/Task/Knights-tour/EasyLang/knights-tour.easy +++ b/Task/Knights-tour/EasyLang/knights-tour.easy @@ -11,23 +11,19 @@ func cntmoves m[] . . return n . -proc sortmoves . m[][] . +proc sortmoves &m[][] . for i = 1 to len m[][] cnt[] &= cntmoves m[i][] . - for i = 1 to len cnt[] - 1 - for j = i + 1 to len cnt[] - if cnt[j] < cnt[i] - swap cnt[j] cnt[i] - swap m[j][] m[i][] - . + for i = 1 to len cnt[] - 1 : for j = i + 1 to len cnt[] + if cnt[j] < cnt[i] + swap cnt[j] cnt[i] + swap m[j][] m[i][] . . . func solve r c cnt . - if cnt > size * size - return 1 - . + if cnt > size * size : return 1 movs[][] = [ ] for d = 1 to len dirs[][] rn = r + dirs[d][1] @@ -41,29 +37,21 @@ func solve r c cnt . rn = movs[i][1] cn = movs[i][2] brd[rn][cn] = cnt - if solve rn cn (cnt + 1) = 1 - return 1 - . + if solve rn cn (cnt + 1) = 1 : return 1 brd[rn][cn] = 0 . return 0 . -proc prepare . . +proc prepare . brd[][] = [ ] len brd[][] size - for r to size - len brd[r][] size - . + for r to size : len brd[r][] size . -proc printbrd . . - numfmt 0 3 - if size > 10 - numfmt 0 4 - . +proc printbrd . + numfmt 3 0 + if size > 10 : numfmt 4 0 for r to size - for c to size - write brd[r][c] - . + for c to size : write brd[r][c] print "" . . @@ -80,33 +68,25 @@ else print "no solutions found: (" & r0 & " " & c0 & ")" . # -proc showgraf . . +proc showgraf . sc = 100 / size - linewidth sc / 15 + glinewidth sc / 15 col[] = [ 777 333 ] - for r = 0 to size - 1 - for c = 0 to size - 1 - color col[(r + c) mod1 2] - move sc * c sc * r - rect sc sc - . + for r = 0 to size - 1 : for c = 0 to size - 1 + gcolor col[(r + c) mod1 2] + grect sc * c sc * r sc sc . - move 0 / 0 0 for i to size * size - for r = 1 to size - for c = 1 to size - if brd[r][c] = i - color 600 - x = c * sc - sc / 2 - y = r * sc - sc / 2 - line x y - color 880 - circle sc / 10 - . - . + for r = 1 to size : for c = 1 to size : if brd[r][c] = i + gcolor 600 + x = c * sc - sc / 2 + y = r * sc - sc / 2 + if i > 1 : gline xp yp x y + xp = x + yp = y + gcolor 880 + gcircle x y sc / 10 . . . -if found = 1 - showgraf -. +if found = 1 : showgraf diff --git a/Task/Knuth-shuffle/EasyLang/knuth-shuffle.easy b/Task/Knuth-shuffle/EasyLang/knuth-shuffle.easy index ea070c7fe5..d764abb8d7 100644 --- a/Task/Knuth-shuffle/EasyLang/knuth-shuffle.easy +++ b/Task/Knuth-shuffle/EasyLang/knuth-shuffle.easy @@ -1,4 +1,4 @@ -proc shuffle . a[] . +proc shuffle &a[] . for i = len a[] downto 2 r = random i swap a[r] a[i] diff --git a/Task/Knuth-shuffle/Objeck/knuth-shuffle.objeck b/Task/Knuth-shuffle/Objeck/knuth-shuffle.objeck new file mode 100644 index 0000000000..8c086185c6 --- /dev/null +++ b/Task/Knuth-shuffle/Objeck/knuth-shuffle.objeck @@ -0,0 +1,21 @@ +# version for array of references +function : Shuffle (array : Base[]) ~ Nil { + n := array->Size(); + while(n > 1) { + k := Int->Random(n--); //decrements after using the value + temp := array[n]; + array[n] := array[k]; + array[k] := temp; + } +} + +# version for array of ints +function : Shuffle (array : Int[]) ~ Nil { + n := array->Size(); + while(n > 1) { + k := Int->Random(n--); # decrements after using the value + temp := array[n]; + array[n] := array[k]; + array[k] := temp; + }; +} diff --git a/Task/Knuth-shuffle/Wisp/knuth-shuffle.wisp b/Task/Knuth-shuffle/Wisp/knuth-shuffle.wisp new file mode 100644 index 0000000000..e700dbc1ca --- /dev/null +++ b/Task/Knuth-shuffle/Wisp/knuth-shuffle.wisp @@ -0,0 +1,30 @@ +import : only (srfi :27 random-bits) random-integer + srfi :64 tests + +define : vector-shuffle! vec + . "Shuffle the vector VEC with Knuth shuffle" + define len : vector-length vec + define : swap! i j + define tmp : vector-ref vec i + vector-set! vec i : vector-ref vec j + vector-set! vec j tmp + cond + : <= len 1 + . vec + else + for-each : λ (i) : swap! i : random-integer i + reverse : cdr : iota len + . vec + +define : list-shuffle the-list + . "Shuffle a list in O(N) with Knuth shuffle using an intermediate vector." + vector->list : vector-shuffle! : list->vector the-list + +;; deterministic tests +test-begin "knuth-shuffle" +test-equal '() : list-shuffle '() +test-equal '(1) : list-shuffle '(1) +test-end +;; sample run +display : list-shuffle '(1 2 3 4) +newline diff --git a/Task/Knuths-algorithm-S/Fortran/knuths-algorithm-s.f b/Task/Knuths-algorithm-S/Fortran/knuths-algorithm-s.f new file mode 100644 index 0000000000..af81b50898 --- /dev/null +++ b/Task/Knuths-algorithm-S/Fortran/knuths-algorithm-s.f @@ -0,0 +1,121 @@ +module knuth_s + implicit none + private + public :: s_of_n_creator, free_sample, sample_state, s_of_n + + ! Type to hold sample state + type :: sample_state + integer :: n + integer :: count + integer, allocatable :: sample(:) + end type sample_state + +contains + + ! Subroutine to create the s_of_n sampling function + subroutine s_of_n_creator(n, state) + integer, intent(in) :: n + type(sample_state), pointer :: state + + allocate (state) + state % n = n + state % count = 0 + allocate (state % sample(n)) + end subroutine s_of_n_creator + + ! Function to perform sampling + function s_of_n(state, item) result(current_sample) + type(sample_state), pointer :: state + integer, intent(in) :: item + integer, pointer :: current_sample(:) + real :: r + integer :: j + + ! Add item to sample if we haven't reached n yet + if (state % count < state % n) then + state % count = state % count + 1 + state % sample(state % count) = item + else + ! Knuth's Algorithm S: select with probability n/i + call random_number(r) + if (r < real(state % n) / real(state % count + 1)) then + ! Randomly replace one of the existing items + call random_number(r) + j = int(r * state % n) + 1 + state % sample(j) = item + end if + state % count = state % count + 1 + end if + current_sample => state % sample + end function s_of_n + + ! Cleanup function to deallocate sample state + subroutine free_sample(state) + type(sample_state), pointer :: state + deallocate (state % sample) + deallocate (state) + end subroutine free_sample + +end module knuth_s + +program test_knuth_s + use knuth_s + implicit none + type(sample_state), pointer :: state + integer, pointer :: sample(:) + integer :: i, j, k, reps + integer :: frequencies(0:9) + character(len=50) :: sample_str + integer :: n, timex(8) + integer, allocatable :: seed(:) + call random_seed(size=n) + allocate (seed(n)) + call date_and_time(values=timex) + seed(1) = timex(5) * 3600000 + timex(6) * 60000 + timex(7) * 1000 + timex(8) + do i = 2, n + seed(i) = seed(1) + 37 * (i - 1) + end do + ! Initialize random seed + call random_seed(put=seed) + + ! Show one run's sampling progression + print *, 'Single run samples for n = 3:' + call s_of_n_creator(3, state) + do i = 0, 9 + sample => s_of_n(state, i) + ! Format sample output + sample_str = '' + write (sample_str, '("[", *(I0, ", "))') sample(1:min(state % count, 3)) + if (state % count > 0) then + sample_str = trim(sample_str) + sample_str = sample_str(1:len_trim(sample_str) - 1)//']' + else + sample_str = '[]' + end if + print '(A, I0, A, A)', ' Item: ', i, ' -> sample: ', trim(sample_str) + end do + call free_sample(state) + + ! Initialize frequency counter + frequencies = 0 + + ! Run 100,000 repetitions to count final sample frequencies + reps = 100000 + do i = 1, reps + call s_of_n_creator(3, state) + do j = 0, 9 + sample => s_of_n(state, j) + end do + ! Count frequencies from final sample + do k = 1, 3 + frequencies(sample(k)) = frequencies(sample(k)) + 1 + end do + call free_sample(state) + end do + + ! Print frequency results + print *, 'Test item frequencies for ', reps, ' runs:' + do i = 0, 9 + print '(I2, ": ", I5)', i, frequencies(i) + end do +end program test_knuth_s diff --git a/Task/Knuths-algorithm-S/FreeBASIC/knuths-algorithm-s.basic b/Task/Knuths-algorithm-S/FreeBASIC/knuths-algorithm-s.basic new file mode 100644 index 0000000000..d81ad506c3 --- /dev/null +++ b/Task/Knuths-algorithm-S/FreeBASIC/knuths-algorithm-s.basic @@ -0,0 +1,98 @@ +Type SampleState + sample(0 To 99) As Integer ' Array to store the sample (arbitrary maximum size) + sampleSize As Integer ' Current sample size + i As Integer ' Counter of processed elements + n As Integer ' Desired sample size +End Type + +' Function to generate a random number between 0 and max-1 +Function randInt(Byval max As Integer) As Integer + Return Int(Rnd() * max) +End Function + +' Function to create a new sampler +Function createSampler(Byval n As Integer) As SampleState + Dim sampler As SampleState + sampler.sampleSize = 0 + sampler.i = 0 + sampler.n = n + Return sampler +End Function + +' Function to process a new element and update the sample +Function sampleOfN(Byref sampler As SampleState, Byval item As Integer) As Integer Ptr + sampler.i += 1 + + If sampler.i <= sampler.n Then + sampler.sample(sampler.sampleSize) = item + sampler.sampleSize += 1 + Else + If randInt(sampler.i) < sampler.n Then + sampler.sample(randInt(sampler.n)) = item + End If + End If + + Return @sampler.sample(0) +End Function + +Sub printArray(arr() As Integer, Byval size As Integer) + Print "[" + For i As Integer = 0 To size-1 + Print arr(i) + If i < size-1 Then Print ", " + Next + Print "]" +End Sub + +Sub main() + Dim As Integer i, j + + Dim As Integer frequency(0 To 9) + For i = 0 To 9 + frequency(i) = 0 + Next + + Print "Single run samples for n = 3:" + + Dim As SampleState sampler = createSampler(3) + Dim As Integer Ptr samplePtr + Dim As Integer sample(0 To 2) + + For i = 0 To 9 + samplePtr = sampleOfN(sampler, i) + + For j = 0 To sampler.sampleSize-1 + sample(j) = samplePtr[j] + Next + + Print " Item: " & i & " -> sample: "; + Print "[ "; + For j = 0 To sampler.sampleSize-1 + Print Chr(8) & sample(j); + If j < sampler.sampleSize-1 Then Print ", "; + Next + Print "]" + Next + + For i = 0 To 99999 + sampler = createSampler(3) + + For j = 0 To 9 + samplePtr = sampleOfN(sampler, j) + Next + + For j = 0 To sampler.n-1 + frequency(samplePtr[j]) += 1 + Next + Next + + Print !"\nTest item frequencies for 100000 runs:" + For i = 0 To 9 + Print " " & i & ": " & frequency(i) + Next +End Sub + +Randomize Timer +main() + +Sleep diff --git a/Task/Knuths-algorithm-S/JavaScript/knuths-algorithm-s.js b/Task/Knuths-algorithm-S/JavaScript/knuths-algorithm-s.js new file mode 100644 index 0000000000..e1e6db258e --- /dev/null +++ b/Task/Knuths-algorithm-S/JavaScript/knuths-algorithm-s.js @@ -0,0 +1,36 @@ +class SOfN { + constructor(n) { + this.m = this.n = n + this.s = [] + } + + add(item) { + if (this.s.length < this.n) { + this.s.push(item) + } else { + const rand = Math.floor(Math.random() * ++this.m) + if (rand < this.n) { + this.s[rand] = item + } + } + } +} + +function main() { + for (const [n, m] of [[3, 3], [3, 10]]) { + const freqs = new Array(m).fill(0) + + for (let i = 0; i < 1e5; ++i) { + const sOfN = new SOfN(n) + for (let x = 0; x < m; ++x) { + sOfN.add(x) + } + for (const d of sOfN.s) { + ++freqs[d] + } + } + console.log(`Results for n=${n}, m=${m}: [${freqs.join(', ')}]`) + } +} + +main() diff --git a/Task/Knuths-power-tree/FreeBASIC/knuths-power-tree.basic b/Task/Knuths-power-tree/FreeBASIC/knuths-power-tree.basic new file mode 100644 index 0000000000..3c1132d308 --- /dev/null +++ b/Task/Knuths-power-tree/FreeBASIC/knuths-power-tree.basic @@ -0,0 +1,247 @@ +#include once "big_int\big_integer.bi" + +Const NULL As Any Ptr = 0 + +Type HashEntry + key As Integer + value As Integer + sgte As HashEntry Ptr +End Type + +Type HashMap + buckets(255) As HashEntry Ptr + + Declare Sub put(key As Integer, value As Integer) + Declare Function get(key As Integer, defaultValue As Integer = 0) As Integer + Declare Function contains(key As Integer) As Boolean +End Type + +Sub HashMap.put(key As Integer, value As Integer) + Dim As Integer bucket = key And 255 + Dim As HashEntry Ptr entry = buckets(bucket) + + ' Check if key already exists + While entry <> NULL + If entry->key = key Then + entry->value = value + Exit Sub + End If + entry = entry->sgte + Wend + + ' Create new entry + entry = New HashEntry + entry->key = key + entry->value = value + entry->sgte = buckets(bucket) + buckets(bucket) = entry +End Sub + +Function HashMap.get(key As Integer, defaultValue As Integer = 0) As Integer + Dim As Integer bucket = key And 255 + Dim As HashEntry Ptr entry = buckets(bucket) + + While entry <> NULL + If entry->key = key Then Return entry->value + entry = entry->sgte + Wend + + Return defaultValue +End Function + +Function HashMap.contains(key As Integer) As Boolean + Dim As Integer bucket = key And 255 + Dim As HashEntry Ptr entry = buckets(bucket) + + While entry <> NULL + If entry->key = key Then Return True + entry = entry->sgte + Wend + + Return False +End Function + +Type IntArray + dato As Integer Ptr + size As Integer + capacity As Integer + + Declare Sub add(value As Integer) + Declare Function get(index As Integer) As Integer + Declare Function getSize() As Integer + Declare Sub clear() +End Type + +Sub IntArray.add(value As Integer) + If size >= capacity Then + capacity = Iif(capacity = 0, 8, capacity * 2) + Dim As Integer Ptr newdato = New Integer[capacity] + If dato <> NULL Then + For i As Integer = 0 To size - 1 + newdato[i] = dato[i] + Next + Delete[] dato + End If + dato = newdato + End If + + dato[size] = value + size += 1 +End Sub + +Function IntArray.get(index As Integer) As Integer + If index >= 0 And index < size Then Return dato[index] + Return 0 +End Function + +Function IntArray.getSize() As Integer + Return size +End Function + +Sub IntArray.clear() + size = 0 +End Sub + +' Global variables +Dim Shared As HashMap p +Dim Shared As IntArray levels(0) ' Array of levels + +' Function to compute the path to n +Function path(n As Integer) As IntArray + Dim As Integer i, j, x, y, sum + Dim As IntArray result + + ' Base case + If n = 0 Then Return result + + ' Check if we already have a path to n + While Not p.contains(n) + Dim q As IntArray + + ' Process current level + For i = 0 To levels(0).getSize() - 1 + x = levels(0).get(i) + + ' Get path to x + Dim As IntArray xPath = path(x) + + ' Try to extend the path + For j = 0 To xPath.getSize() - 1 + y = xPath.get(j) + sum = x + y + + ' Check if we already have a path to sum + If p.contains(sum) Then Exit For + + ' Record the path + p.put(sum, x) + q.add(sum) + Next j + Next i + + ' Update level + levels(0).clear() + For i = 0 To q.getSize() - 1 + levels(0).add(q.get(i)) + Next i + + ' If we can't make progress, break + If q.getSize() = 0 Then Exit While + Wend + + ' Reconstruct the path + Dim As Integer curr = n + Dim As IntArray tempPath + + While curr <> 0 + tempPath.add(curr) + curr = p.get(curr) + Wend + + ' Reverse the path + For i = tempPath.getSize() - 1 To 0 Step -1 + result.add(tempPath.get(i)) + Next i + + Return result +End Function + +' Function to compute x^n using the tree method with BigInteger for integers +Function treePowBig(x As Integer, n As Integer) As BigInt + Dim As BigInt r(0 To n) + ' Initialize r[0] = 1 and r[1] = x + r(0) = 1 + r(1) = x + + Dim As Integer i, curr, p = 0 + Dim As IntArray pathToN = path(n) + + For i = 0 To pathToN.getSize() - 1 + curr = pathToN.get(i) + r(curr) = r(curr - p) * r(p) + p = curr + Next i + + Return r(n) +End Function + +' Function to compute x^n using the tree method with high precision for decimals +Function treePowDecimal(x As Double, n As Integer) As Double + Dim As Double r(0 To n) + ' Initialize r[0] = 1 and r[1] = x + r(0) = 1 + r(1) = x + + Dim As Integer i, curr, p = 0 + Dim As IntArray pathToN = path(n) + + For i = 0 To pathToN.getSize() - 1 + curr = pathToN.get(i) + r(curr) = r(curr - p) * r(p) + p = curr + Next i + + Return r(n) +End Function + +' Function to display the power calculation +Sub showPow(x As Double, n As Integer) + Dim As IntArray pathToN = path(n) + Dim As String pathStr = "" + + For i As Integer = 0 To pathToN.getSize() - 1 + If i > 0 Then pathStr &= ", " + pathStr &= Str(pathToN.get(i)) + Next i + + Print n & ": [" & pathStr & "]" + + If Int(x) = x And n > 20 Then + ' Use BigInt for large integer powers + Dim As BigInt result = treePowBig(Int(x), n) + Print x & "^" & n & " = " & result + Elseif Int(x) <> x Then + ' Use high precision for decimal numbers + Dim As Double result = treePowDecimal(x, n) + Print Using "##.#^## = ####.######"; x; n; result + Else + ' Use standard calculation for small integer powers + Dim As Double result = treePowDecimal(x, n) + Print Using "##^## = &"; Int(x); n; result + End If + Print +End Sub + +' Initialize +p.put(1, 0) +levels(0).add(1) + +' Main program +For i As Integer = 0 To 17 + showPow(2, i) +Next i + +showPow(1.1, 81) +showPow(3, 191) + +Sleep diff --git a/Task/Knuths-power-tree/JavaScript/knuths-power-tree.js b/Task/Knuths-power-tree/JavaScript/knuths-power-tree.js new file mode 100644 index 0000000000..87e6b3f255 --- /dev/null +++ b/Task/Knuths-power-tree/JavaScript/knuths-power-tree.js @@ -0,0 +1,103 @@ +class PowerTree { + static p = new Map(); + static lvl = []; + + static { + PowerTree.p.set(1, 0); + + let temp = [1]; + PowerTree.lvl.push(temp); + } + + static path(n) { + if (n === 0) return []; + while (!PowerTree.p.has(n)) { + let q = []; + for (let x of PowerTree.lvl[0]) { + for (let y of PowerTree.path(x)) { + if (PowerTree.p.has(x + y)) break; + PowerTree.p.set(x + y, x); + q.push(x + y); + } + } + PowerTree.lvl[0] = [...q]; // Important: create a new array! Otherwise, the original array is mutated. + } + let temp = PowerTree.path(PowerTree.p.get(n)); + temp.push(n); + return temp; + } + + static treePow(x, n) { + const r = new Map(); + r.set(0, 1n); // Changed to bigint for accurate integer results + r.set(1, BigInt(Math.round(x))); // Convert to BigInt + + + if (Number.isInteger(x) && Number.isInteger(n) && n>30){ + r.set(0, 1n); + r.set(1, BigInt(x)); + } else { + r.set(0, 1); + r.set(1, x); + } + + + let p = 0; + const path_result = PowerTree.path(n); + + for (let i of path_result) { + let a = r.get(i - p); + let b = r.get(p); + + if (Number.isInteger(x) && Number.isInteger(n) && n>30){ + r.set(i, a * b); + } else { + + if (typeof a === 'bigint' && typeof b === 'bigint'){ + r.set(i, Number(a) * Number(b)); + } else if (typeof a === 'bigint'){ + r.set(i, Number(a) * b); + } else if (typeof b === 'bigint'){ + r.set(i, a * Number(b)); + } else { + r.set(i, a * b); + } + } + + + p = i; + } + + if (Number.isInteger(x) && Number.isInteger(n) && n>30){ + return Number(r.get(n)); + } + return r.get(n); + } + + + static showPow(x, n, isIntegral) { + console.log(`${n}: ${PowerTree.path(n)}`); + let f = isIntegral ? "%.0f" : "%f"; + //console.log(f, x); // Javascript doesn't have printf-style formatting built in + + let formatted_x; + if (isIntegral) { + formatted_x = Math.round(x); + } else { + formatted_x = x.toFixed(6); // Or whatever precision you need. + } + + console.log(`${formatted_x} ^ ${n} = ${PowerTree.treePow(x, n)}`); + console.log("\n"); + } + + static main() { + for (let n = 0; n <= 17; ++n) { + PowerTree.showPow(2.0, n, true); + } + PowerTree.showPow(1.1, 81, false); + PowerTree.showPow(3.0, 191, true); + } +} + +PowerTree.main(); diff --git a/Task/Koch-curve/EasyLang/koch-curve.easy b/Task/Koch-curve/EasyLang/koch-curve.easy index ab72dbe553..81bdc0e0b6 100644 --- a/Task/Koch-curve/EasyLang/koch-curve.easy +++ b/Task/Koch-curve/EasyLang/koch-curve.easy @@ -1,4 +1,6 @@ -proc koch x1 y1 x2 y2 iter . . +xp = 0 / 0 +yp = xp +proc koch x1 y1 x2 y2 iter . x3 = (x1 * 2 + x2) / 3 y3 = (y1 * 2 + y2) / 3 x4 = (x1 + x2 * 2) / 3 @@ -12,17 +14,18 @@ proc koch x1 y1 x2 y2 iter . . koch x5 y5 x4 y4 iter koch x4 y4 x2 y2 iter else - line x1 y1 - line x3 y3 - line x5 y5 - line x4 y4 - line x2 y2 + if xp = xp : gline xp yp x1 y1 + gline x1 y1 x3 y3 + gline x3 y3 x3 y3 + gline x3 y3 x4 y4 + gline x4 y4 x2 y2 + xp = x2 + yp = y2 . . -linewidth 0.3 +glinewidth 0.3 x1 = 15 y1 = 30 -move x1 y1 for ang = 0 step 120 to 240 x2 = x1 + 70 * cos ang y2 = y1 + 70 * sin ang diff --git a/Task/Kosaraju/EasyLang/kosaraju.easy b/Task/Kosaraju/EasyLang/kosaraju.easy index d4b827640d..d64470a143 100644 --- a/Task/Kosaraju/EasyLang/kosaraju.easy +++ b/Task/Kosaraju/EasyLang/kosaraju.easy @@ -6,7 +6,7 @@ len vis[] gc len l[] gc x = gc len t[][] gc -proc visit u . . +proc visit u . if vis[u] = 0 vis[u] = 1 for v in g[u][] @@ -21,7 +21,7 @@ for i range0 gc visit i . len c[] gc -proc assign u root . . +proc assign u root . if vis[u] = 1 vis[u] = 0 c[u] = root diff --git a/Task/Kosaraju/Rust/kosaraju.rs b/Task/Kosaraju/Rust/kosaraju.rs new file mode 100644 index 0000000000..a6e0c5a6d4 --- /dev/null +++ b/Task/Kosaraju/Rust/kosaraju.rs @@ -0,0 +1,91 @@ +use std::fmt; + +// Define a wrapper struct for Vec +struct DisplayVec(Vec); + +impl DisplayVec { + fn new(vec: Vec) -> Self { + DisplayVec(vec) + } +} + + +// Implement the Display trait for the wrapper struct +impl fmt::Display for DisplayVec { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "[")?; + if let Some((first, rest)) = self.0.split_first() { + write!(f, "{}", first)?; + for elem in rest { + write!(f, ", {}", elem)?; + } + } + write!(f, "]") + } +} + +fn kosaraju(g: &mut Vec>) -> Vec { + let size = g.len(); + let mut vis = vec![false; size]; // all false by default + let mut l = vec![0; size]; // all zero by default + let mut x = size; // index for filling l in reverse order + let mut t = vec![vec![]; size]; // transpose graph + + // Recursive subroutine 'visit': + fn visit(u: usize, g: &Vec>, vis: &mut Vec, l: &mut Vec, x: &mut usize, t: &mut Vec>) { + if !vis[u] { + vis[u] = true; + for &v in &g[u] { + visit(v, g, vis, l, x, t); + t[v].push(u); // construct transpose + } + *x -= 1; + l[*x] = u; + } + } + + // 2. For each vertex u of the graph do visit(u) + for i in 0..g.len() { + visit(i, g, &mut vis, &mut l, &mut x, &mut t); + } + + let mut c = vec![0; size]; // used for component assignment + vis = vec![true; size]; //repurpose vis to mean 'unassigned' + + // Recursive subroutine 'assign': + fn assign(u: usize, root: usize, t: &Vec>, vis: &mut Vec, c: &mut Vec) { + if vis[u] { + vis[u] = false; + c[u] = root; + for &v in &t[u] { + assign(v, root, t, vis, c); + } + } + } + + // 3: For each element u of l in order, do assign(u, u) + for &u in &l { + if vis[u] { + assign(u, u, &t, &mut vis, &mut c); + } + + } + + c +} + +fn main() { + let mut g = vec![ + vec![1], + vec![2], + vec![0], + vec![1, 2, 4], + vec![3, 5], + vec![2, 6], + vec![5], + vec![4, 6, 7], + ]; + + let result = kosaraju(&mut g); + println!("{}", DisplayVec::new(result)); +} diff --git a/Task/Kronecker-product-based-fractals/EasyLang/kronecker-product-based-fractals.easy b/Task/Kronecker-product-based-fractals/EasyLang/kronecker-product-based-fractals.easy index 30c4fe6ab0..afa47b441f 100644 --- a/Task/Kronecker-product-based-fractals/EasyLang/kronecker-product-based-fractals.easy +++ b/Task/Kronecker-product-based-fractals/EasyLang/kronecker-product-based-fractals.easy @@ -18,17 +18,16 @@ func[][] krpow a[][] n . . return r[][] . -proc show p[][] . . - clear +proc show p[][] . + gclear n = len p[][] sc = 100 / n for r to n for c to n x = (c - 1) * sc y = (r - 1) * sc - move x y if p[r][c] = 1 - rect sc sc + grect x y sc sc . . . diff --git a/Task/Langtons-ant/EasyLang/langtons-ant.easy b/Task/Langtons-ant/EasyLang/langtons-ant.easy index 24011e0fa8..eefb6c822c 100644 --- a/Task/Langtons-ant/EasyLang/langtons-ant.easy +++ b/Task/Langtons-ant/EasyLang/langtons-ant.easy @@ -1,15 +1,12 @@ len f[] 100 * 100 -proc show . . - for y = 0 to 99 - for x = 0 to 99 - if f[y * 100 + x + 1] = 1 - move x y - rect 1 1 - . +proc show . + for y = 0 to 99 : for x = 0 to 99 + if f[y * 100 + x + 1] = 1 + grect x y 1 1 . . . -proc run x y dir . . +proc run x y dir . dx[] = [ 0 1 0 -1 ] dy[] = [ -1 0 1 0 ] while x >= 0 and x < 100 and y >= 0 and y < 100 diff --git a/Task/Largest-int-from-concatenated-ints/XPL0/largest-int-from-concatenated-ints.xpl0 b/Task/Largest-int-from-concatenated-ints/XPL0/largest-int-from-concatenated-ints.xpl0 new file mode 100644 index 0000000000..02634408ba --- /dev/null +++ b/Task/Largest-int-from-concatenated-ints/XPL0/largest-int-from-concatenated-ints.xpl0 @@ -0,0 +1,34 @@ +func Cat(A, B); \Concatenate integers A and B +int A, B, T; +[T:= B; +while T do + [A:= A*10; + T:= T/10; + ]; +return A+B; +]; + +proc CatSort(A, Len); \Sort array A by concatenating adjacent values +int A, Len; +int I, J, T, X, Y; +[for J:= Len-1 downto 0 do + for I:= 0 to J-1 do + [X:= Cat(A(I), A(I+1)); + Y:= Cat(A(I+1), A(I)); + if X > Y then + [T:= A(I); A(I):= A(I+1); A(I+1):= T]; + ]; +]; + +proc Largest(Ints, Len); \Show the largest int from concatenated ints +int Ints, Len; +int I; +[CatSort(Ints, Len); +for I:= Len-1 downto 0 do + IntOut(0, Ints(I)); +CrLf(0); +]; + +[Largest([1, 34, 3, 98, 9, 76, 45, 4], 8); + Largest([54, 546, 548, 60], 4); +] diff --git a/Task/Largest-number-divisible-by-its-digits/EasyLang/largest-number-divisible-by-its-digits.easy b/Task/Largest-number-divisible-by-its-digits/EasyLang/largest-number-divisible-by-its-digits.easy index b3697e1722..61f49ab4b2 100644 --- a/Task/Largest-number-divisible-by-its-digits/EasyLang/largest-number-divisible-by-its-digits.easy +++ b/Task/Largest-number-divisible-by-its-digits/EasyLang/largest-number-divisible-by-its-digits.easy @@ -1,21 +1,17 @@ global found dig[] . -proc test . . +proc test . for i to len dig[] n = n * 10 + dig[i] . for i to len dig[] - if n mod dig[i] <> 0 - return - . + if n mod dig[i] <> 0 : return . found = 1 print n . len use[] 9 -proc perm pos . . - if found = 1 - return - . +proc perm pos . + if found = 1 : return for i = 9 downto 1 dig[pos] = i if use[i] = 0 diff --git a/Task/Largest-proper-divisor-of-n/ALGOL-60/largest-proper-divisor-of-n.alg b/Task/Largest-proper-divisor-of-n/ALGOL-60/largest-proper-divisor-of-n.alg new file mode 100644 index 0000000000..585fbb17d0 --- /dev/null +++ b/Task/Largest-proper-divisor-of-n/ALGOL-60/largest-proper-divisor-of-n.alg @@ -0,0 +1,33 @@ +begin + +comment - return n mod m; +integer procedure mod(n, m); + value n, m; integer n, m; +begin + mod := n - entier(n/m) * m; +end; + +comment - return the largest proper divisor of n; +integer procedure lpd(n); + value n; integer n; +begin + integer i; + if n = 1 then + lpd := 1 + else + begin + i := n/2; + for i := i while mod(n,i) notequal 0 do + i := i - 1; + lpd := i; + end; +end; + +integer k; +for k := 1 step 1 until 100 do + begin + outinteger(1,lpd(k)); + if mod(k,10) = 0 then outstring(1,"\n"); + end; + +end diff --git a/Task/Last-Friday-of-each-month/EasyLang/last-friday-of-each-month.easy b/Task/Last-Friday-of-each-month/EasyLang/last-friday-of-each-month.easy index b2b086e459..d960680b34 100644 --- a/Task/Last-Friday-of-each-month/EasyLang/last-friday-of-each-month.easy +++ b/Task/Last-Friday-of-each-month/EasyLang/last-friday-of-each-month.easy @@ -1,17 +1,13 @@ -proc show y . . +proc show y . days[] = [ 31 28 31 30 31 30 31 31 30 31 30 31 ] days[2] += if y mod 4 = 0 and (y mod 100 <> 0 or y mod 400 = 0) w = y * 365 + (y - 1) div 4 - (y - 1) div 100 + (y - 1) div 400 + 6 for m = 1 to 12 w = (w + days[m]) mod 7 m$ = m - if m < 10 - m$ = 0 & m - . + if m < 10 : m$ = 0 & m h = 5 - if w < 5 - h = -2 - . + if w < 5 : h = -2 print y & "-" & m$ & "-" & days[m] + h - w . . diff --git a/Task/Last-letter-first-letter/EasyLang/last-letter-first-letter.easy b/Task/Last-letter-first-letter/EasyLang/last-letter-first-letter.easy index fc6da4d81f..8223b76a5e 100644 --- a/Task/Last-letter-first-letter/EasyLang/last-letter-first-letter.easy +++ b/Task/Last-letter-first-letter/EasyLang/last-letter-first-letter.easy @@ -1,13 +1,11 @@ repeat s$ = input until s$ = "" - for n$ in strsplit s$ " " - pok$[] &= n$ - . + for n$ in strsplit s$ " " : pok$[] &= n$ . # chain$[] = [ ] -proc search lng . . +proc search lng . if lng > len chain$[] chain$[] = [ ] for j to lng diff --git a/Task/Last-letter-first-letter/FreeBASIC/last-letter-first-letter.basic b/Task/Last-letter-first-letter/FreeBASIC/last-letter-first-letter.basic new file mode 100644 index 0000000000..f057a39137 --- /dev/null +++ b/Task/Last-letter-first-letter/FreeBASIC/last-letter-first-letter.basic @@ -0,0 +1,55 @@ +Dim As String names(69) = { "audino", "bagon", "baltoy", "banette", _ +"bidoof", "braviary", "bronzor", "carracosta", "charmeleon", _ +"cresselia", "croagunk", "darmanitan", "deino", "emboar", _ +"emolga", "exeggcute", "gabite", "girafarig", "gulpin", _ +"haxorus", "heatmor", "heatran", "ivysaur", "jellicent", _ +"jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba", _ +"loudred", "lumineon", "lunatone", "machamp", "magnezone", _ +"mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu", _ +"pinsir", "poliwrath", "poochyena", "porygon2", "porygonz", _ +"registeel", "relicanth", "remoraid", "rufflet", "sableye", _ +"scolipede", "scrafty", "seaking", "sealeo", "silcoon", _ +"simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga", _ +"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", _ +"wailord", "wartortle", "whismur", "wingull", "yamask" } + +Dim As String strbegin = "gabite" +Dim As String strdir = "first" + +Dim As String ready() +ready(0) = strbegin +Print strbegin + +Dim As String strc +Dim As Boolean flag +Dim As Integer i, n, foundIndex + +Do + strc = Right(strbegin, 1) + foundIndex = -1 + For i = 0 To Ubound(names) + If Left(names(i), 1) = strc Then + flag = True + For n = 0 To Ubound(ready) + If names(i) = ready(n) Then + flag = False + Exit For + End If + Next + If flag Then + foundIndex = i + Exit For + End If + End If + Next + + If foundIndex = -1 Then Exit Do + + Redim Preserve ready(Ubound(ready) + 1) + ready(Ubound(ready)) = names(foundIndex) + Print names(foundIndex) + strbegin = names(foundIndex) + strdir = Iif(strdir = "first", "last", "first") +Loop + +Sleep diff --git a/Task/Last-letter-first-letter/XPL0/last-letter-first-letter.xpl0 b/Task/Last-letter-first-letter/XPL0/last-letter-first-letter.xpl0 new file mode 100644 index 0000000000..98ed114789 --- /dev/null +++ b/Task/Last-letter-first-letter/XPL0/last-letter-first-letter.xpl0 @@ -0,0 +1,68 @@ +string 0; \use zero-terminated strings +def NamesLen = 70; +int Path(NamesLen), MaxPath(NamesLen); +int Names, MaxPathEnd, MaxPathCnt; + +proc Search(Depth); \Depth-first search for longest chain of Names +int Depth; +char Name; +int LastLetter, FirstLetter, Len, I, J, T; +[Path(Depth):= Names(Depth); \record path being searched +Name:= Names(Depth); \get last letter of Name at Depth +Len:= 0; while Name(Len) do Len:= Len+1; +LastLetter:= Name(Len-1); +Depth:= Depth+1; + +for I:= Depth to NamesLen-1 do \for remaining Names not in path... + [Name:= Names(I); \get first letter of a Name + FirstLetter:= Name(0); + if FirstLetter = LastLetter then \there is a next Name + [if Depth > MaxPathEnd then \record this longer path + [for J:= 0 to Depth-1 do \copy path already searched + MaxPath(J):= Path(J); + MaxPath(Depth):= Name; \append next Name + MaxPathEnd:= Depth; + MaxPathCnt:= 1; \reset counter for this longer path + ] + else if Depth = MaxPathEnd then + MaxPathCnt:= MaxPathCnt+1; \count instances of longest path + + T:= Names(Depth); Names(Depth):= Names(I); Names(I):= T; \swap Names + Search(Depth); \recurse + Names(I):= Names(Depth); Names(Depth):= T; \restore order + ]; + ]; +]; + +int I, T; +[Names:= [ \Pokemon names + "audino", "bagon", "baltoy", "banette", "bidoof", + "braviary", "bronzor", "carracosta", "charmeleon", "cresselia", + "croagunk", "darmanitan", "deino", "emboar", "emolga", + "exeggcute", "gabite", "girafarig", "gulpin", "haxorus", + "heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", + "kangaskhan", "kricketune", "landorus", "ledyba", "loudred", + "lumineon", "lunatone", "machamp", "magnezone", "mamoswine", + "nosepass", "petilil", "pidgeotto", "pikachu", "pinsir", + "poliwrath", "poochyena", "porygon2", "porygonz", "registeel", + "relicanth", "remoraid", "rufflet", "sableye", "scolipede", + "scrafty", "seaking", "sealeo", "silcoon", "simisear", + "snivy", "snorlax", "spoink", "starly", "tirtouga", + "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", + "wailord", "wartortle", "whismur", "wingull", "yamask"]; +MaxPathEnd:= 0; MaxPathCnt:= 0; + +for I:= 0 to NamesLen-1 do + [T:= Names(0); Names(0):= Names(I); Names(I):= T; \swap out pending Name + Search(0); + Names(I):= Names(0); Names(0):= T; \restore Names order + ]; +Text(0, "Maximum path length : "); IntOut(0, MaxPathEnd+1); CrLf(0); +Text(0, "Paths of that length: "); IntOut(0, MaxPathCnt); CrLf(0); +Text(0, "Example path of that length:"); +for I:= 0 to MaxPathEnd do + [if rem(I/5) then ChOut(0, ^ ) else CrLf(0); + Text(0, MaxPath(I)); + ]; +CrLf(0); +] diff --git a/Task/Latin-Squares-in-reduced-form/Rust/latin-squares-in-reduced-form.rs b/Task/Latin-Squares-in-reduced-form/Rust/latin-squares-in-reduced-form.rs new file mode 100644 index 0000000000..cd4999d953 --- /dev/null +++ b/Task/Latin-Squares-in-reduced-form/Rust/latin-squares-in-reduced-form.rs @@ -0,0 +1,144 @@ +use std::io; + +type Matrix = Vec>; + +fn dlist(n: usize, start: usize) -> Matrix { + let mut a: Vec = (0..n).collect(); + a.swap(0, start - 1); // 1-based to 0-based index, swap start-1 with first element + + let first = a[1]; + + let mut result = Vec::new(); + + fn recurse(a: &mut Vec, last: usize, first: usize, result: &mut Matrix) { + if last == 1 { + // Test if it's a derangement + for j in 1..a.len() { + if a[j] == j { + return; // Not deranged + } + } + + // Convert back to 1-based indexing + result.push(a.iter().map(|&v| v + 1).collect()); + return; + } + + for i in (1..=last).rev() { + a.swap(i, last); + recurse(a, last - 1, first, result); + a.swap(i, last); + } + } + + let mut a_clone = a.clone(); + recurse(&mut a_clone, n - 1, first, &mut result); + result +} + +fn print_square(latin: &Matrix) { + for row in latin { + print!("["); + let len = row.len(); + for (i, val) in row.iter().enumerate() { + if i != len - 1 { + print!("{}, ", val); + } else { + print!("{}", val); + } + } + println!("]"); + } + println!(); +} + +fn reduced_latin_squares(n: usize, echo: bool) -> u64 { + if n == 0 { + if echo { + println!("[]"); + } + return 0; + } else if n == 1 { + if echo { + println!("[1]"); + } + return 1; + } + + // Initialize the Latin square with indices + let mut rlatin: Matrix = (0..n) + .map(|i| (0..n).map(|j| j + 1).collect::>()) + .collect(); + + // First row is 1 to n + for j in 0..n { + rlatin[0][j] = j + 1; + } + + let mut count: u64 = 0; + + fn recurse( + i: usize, + rlatin: &mut Matrix, + n: usize, + echo: bool, + count: &mut u64, + ) { + let rows = dlist(n, i); + + for row in &rows { + rlatin[i - 1] = row.clone(); + + let mut conflict = false; + + for k in 0..i - 1 { + for j in 1..n { + if rlatin[k][j] == rlatin[i - 1][j] { + conflict = true; + break; + } + } + if conflict { + break; + } + } + + if !conflict { + if i < n { + recurse(i + 1, rlatin, n, echo, count); + } else { + *count += 1; + if echo { + print_square(rlatin); + } + } + } + } + } + + recurse(2, &mut rlatin, n, echo, &mut count); + count +} + +fn factorial(n: u64) -> u64 { + (1..=n).product() +} + +fn main() { + println!("The four reduced Latin squares of order 4 are:\n"); + reduced_latin_squares(4, true); + + println!("The size of the set of reduced Latin squares for the following orders"); + println!("and hence the total number of Latin squares of these orders are:\n"); + + for n in 1..7 { + let size = reduced_latin_squares(n, false); + let fact_n_1 = factorial((n - 1) as u64); + let total = fact_n_1 * fact_n_1 * n as u64 * size; + + println!( + "Order {}: Size {} x {}! x {}! => Total {}", + n, size, n, n - 1, total + ); + } +} diff --git a/Task/Latin-Squares-in-reduced-form/Zig/latin-squares-in-reduced-form.zig b/Task/Latin-Squares-in-reduced-form/Zig/latin-squares-in-reduced-form.zig new file mode 100644 index 0000000000..38101bc8e1 --- /dev/null +++ b/Task/Latin-Squares-in-reduced-form/Zig/latin-squares-in-reduced-form.zig @@ -0,0 +1,207 @@ +const std = @import("std"); + +const Matrix = std.ArrayList(std.ArrayList(usize)); + +fn dlist(n: usize, start: usize, allocator: std.mem.Allocator) !Matrix { + var a = std.ArrayList(usize).init(allocator); + defer a.deinit(); + + try a.resize(n); + for (0..n) |index| { + a.items[index] = index; + } + + // 1-based to 0-based index, swap start-1 with first element + std.mem.swap(usize, &a.items[0], &a.items[start - 1]); + + const first = a.items[1]; + + var result = Matrix.init(allocator); + + const Context = struct { + a: *std.ArrayList(usize), + first: usize, + result: *Matrix, + allocator: std.mem.Allocator, + }; + + var context = Context{ + .a = &a, + .first = first, + .result = &result, + .allocator = allocator, + }; + + var a_clone = try a.clone(); + defer a_clone.deinit(); + + try recurse(&a_clone, n - 1, &context); + + return result; +} + +fn recurse(a: *std.ArrayList(usize), last: usize, context: anytype) !void { + if (last == 1) { + // Test if it's a derangement + for (1..a.items.len) |j| { + if (a.items[j] == j) { + return; // Not deranged + } + } + + // Convert back to 1-based indexing + var row = std.ArrayList(usize).init(context.allocator); + for (a.items) |v| { + try row.append(v + 1); + } + try context.result.append(row); + return; + } + + var i: usize = last; + while (i >= 1) : (i -= 1) { + std.mem.swap(usize, &a.items[i], &a.items[last]); + try recurse(a, last - 1, context); + std.mem.swap(usize, &a.items[i], &a.items[last]); + } +} + +fn printSquare(latin: Matrix) void { + for (latin.items) |row| { + std.debug.print("[", .{}); + for (row.items, 0..) |val, i| { + if (i != row.items.len - 1) { + std.debug.print("{}, ", .{val}); + } else { + std.debug.print("{}", .{val}); + } + } + std.debug.print("]\n", .{}); + } + std.debug.print("\n", .{}); +} + +fn reducedLatinSquares(n: usize, echo: bool, allocator: std.mem.Allocator) !u64 { + if (n == 0) { + if (echo) { + std.debug.print("[]\n", .{}); + } + return 0; + } else if (n == 1) { + if (echo) { + std.debug.print("[1]\n", .{}); + } + return 1; + } + + // Initialize the Latin square with indices + var rlatin = Matrix.init(allocator); + defer { + for (rlatin.items) |row| { + row.deinit(); + } + rlatin.deinit(); + } + + for (0..n) |_| { + var row = std.ArrayList(usize).init(allocator); + for (0..n) |j| { + try row.append(j + 1); + } + try rlatin.append(row); + } + + // First row is 1 to n (already initialized above) + + var count: u64 = 0; + + const Context = struct { + rlatin: *Matrix, + n: usize, + echo: bool, + count: *u64, + allocator: std.mem.Allocator, + }; + + var context = Context{ + .rlatin = &rlatin, + .n = n, + .echo = echo, + .count = &count, + .allocator = allocator, + }; + + try recurseLatinSquare(2, &context); + + return count; +} + +fn recurseLatinSquare(i: usize, context: anytype) !void { + var rows = try dlist(context.n, i, context.allocator); + defer { + for (rows.items) |row| { + row.deinit(); + } + rows.deinit(); + } + + for (rows.items) |row| { + // Copy row to rlatin[i-1] + for (row.items, 0..) |val, j| { + context.rlatin.items[i - 1].items[j] = val; + } + + var conflict = false; + + outer: for (0..i - 1) |k| { + for (1..context.n) |j| { + if (context.rlatin.items[k].items[j] == context.rlatin.items[i - 1].items[j]) { + conflict = true; + break :outer; + } + } + } + + if (!conflict) { + if (i < context.n) { + try recurseLatinSquare(i + 1, context); + } else { + context.count.* += 1; + if (context.echo) { + printSquare(context.rlatin.*); + } + } + } + } +} + +fn factorial(n: u64) u64 { + var result: u64 = 1; + var i: u64 = 1; + while (i <= n) : (i += 1) { + result *= i; + } + return result; +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer _ = gpa.deinit(); + + std.debug.print("The four reduced Latin squares of order 4 are:\n\n", .{}); + _ = try reducedLatinSquares(4, true, allocator); + + std.debug.print("The size of the set of reduced Latin squares for the following orders\n", .{}); + std.debug.print("and hence the total number of Latin squares of these orders are:\n\n", .{}); + + for (1..6) |n| { + const size = try reducedLatinSquares(n, false, allocator); + const fact_n_1 = factorial(@as(u64, n - 1)); + const total = fact_n_1 * fact_n_1 * @as(u64, n) * size; + + std.debug.print("Order {}: Size {} x {}! x {}! => Total {}\n", .{ + n, size, n, n - 1, total + }); + } +} diff --git a/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-1.rexx b/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-1.rexx index 7dde8a8542..eaad27631c 100644 --- a/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-1.rexx +++ b/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-1.rexx @@ -1,15 +1,18 @@ -Main: +-- 22 Mar 2025 include Settings -say version; say 'Legendre Prime counter (no memoization)'; say + +say 'LEGENDRE PRIME COUNTER (NO MEMOIZATION)' +say version +say numeric digits 10 do n = 0 to 9 call Time('r') - a = 10**n; p = pi(a) + a = 10**n; p = Pie(a) say '10^'n Right(p,9) Format(Time('e'),3,3)'s' end exit -Pi: +Pie: procedure expose prim. arg xx if xx < 3 then @@ -22,7 +25,7 @@ procedure expose prim. arg xx,yy if yy < 2 then return xx-(xx%2)*(yy=1) -p = prim.prime.yy +p = prim.yy if xx <= p then return 1 return Phi(xx,yy-1)-Phi(xx%p,yy-1) diff --git a/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-2.rexx b/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-2.rexx index 3ca9b25734..d724a28756 100644 --- a/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-2.rexx +++ b/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-2.rexx @@ -1,15 +1,18 @@ -Main: +-- 22 Mar 2025 include Settings -say version; say 'Legendre Prime counter (with memoization)'; say + +say 'LEGENDRE PRIME COUNTER (WITH MEMOIZATION)' +say version +say numeric digits 10 do n = 0 to 9 call Time('r') - a = 10**n; p = Pi(a) + a = 10**n; p = Pie(a) say '10^'n Right(p,9) Format(Time('e'),3,3)'s' end exit -Pi: +Pie: procedure expose prim. work. arg xx if xx < 3 then @@ -23,7 +26,7 @@ procedure expose prim. work. arg xx,yy if yy < 2 then return xx-(xx%2)*(yy=1) -p = prim.prime.yy +p = prim.yy if xx <= p then return 1 if work.xx.yy > 0 then diff --git a/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-3.rexx b/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-3.rexx index 44c20aa6e8..a3f94a0f28 100644 --- a/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-3.rexx +++ b/Task/Legendre-prime-counting-function/REXX/legendre-prime-counting-function-3.rexx @@ -1,6 +1,9 @@ -Main: +-- 22 Mar 2025 include Settings -say version; say 'Legendre Prime counter (sieving)'; say + +say 'LEGENDRE PRIME COUNTER (SIEVING)' +say version +say numeric digits 10 do n = 0 to 8 call Time('r') diff --git a/Task/Leonardo-numbers/ERRE/leonardo-numbers.erre b/Task/Leonardo-numbers/ERRE/leonardo-numbers.erre new file mode 100644 index 0000000000..94ae064f41 --- /dev/null +++ b/Task/Leonardo-numbers/ERRE/leonardo-numbers.erre @@ -0,0 +1,24 @@ +PROGRAM LEONARDO_NUMBERS + +PROCEDURE PRINT_LEONARDO_NUMS(L0,L1,SUM,LMT%,WHAT$) + ! Print the numbers + PRINT(WHAT$;" (";L0;",";L1;",";SUM;"):") + IF LMT%>=1 THEN + PRINT(L0;) + END IF + IF LMT%>=2 THEN + PRINT(L1;) + END IF + FOR I%=3 TO LMT% DO + PRINT(L0+L1+SUM;) + TMP=L0 + L0=L1 + L1=TMP+L1+SUM + END FOR + PRINT +END PROCEDURE + +BEGIN + PRINT_LEONARDO_NUMS(1,1,1,25,"Leonardo numbers") + PRINT_LEONARDO_NUMS(0,1,0,25,"Fibonacci numbers") +END PROGRAM diff --git a/Task/Leonardo-numbers/EasyLang/leonardo-numbers.easy b/Task/Leonardo-numbers/EasyLang/leonardo-numbers.easy index c8752fcccf..ded0a5e511 100644 --- a/Task/Leonardo-numbers/EasyLang/leonardo-numbers.easy +++ b/Task/Leonardo-numbers/EasyLang/leonardo-numbers.easy @@ -1,4 +1,4 @@ -proc leonardo L0 L1 add . . +proc leonardo L0 L1 add . print "L0:" & L0 & " L1:" & L1 & " add:" & add write L0 & " " write L1 & " " diff --git a/Task/Letter-frequency/Nu/letter-frequency.nu b/Task/Letter-frequency/Nu/letter-frequency-1.nu similarity index 100% rename from Task/Letter-frequency/Nu/letter-frequency.nu rename to Task/Letter-frequency/Nu/letter-frequency-1.nu diff --git a/Task/Letter-frequency/Nu/letter-frequency-2.nu b/Task/Letter-frequency/Nu/letter-frequency-2.nu new file mode 100644 index 0000000000..19de718065 --- /dev/null +++ b/Task/Letter-frequency/Nu/letter-frequency-2.nu @@ -0,0 +1 @@ +open 'unixdict.txt' | split chars | where $it =~ '^\pL$' | histogram diff --git a/Task/Levenshtein-distance-Alignment/EasyLang/levenshtein-distance-alignment.easy b/Task/Levenshtein-distance-Alignment/EasyLang/levenshtein-distance-alignment.easy index 8be5ec6616..58c29d7c22 100644 --- a/Task/Levenshtein-distance-Alignment/EasyLang/levenshtein-distance-alignment.easy +++ b/Task/Levenshtein-distance-Alignment/EasyLang/levenshtein-distance-alignment.easy @@ -1,29 +1,23 @@ global dparr[] dpcols . -proc dpnew a b . . +proc dpnew a b . len dparr[] a * b dpcols = b . func dp r c . return dparr[r * dpcols + c + 1] . -proc dps r c v . . +proc dps r c v . dparr[r * dpcols + c + 1] = v . -proc align a$ b$ . ar$ br$ . +proc align a$ b$ &ar$ &br$ . dpnew (len a$ + 1) (len b$ + 1) - for i = 1 to len a$ - dps i 0 i - . - for j = 0 to len b$ - dps 0 j j - . - for i = 1 to len a$ - for j = 1 to len b$ - if substr a$ i 1 = substr b$ j 1 - dps i j dp (i - 1) (j - 1) - else - dps i j lower (lower dp (i - 1) j dp i (j - 1)) dp (i - 1) (j - 1) + 1 - . + for i = 1 to len a$ : dps i 0 i + for j = 0 to len b$ : dps 0 j j + for i = 1 to len a$ : for j = 1 to len b$ + if substr a$ i 1 = substr b$ j 1 + dps i j dp (i - 1) (j - 1) + else + dps i j lower (lower dp (i - 1) j dp i (j - 1)) dp (i - 1) (j - 1) + 1 . . ar$ = "" ; br$ = "" diff --git a/Task/Levenshtein-distance/ANSI-BASIC/levenshtein-distance.basic b/Task/Levenshtein-distance/ANSI-BASIC/levenshtein-distance.basic new file mode 100644 index 0000000000..0c779254b8 --- /dev/null +++ b/Task/Levenshtein-distance/ANSI-BASIC/levenshtein-distance.basic @@ -0,0 +1,29 @@ +100 REM Levenshtein distance +110 DECLARE EXTERNAL FUNCTION LevDist +120 PRINT "The Levenshtein distance..." +130 PRINT "between 'kitten' and 'sitting' is"; LevDist("kitten","sitting") +140 PRINT "between 'rosettacode' and 'raisethysword' is"; LevDist("rosettacode","raisethysword") +150 END +160 EXTERNAL FUNCTION LevDist(S$, T$) +170 LET N = LEN(T$) +180 LET M = LEN(S$) +190 DIM D(0 TO 20, 0 TO 20) +200 REM Both T$ and S$ must not be longer than 20 chars +210 REM Some impementations allow DIM D(0 TO M, 0 TO N), but it is not standard. +220 FOR I = 0 TO M +230 LET D(I, 0) = I +240 NEXT I +250 FOR J = 0 TO N +260 LET D(0, J) = J +270 NEXT J +280 FOR J = 1 TO N +290 FOR I = 1 TO M +300 IF S$(I:I) = T$(J:J) THEN +310 LET D(I, J) = D(I - 1, J - 1) +320 ELSE +330 LET D(I, J) = MIN(D(I - 1, J) + 1, MIN(D(I, J - 1) + 1, D(I - 1, J - 1) + 1)) +340 END IF +350 NEXT I +360 NEXT J +370 LET LevDist = D(M, N) +380 END FUNCTION diff --git a/Task/Levenshtein-distance/Applesoft-BASIC/levenshtein-distance.basic b/Task/Levenshtein-distance/Applesoft-BASIC/levenshtein-distance.basic new file mode 100644 index 0000000000..b649fa4458 --- /dev/null +++ b/Task/Levenshtein-distance/Applesoft-BASIC/levenshtein-distance.basic @@ -0,0 +1,18 @@ + 10 PRINT "THE LEVENSHTEIN DISTANCE..." + 20 CLEAR :S$ = "KITTEN":T$ = "SITTING": GOSUB 100 + 30 PRINT "BETWEEN '"S$"' AND '"T$"' IS "LD + 40 CLEAR :S$ = "ROSETTACODE":T$ = "RAISETHYSWORD": GOSUB 100 + 50 PRINT "BETWEEN '"S$"' AND '"T$"' IS "LD + 60 END + + REM CALCULATE LEVENSHTEIN DISTANCE (LD) GIVEN S$ T$ + 100 LET M = LEN (S$):N = LEN (T$): DIM D(M,N): FOR I = 0 TO M:D(I,0) = I: NEXT : FOR J = 0 TO N:D(0,J) = J: NEXT + 110 FOR J = 1 TO N + 120 FOR I = 1 TO M + 130 IF MID$ (S$,I,1) = MID$ (T$,J,1) THEN D(I,J) = D(I - 1,J - 1): NEXT I,J:LD = D(M,N): RETURN + 140 LET R = NOT (D(I,J - 1) + 1 < D(I - 1,J - 1) + 1):MIN = D(I - R,J - 1) + 1 + 150 LET R = MIN: IF D(I - 1,J) + 1 < MI THEN R = D(I - 1,J) + 1 + 160 LET D(I,J) = R + 170 NEXT I,J + 180 LET LD = D(M,N) + 190 RETURN diff --git a/Task/Levenshtein-distance/Ballerina/levenshtein-distance.ballerina b/Task/Levenshtein-distance/Ballerina/levenshtein-distance.ballerina new file mode 100644 index 0000000000..4b0c04e474 --- /dev/null +++ b/Task/Levenshtein-distance/Ballerina/levenshtein-distance.ballerina @@ -0,0 +1,31 @@ +import ballerina/io; + +function levenshtein(string s, string t) returns int { + int ls = s.length(); + int lt = t.length(); + int[][] d = []; + foreach int i in 0...ls { + d[i] = []; + d[i].setLength(lt + 1); + d[i][0] = i; + } + foreach int j in 0...lt { d[0][j] = j; } + foreach int j in 1...lt { + foreach int i in 1...ls { + if s[i - 1] == t[j - 1] { + d[i][j] = d[i - 1][j - 1]; + } else { + int min = d[i - 1][j]; + if d[i][j - 1] < min { min = d[i][j - 1]; } + if d[i - 1][j - 1] < min { min = d[i - 1][j - 1]; } + d[i][j] = min + 1; + } + } + } + return d[ls][lt]; +} + +public function main() { + io:println(levenshtein("kitten", "sitting")); + io:println(levenshtein("rosettacode", "raisethysword")); +} diff --git a/Task/Levenshtein-distance/Free-Pascal-Lazarus/levenshtein-distance.pas b/Task/Levenshtein-distance/Free-Pascal-Lazarus/levenshtein-distance.pas new file mode 100644 index 0000000000..9423111539 --- /dev/null +++ b/Task/Levenshtein-distance/Free-Pascal-Lazarus/levenshtein-distance.pas @@ -0,0 +1,40 @@ +program LevenshteinDistanceDemo(Output); + +uses + Math; + + function LevenshteinDistance(S, T: string): longint; + var + D: array of array of integer; + I, J, N, M: integer; + begin + N := Length(T); + M := Length(S); + SetLength(D, M + 1, N + 1); + + for I := 0 to M do + D[I, 0] := I; + for J := 0 to N do + D[0, J] := J; + for J := 1 to N do + for I := 1 to M do + if S[I] = T[J] then + D[I, J] := D[I - 1, J - 1] + else + D[I, J] := Min(D[I - 1, J] + 1, Min(D[I, J - 1] + 1, D[I - 1, J - 1] + 1)); + LevenshteinDistance := D[M, N]; + end; + +var + S1, S2: string; + +begin + S1 := 'kitten'; + S2 := 'sitting'; + WriteLn('The Levenshtein distance between "', S1, '" and "', + S2, '" is: ', LevenshteinDistance(S1, S2)); + S1 := 'rosettacode'; + S2 := 'raisethysword'; + WriteLn('The Levenshtein distance between "', S1, '" and "', + S2, '" is: ', LevenshteinDistance(S1, S2)); +end. diff --git a/Task/Levenshtein-distance/GW-BASIC/levenshtein-distance.basic b/Task/Levenshtein-distance/GW-BASIC/levenshtein-distance.basic new file mode 100644 index 0000000000..972b9b5c2e --- /dev/null +++ b/Task/Levenshtein-distance/GW-BASIC/levenshtein-distance.basic @@ -0,0 +1,28 @@ +10 REM Levenshtein distance +20 PRINT "The Levenshtein distance..." +30 S$ = "kitten": T$ = "sitting": GOSUB 1000 +40 PRINT "between '"; S$; "' and '"; T$; "' is"; LEV.DIST +50 S$ = "rosettacode": T$ = "raisethysword": GOSUB 1000 +60 PRINT "between '"; S$; "' and '"; T$; "' is"; LEV.DIST +70 END +1000 REM ** Calculate distance for strings S$ and T$ +1010 M = LEN(S$): N = LEN(T$) +1020 DIM D(M, N) +1030 FOR I = 0 TO M +1040 D(I, 0) = I +1050 NEXT I +1060 FOR J = 0 TO N +1070 D(0, J) = J +1080 NEXT J +1090 FOR J = 1 TO N +1100 FOR I = 1 TO M +1110 IF MID$(S$, I, 1) <> MID$(T$, J, 1) THEN 1140 +1120 D(I, J) = D(I - 1, J - 1) +1130 GOTO 1160 +1140 IF D(I, J - 1) + 1 < D(I - 1, J - 1) + 1 THEN MIN = D(I, J - 1) + 1 ELSE MIN = D(I - 1, J - 1) + 1 +1150 IF D(I - 1, J) + 1 < MIN THEN D(I, J) = D(I - 1, J) + 1 ELSE D(I, J) = MIN +1160 NEXT I +1170 NEXT J +1180 LEV.DIST = D(M, N) +1190 ERASE D +1200 RETURN diff --git a/Task/Levenshtein-distance/Nascom-BASIC/levenshtein-distance.basic b/Task/Levenshtein-distance/Nascom-BASIC/levenshtein-distance.basic new file mode 100644 index 0000000000..f29c501939 --- /dev/null +++ b/Task/Levenshtein-distance/Nascom-BASIC/levenshtein-distance.basic @@ -0,0 +1,33 @@ +10 REM Levenshtein distance +20 ML=20:REM Max. length +30 DIM D(ML,ML) +40 PRINT "The Levenshtein distance..." +50 S$="kitten":T$="sitting" +60 GOSUB 1000 +70 PRINT "between '";S$;"' and '";T$;"' is";DS +80 S$="rosettacode":T$="raisethysword" +90 GOSUB 1000 +100 PRINT "between '";S$;"' and '";T$;"' is";DS +110 END +1000 REM ** Calculate dist. for S$ and T$ +1010 M=LEN(S$):N=LEN(T$) +1020 FOR I=0 TO M +1030 D(I,0)=I +1040 NEXT I +1050 FOR J=0 TO N +1060 D(0,J)=J +1070 NEXT J +1080 FOR J=1 TO N +1090 FOR I=1 TO M +1100 IF MID$(S$,I,1)<>MID$(T$,J,1) THEN 1120 +1110 D(I,J)=D(I-1,J-1):GOTO 1180 +1120 IF D(I,J-1)+1 0 l -= 1 if t mod 2 = 1 @@ -18,13 +18,13 @@ proc show t l . . t = t div 2 . . -proc list n . . +proc list n . for i = offs[n] to offs[n + 1] - 1 show trees[i] n * 2 print "" . . -proc assemble n t sl pos rem . . +proc assemble n t sl pos rem . if rem = 0 append t return @@ -34,26 +34,20 @@ proc assemble n t sl pos rem . . pos = offs[sl] elif pos >= offs[sl + 1] sl -= 1 - if sl = 0 - return - . + if sl = 0 : return pos = offs[sl] . h = bitor bitshift t (2 * sl) trees[pos] assemble n h sl pos rem - sl assemble n t sl pos + 1 rem . -proc make n . . - if offs[n + 1] <> 0 - return - . - if n > 0 - make n - 1 - . +proc make n . + if offs[n + 1] <> 0 : return + if n > 0 : make n - 1 assemble n 0 n - 1 offs[n - 1] n - 1 offs[n + 1] = len trees[] . -proc test n . . +proc test n . append 0 make n print "Number of " & n & "-trees: " & offs[n + 1] - offs[n] diff --git a/Task/Literals-Floating-point/REXX/literals-floating-point-1.rexx b/Task/Literals-Floating-point/REXX/literals-floating-point-1.rexx deleted file mode 100644 index d4a63f46dc..0000000000 --- a/Task/Literals-Floating-point/REXX/literals-floating-point-1.rexx +++ /dev/null @@ -1,6 +0,0 @@ -something = 127 -something = '127' /*exactly the same as the above. */ -something = 1.27e2 -something = 1.27E2 -something = 1.27E+2 -something = ' + 0001.27e+00000000000000002 ' diff --git a/Task/Literals-Floating-point/REXX/literals-floating-point-2.rexx b/Task/Literals-Floating-point/REXX/literals-floating-point-2.rexx deleted file mode 100644 index adaeedff96..0000000000 --- a/Task/Literals-Floating-point/REXX/literals-floating-point-2.rexx +++ /dev/null @@ -1,3 +0,0 @@ -something = -.00478 -say something -say format(something,,,,0) diff --git a/Task/Literals-Floating-point/REXX/literals-floating-point.rexx b/Task/Literals-Floating-point/REXX/literals-floating-point.rexx new file mode 100644 index 0000000000..df07d9fa3e --- /dev/null +++ b/Task/Literals-Floating-point/REXX/literals-floating-point.rexx @@ -0,0 +1,52 @@ +-- 19 May 2025 +include Settings + +say 'LITERALS FLOATING POINT' +say version +say +say 'The standard precision (numeric digits) is 9' +say +say 'Assigments are as string...' +a = 666666.666666; say a +say 'until you do a calculation' +say a/1 +say +say 'Default Format...' +say 'Leading and trailing zeroes may be Left out' +l = 13 +a = 123.456; say Left(a,l) '=' a/1 +a = '123.456'; say Left(a,l) '=' a/1 +a = "123.456"; say Left(a,l) '=' a/1 +a = 0123.4560; say Left(a,l) '=' a/1 +a = 12345.6E-2; say Left(a,l) '=' a/1 +a = 123.456E0; say Left(a,l) '=' a/1 +a = 1.23456E+2; say Left(a,l) '=' a/1 +a = ' 01.23456E+02 '; say Left(a,l) '=' a/1 +say +say 'Force standard, scientific or engineering Format...' +l = 11 +a = 7; b = '1/'a; c = 1/a +say Left('1/'||a,l) '=' c +say Left('Standard',l) '=' Std(c) +say Left('Scientific',l) '=' Sci(c) +say Left('Engineering',l) '=' Eng(c) +a = 7000000; b = '1/'a; c = 1/a +say Left('1/'||a,l) '=' c +say Left('Standard',l) '=' Std(c) +say Left('Scientific',l) '=' Sci(c) +say Left('Engineering',l) '=' Eng(c) +a = 7 +say Left(a,l) '=' a +say Left('Standard',l) '=' Std(a) +say Left('Scientific',l) '=' Sci(a) +say Left('Engineering',l) '=' Eng(a) +a = 70000000000 +say Left(a,l) '=' a+0 +say Left('Standard',l) '=' Std(a) +say Left('Scientific',l) '=' Sci(a) +say Left('Engineering',l) '=' Eng(a) +exit + +include Functions +include Helper +include Abend diff --git a/Task/Literals-Integer/JavaScript/literals-integer.js b/Task/Literals-Integer/JavaScript/literals-integer.js index bbf26dfea5..9809f8dc0a 100644 --- a/Task/Literals-Integer/JavaScript/literals-integer.js +++ b/Task/Literals-Integer/JavaScript/literals-integer.js @@ -1,3 +1,3 @@ -if ( 727 == 0x2d7 && - 727 == 01327 ) - window.alert("true"); +727 === 0x2d7 // true +727 === 0o1327 // true +727 === 0b1011010111 // true diff --git a/Task/Literals-Integer/REXX/literals-integer.rexx b/Task/Literals-Integer/REXX/literals-integer.rexx index 8dc30648c3..bbdf185f1b 100644 --- a/Task/Literals-Integer/REXX/literals-integer.rexx +++ b/Task/Literals-Integer/REXX/literals-integer.rexx @@ -1,31 +1,53 @@ -/*REXX pgm displays an integer (expressed in the pgm as a literal) in different bases*/ - /*────────── expressing decimal numbers ──────────*/ -ddd = 123 /*a decimal number (expressed as a literal). */ -ddd = '123' /*this is exactly the same as above. */ -ddd = "123" /*this is exactly the same as above also. */ - /*────────── expressing hexadecimal numbers ──────*/ -hhh = '7b'x /*a value, expressed as a hexadecimal literal. */ -hhh = '7B'x /* (same as above) using a capital "B". */ -hhh = '7B'X /* (same as above) using a capital "X". */ -cow = 'dead beef'x /*another value, with a blank for the eyeballs.*/ -cow = 'de ad be ef'x /* (same as above) with blanks for the eyeballs.*/ - /*────────── expressing binary numbers ───────────*/ -bbb = '1111011'b /*a value, expressed as a binary literal. */ -bbb = '01111011'b /* (same as above) with a full 8 binary digits. */ -bbb = '0111 1011'b /* (same as above) with a blank for the eyeballs.*/ +-- 19 May 2025 +include Settings -say ' base 10=' ddd -say ' base 2=' x2b( d2x( ddd ) ) -say ' base 16=' d2x( ddd ) -say ' base 256=' d2c( ddd ) /*the output displayed is ASCII (or maybe EBCDIC).*/ +say 'LITERALS INTEGER' +say version +say +say 'The standard precision (numeric digits) is 9' +say +say 'Assigments are as string...' +a = 6666666666666; say a +say 'until you do a calculation' +say a/1 +say +say 'Decimal...' +l = 8 +a = 0123; say left(a,l) '=' a/1 +a = 123; say left(a,l) '=' a/1 +a = 123.; say left(a,l) '=' a/1 +a = 123.0; say left(a,l) '=' a/1 +a = "123"; say left(a,l) '=' a/1 +a = '123'; say left(a,l) '=' a/1 +a = ' 123 '; say left(a,l) '=' a/1 +a = +123; say left(a,l) '=' a/1 +a = '+123'; say left(a,l) '=' a/1 +a = ' + 123 '; say left(a,l) '=' a/1 +a = .0123E4; say left(a,l) '=' a/1 +a = 12.3E1; say left(a,l) '=' a/1 +a = '12.3e1'; say left(a,l) '=' a/1 +a = 1230E-1; say left(a,l) '=' a/1 +a = 1230E-01; say left(a,l) '=' a/1 +say +say 'Hexadecimal...' +say 'Blanks to separate words and bytes are allowed' +l = 14 +say left("'5a'x",l) '=' '5a'x +say left("'5A'x",l) '=' '5A'x +say left("'5A'X",l) '=' '5A'X +say left("'50515253'X",l) '=' '50515253'X +say left("'5051 5253'X",l) '=' '5051 5253'X +say left("'50 51 52 53'X",l) '=' '50 51 52 53'X +say +say 'Binary...' +say 'Blanks to separate words, bytes and nibbles are allowed' +l = 42 +say left("'1010000010100010101001001010011'B",l) '=' '1010000010100010101001001010011'B +say left("'01010000010100010101001001010011'B",l) '=' '01010000010100010101001001010011'B +say left("'0101000001010001 0101001001010011'B",l) '=' '0101000001010001 0101001001010011'B +say left("'01010000 01010001 01010010 01010011'B",l) '=' '01010000 01010001 01010010 01010011'B +say left("'0101 0000 0101 0001 0101 0010 0101 0011'B",l) '=' '0101 0000 0101 0001 0101 0010 0101 0011'B +exit -thingy1= +123 /*╔══════════════════════════════════════════════╗*/ -thingy2= '+123' /*║ All of the THINGYs variables aren't strictly ║*/ -thingy3= ' 123' /*║ (exactly) equal to the DDD variable, but ║*/ -thingy4= 123. /*║ they do compare numerically equal. When ║*/ -thingy5= 12.3e+1 /*║ compared numerically, numbers are rounded to ║*/ -thingy6= 1230e-1 /*║ the current setting of NUMERIC DIGITS. The ║*/ -thingy7= 1230E-0001 /*║ default for (decimal) NUMERIC DIGITS is 9 ║*/ -thingy8= ' + 123 ' /*╚══════════════════════════════════════════════╝*/ - - /*stick a fork in it, we're all done. */ +include Helper +include Abend diff --git a/Task/Logical-operations/EasyLang/logical-operations.easy b/Task/Logical-operations/EasyLang/logical-operations.easy index 535a6d5b4a..399eb9b09a 100644 --- a/Task/Logical-operations/EasyLang/logical-operations.easy +++ b/Task/Logical-operations/EasyLang/logical-operations.easy @@ -1,4 +1,4 @@ -proc logic a b . . +proc logic a b . if a = 1 and b = 1 r1 = 1 . diff --git a/Task/Long-primes/EasyLang/long-primes.easy b/Task/Long-primes/EasyLang/long-primes.easy index c6faa26dc8..8c507a955a 100644 --- a/Task/Long-primes/EasyLang/long-primes.easy +++ b/Task/Long-primes/EasyLang/long-primes.easy @@ -1,18 +1,14 @@ fastfunc isprim num . - if num mod 2 = 0 and num > 2 - return 0 - . + if num mod 2 = 0 and num > 2 : return 0 i = 3 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 . return 1 . prim = 2 -proc nextprim . . +proc nextprim . repeat prim += 1 until isprim prim = 1 @@ -47,8 +43,6 @@ repeat limit *= 2 . until limit > 32000 - if period prim = prim - 1 - cnt += 1 - . + if period prim = prim - 1 : cnt += 1 nextprim . diff --git a/Task/Long-primes/REXX/long-primes-1.rexx b/Task/Long-primes/REXX/long-primes-1.rexx deleted file mode 100644 index 8453b4c779..0000000000 --- a/Task/Long-primes/REXX/long-primes-1.rexx +++ /dev/null @@ -1,22 +0,0 @@ -/*REXX pgm calculates/displays base ten long primes (AKA golden primes, proper primes,*/ -/*───────────────────── maximal period primes, long period primes, full reptend primes).*/ -parse arg a /*obtain optional argument from the CL.*/ -if a='' | a="," then a= '500 -500 -1000 -2000 -4000 -8000 -16000' , /*Not specified? */ - '-32000 -64000 -128000 -512000 -1024000' /*Then use default*/ - do k=1 for words(a); H=word(a, k) /*step through the list of high limits.*/ - neg= H<1 /*used as an indicator to display count*/ - H= abs(H) /*obtain the absolute value of H. */ - $= /*the list of long primes (so far). */ - do j=7 to H by 2 /*start with 7, just use odd integers.*/ - if .len(j) + 1 \== j then iterate /*Period length wrong? Then skip it. */ - $=$ j /*add the long prime to the $ list.*/ - end /*j*/ - say - if neg then do; say 'number of long primes ≤ ' H " is: " words($); end - else do; say 'list of long primes ≤ ' H":"; say strip($); end - end /*k*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -.len: procedure; parse arg x; r=1; do x; r= 10*r // x; end /*x*/ - rr=r; do p=1 until r==rr; r= 10*r // x; end /*p*/ - return p diff --git a/Task/Long-primes/REXX/long-primes-2.rexx b/Task/Long-primes/REXX/long-primes-2.rexx deleted file mode 100644 index cc8e17cd7a..0000000000 --- a/Task/Long-primes/REXX/long-primes-2.rexx +++ /dev/null @@ -1,28 +0,0 @@ -/*REXX pgm calculates/displays base ten long primes (AKA golden primes, proper primes,*/ -/*───────────────────── maximal period primes, long period primes, full reptend primes).*/ -parse arg a /*obtain optional argument from the CL.*/ -if a='' | a="," then a= '500 -500 -1000 -2000 -4000 -8000 -16000' , /*Not specified? */ - '-32000 -64000 -128000 -512000 -1024000' /*Then use default*/ - do k=1 for words(a); H=word(a, k) /*step through the list of high limits.*/ - neg= H<1 /*used as an indicator to display count*/ - H= abs(H) /*obtain the absolute value of H. */ - $= /*the list of long primes (so far). */ - do j=7 to H by 2; parse var j '' -1 _ /*start with 7, just use odd integers.*/ - if _==5 then iterate /*last digit a five? Then not a prime.*/ - if j// 3==0 then iterate /*Is divisible by 3? " " " " */ - if j\==11 then if j//11==0 then iterate /* " " " 11? " " " " */ - if j\==13 then if j//13==0 then iterate /* " " " 13? " " " " */ - if j\==17 then if j//17==0 then iterate /* " " " 17? " " " " */ - if j\==19 then if j//19==0 then iterate /* " " " 19? " " " " */ - if .len(j) + 1 \== j then iterate /*Period length wrong? Then skip it. */ - $=$ j /*add the long prime to the $ list.*/ - end /*j*/ - say - if neg then do; say 'number of long primes ≤ ' H " is: " words($); end - else do; say 'list of long primes ≤ ' H":"; say strip($); end - end /*k*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -.len: procedure; parse arg x; r=1; do x; r= 10*r // x; end /*x*/ - rr=r; do p=1 until r==rr; r= 10*r // x; end /*p*/ - return p diff --git a/Task/Long-primes/REXX/long-primes-3.rexx b/Task/Long-primes/REXX/long-primes-3.rexx deleted file mode 100644 index 8474e700c4..0000000000 --- a/Task/Long-primes/REXX/long-primes-3.rexx +++ /dev/null @@ -1,38 +0,0 @@ -/*REXX pgm calculates/displays base ten long primes (AKA golden primes, proper primes,*/ -/*───────────────────── maximal period primes, long period primes, full reptend primes).*/ -parse arg a /*obtain optional argument from the CL.*/ -if a='' | a="," then a= '500 -500 -1000 -2000 -4000 -8000 -16000' , /*Not specified? */ - '-32000 -64000 -128000 -512000 -1024000' /*Then use default*/ -m=0; aa= words(a) /* [↑] two list types of low primes. */ - do j=1 for aa; m= max(m, abs(word(a, j))) /*find the maximum argument in the list*/ - end /*j*/ -call genP /*go and generate some primes. */ - do k=1 for aa; H= word(a, k) /*step through the list of high limits.*/ - neg= H<1 /*used as an indicator to display count*/ - H= abs(H) /*obtain the absolute value of H. */ - $= /*the list of long primes (so far). */ - do j=7 to H by 2 - if \@.j then iterate /*Is J not a prime? Then skip it. */ - if .len(j) + 1 \== j then iterate /*Period length wrong? " " " */ - $= $ j /*add the long prime to the $ list.*/ - end /*j*/ /* [↑] some pretty weak prime testing.*/ - say - if neg then say 'number of long primes ≤ ' H " is: " words($) - else do; say 'list of long primes ≤ ' H":"; say strip($); end - end /*k*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: @.=0; @.2=1; @.3=1; @.5=1; @.7=1; @.11=1; !.=0; !.1=2; !.2=3; !.3=5; !.4=7; !.5=11 - #= 5 /*the number of primes (so far). */ - do g=!.#+2 by 2 until g>=m /*gen enough primes to satisfy max A. */ - if @.g\==0 then iterate /*Is it not a prime? Then skip it. */ - do d=2 until !.d**2>g /*only divide up to square root of X. */ - if g//!.d==0 then iterate g /*Divisible? Then skip this integer. */ - end /*d*/ /* [↓] a spanking new prime was found.*/ - #= #+1 @.g= 1; !.#= g /*bump P counter; assign P, add to P's.*/ - end /*g*/ - return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -.len: procedure; parse arg x; r=1; do x; r= 10*r // x; end /*x*/ - rr=r; do p=1 until r==rr; r= 10*r // x; end /*p*/ - return p diff --git a/Task/Long-primes/REXX/long-primes.rexx b/Task/Long-primes/REXX/long-primes.rexx new file mode 100644 index 0000000000..4270b9f8ab --- /dev/null +++ b/Task/Long-primes/REXX/long-primes.rexx @@ -0,0 +1,56 @@ +-- 8 May 2025 +include Settings + +say 'LONG PRIMES' +say version +say +call GetPrimes 70000 +call LPbelow500 +call NumberOfLP +exit + +GetPrimes: +call Time('r') +arg x +say 'Get primes up to' x +numeric digits 10 +call Primes(x) +say Format(Time('e'),,3) 'seconds'; say +return + +LPbelow500: +call Time('r') +say 'Long primes < 500' +p = 0 +do i = 1 to prim.0 until p > 500 + p = prim.i + if p-qperiod(1 p) = 1 then + call Charout ,p' ' +end +say +say Format(Time('e'),,3) 'seconds'; say +return + +NumberOfLP: +call Time('r') +say 'Number of long primes up to' +t = '500 1000 2000 4000 8000 16000 32000 64000 0' +w = 1; a = Word(t,1); n = 0 +do i = 1 to prim.0 while a > 0 + p = prim.i + if p > a then do + say Right(a,5) Right(n,4) + w = w+1; a = Word(t,w) + end + if p-qperiodinv(p) = 1 then do + n = n+1 + end +end +say Format(Time('e'),,3) 'seconds'; say +return + +include Functions +include Sequences +include Rational +include Constants +include Abend diff --git a/Task/Longest-string-challenge/C-sharp/longest-string-challenge.cs b/Task/Longest-string-challenge/C-sharp/longest-string-challenge.cs new file mode 100644 index 0000000000..23351f5c8c --- /dev/null +++ b/Task/Longest-string-challenge/C-sharp/longest-string-challenge.cs @@ -0,0 +1,36 @@ +string[] input = ["a", "bb", "ccc", "ddd", "ee", "f", "ggg"]; + +#pragma warning disable CA1860 // Avoid using 'Enumerable.Any()' extension method + +string longest = ""; +string template = ""; + +foreach (string line in input) +{ + string t = template; + string l = line; + + foreach (var _ in line) + { + if (t.Any()) + t = t[..^1]; + else + { + longest = ""; + template = line; + break; + } + + if (l.Any()) + l = l[..^1]; + } + + if (!t.Any()) + longest += line; // string concatenation, not addition +} + +while (longest.Any()) +{ + Console.WriteLine(longest[..template.Length]); + longest = longest[template.Length..]; +} diff --git a/Task/Look-and-say-sequence/EasyLang/look-and-say-sequence.easy b/Task/Look-and-say-sequence/EasyLang/look-and-say-sequence.easy index 94c6316232..9d91e1f128 100644 --- a/Task/Look-and-say-sequence/EasyLang/look-and-say-sequence.easy +++ b/Task/Look-and-say-sequence/EasyLang/look-and-say-sequence.easy @@ -1,4 +1,4 @@ -proc lookandsay . a$ . +proc lookandsay &a$ . c = 1 p$ = substr a$ 1 1 for i = 2 to len a$ diff --git a/Task/Look-and-say-sequence/MAD/look-and-say-sequence.mad b/Task/Look-and-say-sequence/MAD/look-and-say-sequence.mad new file mode 100644 index 0000000000..09a9de2f77 --- /dev/null +++ b/Task/Look-and-say-sequence/MAD/look-and-say-sequence.mad @@ -0,0 +1,36 @@ + NORMAL MODE IS INTEGER + + INTERNAL FUNCTION(XX) + ENTRY TO LOKSAY. + X = XX + + THROUGH CTDGT, FOR K = 1, 0, K.G.X +CTDGT K = K*10 + K = K/10 + R = 0 + DS = 0 + +GROUP D = X/K + X = X-K*D + K = K/10 + + WHENEVER DS.NE.D + WHENEVER DS.NE.0, R = R*100 + N*10 + DS + N = 1 + DS = D + OTHERWISE + N = N+1 + END OF CONDITIONAL + + WHENEVER K.NE.0, TRANSFER TO GROUP + R = R*100 + N*10 + DS + FUNCTION RETURN R + END OF FUNCTION + + VECTOR VALUES FMT = $I20*$ + L = 1 + THROUGH STEP, FOR I=1, 1, I.GE.10 + PRINT FORMAT FMT, L +STEP L = LOKSAY.(L) + + END OF PROGRAM diff --git a/Task/Look-and-say-sequence/Python/look-and-say-sequence-5.py b/Task/Look-and-say-sequence/Python/look-and-say-sequence-5.py new file mode 100644 index 0000000000..a48a7400bc --- /dev/null +++ b/Task/Look-and-say-sequence/Python/look-and-say-sequence-5.py @@ -0,0 +1,9 @@ +from more_itertools import groupby_transform, take, ilen + +def lookandsay(seq = "1"): + yield seq + while True: + yield (seq := "".join(f"{count}{n}" for n, count in + groupby_transform(seq, reducefunc = ilen))) + +list(take(5, lookandsay())) diff --git a/Task/Look-and-say-sequence/SETL/look-and-say-sequence.setl b/Task/Look-and-say-sequence/SETL/look-and-say-sequence.setl index 31c8cbd598..3dbfe302cf 100644 --- a/Task/Look-and-say-sequence/SETL/look-and-say-sequence.setl +++ b/Task/Look-and-say-sequence/SETL/look-and-say-sequence.setl @@ -6,18 +6,10 @@ program looksay; end loop; proc looksay(s); - loop for c in s do; - if cur /= c then - if count /= om then - r +:= count + cur; - end if; - cur := c; - count := 1; - else - count +:= 1; - end if; + loop init r := ""; while s /= "" do + p := span(s, s(1)); + r +:= str(#p) + p(1); end loop; - r +:= count + cur; return r; end proc; end looksay; diff --git a/Task/Loop-over-multiple-arrays-simultaneously/Ballerina/loop-over-multiple-arrays-simultaneously.ballerina b/Task/Loop-over-multiple-arrays-simultaneously/Ballerina/loop-over-multiple-arrays-simultaneously.ballerina new file mode 100644 index 0000000000..62f6f4661e --- /dev/null +++ b/Task/Loop-over-multiple-arrays-simultaneously/Ballerina/loop-over-multiple-arrays-simultaneously.ballerina @@ -0,0 +1,10 @@ +import ballerina/io; + +public function main() { + var a1 = ["a", "b", "c"]; + var a2 = ["A", "B", "C"]; + var a3 = [1, 2, 3]; + foreach int i in a3 { + io:println(a1[i-1], a2[i-1], i); + } +} diff --git a/Task/Loops-Break/ALGOL-68/loops-break.alg b/Task/Loops-Break/ALGOL-68/loops-break.alg index 7a05d01147..739def288e 100644 --- a/Task/Loops-Break/ALGOL-68/loops-break.alg +++ b/Task/Loops-Break/ALGOL-68/loops-break.alg @@ -1,13 +1,11 @@ -main: ( - INT a, b; - INT seed := 4; # chosen by a fair dice roll, guaranteed to be random c.f. http://xkcd.com/221/ # - # first random; # +#main# +( WHILE - a := ENTIER (next random(seed) * 20); + INT a = ENTIER (random * 20); print((a)); - # WHILE # NOT (a = 10) DO - b := ENTIER (next random(seed) * 20); - print((b, new line)) + a /= 10 + DO + print((ENTIER (random * 20), new line)) OD; print(new line) ) diff --git a/Task/Loops-Break/Ballerina/loops-break.ballerina b/Task/Loops-Break/Ballerina/loops-break.ballerina new file mode 100644 index 0000000000..c28087524c --- /dev/null +++ b/Task/Loops-Break/Ballerina/loops-break.ballerina @@ -0,0 +1,12 @@ +import ballerina/io; +import ballerina/random; + +public function main() returns error? { + while true { + int n = check random:createIntInRange(0, 20); + io:println(n); + if n == 10 { break; } + n = check random:createIntInRange(0, 20); + io:println(n); + } +} diff --git a/Task/Loops-Break/Uxntal/loops-break.uxnatl b/Task/Loops-Break/Uxntal/loops-break.uxnatl new file mode 100644 index 0000000000..97d03ed8e7 --- /dev/null +++ b/Task/Loops-Break/Uxntal/loops-break.uxnatl @@ -0,0 +1,62 @@ +%newline { [ LIT2 0a -Console/write ] DEO } +%tab { [ LIT2 09 -Console/write ] DEO } +%MOD ( a b -- a%b ) { DIVk MUL SUB } + +|18 @Console/write +|c0 @DateTime/year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 + +|100 + +rand/init + +&loop + rand/0:13 DUP print/dec tab + #0a NEQ ?{ + newline !&break } + rand/0:13 print/dec newline + !&loop + +&break + +BRK + +@print/dec ( dec -- ) + DUP #64 DIV /num + DUP #0a DIV /num + ( >> ) + +@print/num_ ( num -- ) + #0a DIVk MUL SUB [ LIT "0 ] ADD .Console/write DEO + JMP2r + +@print/num ( num -- ) + DUP ?&num_ + POP + JMP2r + +@rand/init ( -- ) + [ LIT2 00 -DateTime/second ] DEI + [ LIT2 00 -DateTime/minute ] DEI #60 SFT2 EOR2 + [ LIT2 00 -DateTime/hour ] DEI #c0 SFT2 EOR2 ,&x STR2 + [ LIT2 00 -DateTime/hour ] DEI #04 SFT2 + [ LIT2 00 -DateTime/day ] DEI #10 SFT2 EOR2 + [ LIT2 00 -DateTime/month ] DEI #60 SFT2 EOR2 + .DateTime/year DEI2 #a0 SFT2 EOR2 ,&y STR2 + JMP2r + +@rand/short ( -- number* ) + [ LIT2 &x $2 ] + DUP2 #50 SFT2 EOR2 + DUP2 #03 SFT2 EOR2 + [ LIT2 &y $2 ] DUP2 ,&x STR2 + DUP2 #01 SFT2 EOR2 EOR2 + ,&y STR2k POP + JMP2r + +@rand/byte ( -- number ) + /short AND + JMP2r + +@rand/0:13 ( -- U[0,13] ) + /byte #14 MOD + JMP2r diff --git a/Task/Loops-Continue/Ballerina/loops-continue.ballerina b/Task/Loops-Continue/Ballerina/loops-continue.ballerina new file mode 100644 index 0000000000..1dc361e882 --- /dev/null +++ b/Task/Loops-Continue/Ballerina/loops-continue.ballerina @@ -0,0 +1,12 @@ +import ballerina/io; + +public function main() { + foreach int i in 1...10 { + io:print(i); + if i % 5 == 0 { + io:println(); + continue; + } + io:print(", "); + } +} diff --git a/Task/Loops-Continue/Uxntal/loops-continue.uxnatl b/Task/Loops-Continue/Uxntal/loops-continue.uxnatl new file mode 100644 index 0000000000..8e43bba3fe --- /dev/null +++ b/Task/Loops-Continue/Uxntal/loops-continue.uxnatl @@ -0,0 +1,31 @@ +%newline { [ LIT2 0a -Console/write ] DEO } +%comma { [ LIT2 ", -Console/write ] DEO } +%space { [ LIT2 20 -Console/write ] DEO } +%MOD ( a b -- a%b ) { DIVk MUL SUB } + +|18 @Console/write + +|100 + +#0b01 +&loop + DUP print-dec + DUP #05 MOD ?{ + newline !&continue } + comma space + &continue + INC GTHk ?&loop +POP2 +BRK + +@print-dec ( dec -- ) + DUP #64 DIV print-num/try + DUP #0a DIV print-num/try + ( >> ) + +@print-num ( num -- ) + #0a DIVk MUL SUB [ LIT "0 ] ADD .Console/write DEO + JMP2r + &try ( num -- ) + DUP ?print-num + POP JMP2r diff --git a/Task/Loops-Do-while/Ballerina/loops-do-while-1.ballerina b/Task/Loops-Do-while/Ballerina/loops-do-while-1.ballerina new file mode 100644 index 0000000000..aee89996e5 --- /dev/null +++ b/Task/Loops-Do-while/Ballerina/loops-do-while-1.ballerina @@ -0,0 +1,10 @@ +import ballerina/io; + +public function main() { + int v = 0; + while true { + v += 1; + io:println(v); + if v % 6 == 0 { break; } + } +} diff --git a/Task/Loops-Do-while/Ballerina/loops-do-while-2.ballerina b/Task/Loops-Do-while/Ballerina/loops-do-while-2.ballerina new file mode 100644 index 0000000000..9ebeed7b64 --- /dev/null +++ b/Task/Loops-Do-while/Ballerina/loops-do-while-2.ballerina @@ -0,0 +1,11 @@ +import ballerina/io; + +public function main() { + int value = 0; + boolean ok = true; + while ok { + value += 1; + io:println(value); + ok = value % 6 != 0; + } +} diff --git a/Task/Loops-Do-while/SETL/loops-do-while.setl b/Task/Loops-Do-while/SETL/loops-do-while.setl new file mode 100644 index 0000000000..dcbd441f9d --- /dev/null +++ b/Task/Loops-Do-while/SETL/loops-do-while.setl @@ -0,0 +1,7 @@ +program dowhile; + value := 0; + loop until value mod 6 = 0 do + print(value); + value +:= 1; + end loop; +end program; diff --git a/Task/Loops-Do-while/Uxntal/loops-do-while.uxnatl b/Task/Loops-Do-while/Uxntal/loops-do-while.uxnatl new file mode 100644 index 0000000000..9ca41f10d4 --- /dev/null +++ b/Task/Loops-Do-while/Uxntal/loops-do-while.uxnatl @@ -0,0 +1,22 @@ +%newline { [ LIT2 0a -Console/write ] DEO } +%MOD ( a b -- a%b ) { DIVk MUL SUB } + +|18 @Console/write + +|100 + +#00 +&do-while + INC DUP print-hex/byte newline + DUP #06 MOD ?&do-while +POP + +BRK + +@print-hex ( short* -- ) + SWP /byte + &byte ( byte -- ) + DUP #04 SFT /nibble + &nibble ( byte -- ) + #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO + JMP2r diff --git a/Task/Loops-Downward-for/Ballerina/loops-downward-for.ballerina b/Task/Loops-Downward-for/Ballerina/loops-downward-for.ballerina new file mode 100644 index 0000000000..d77ab4f583 --- /dev/null +++ b/Task/Loops-Downward-for/Ballerina/loops-downward-for.ballerina @@ -0,0 +1,8 @@ +import ballerina/io; + +public function main() { + foreach int i in int:range(10, -1, -1) { + io:print(i, " "); + } + io:println(); +} diff --git a/Task/Loops-For-with-a-specified-step/Ballerina/loops-for-with-a-specified-step.ballerina b/Task/Loops-For-with-a-specified-step/Ballerina/loops-for-with-a-specified-step.ballerina new file mode 100644 index 0000000000..c2cda1fdc8 --- /dev/null +++ b/Task/Loops-For-with-a-specified-step/Ballerina/loops-for-with-a-specified-step.ballerina @@ -0,0 +1,9 @@ +import ballerina/io; + +public function main() { + // print odd numbers from 1 to 9 + foreach int i in int:range(1, 10, 2) { + io:print(i, " "); + } + io:println(); +} diff --git a/Task/Loops-For-with-a-specified-step/Uxntal/loops-for-with-a-specified-step.uxnatl b/Task/Loops-For-with-a-specified-step/Uxntal/loops-for-with-a-specified-step.uxnatl new file mode 100644 index 0000000000..fdc85b0850 --- /dev/null +++ b/Task/Loops-For-with-a-specified-step/Uxntal/loops-for-with-a-specified-step.uxnatl @@ -0,0 +1,20 @@ +%newline { [ LIT2 0a -Console/write ] DEO } + +|18 @Console/write + +|100 + +#1000 [ LITr 02 ] +&loop + DUP print/byte newline + STHkr ADD GTHk ?&loop +POP2 POPr + +BRK + +@print/byte ( byte -- ) + DUP #04 SFT /nibble + + &nibble ( byte -- ) + #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD .Console/write DEO + JMP2r diff --git a/Task/Loops-For/Ballerina/loops-for.ballerina b/Task/Loops-For/Ballerina/loops-for.ballerina new file mode 100644 index 0000000000..b8319f1317 --- /dev/null +++ b/Task/Loops-For/Ballerina/loops-for.ballerina @@ -0,0 +1,8 @@ +import ballerina/io; + +public function main() { + foreach int i in 1...5 { + foreach int j in 1...i { io:print("*"); } + io:println(); + } +} diff --git a/Task/Loops-For/Excel/loops-for.excel b/Task/Loops-For/Excel/loops-for.excel new file mode 100644 index 0000000000..49ea28564d --- /dev/null +++ b/Task/Loops-For/Excel/loops-for.excel @@ -0,0 +1,9 @@ +=REDUCE( + "", SEQUENCE(6), + LAMBDA(outer, i, + VSTACK( + outer, + REDUCE("", SEQUENCE(i), LAMBDA(inner, j, inner & "*")) + ) + ) + ) diff --git a/Task/Loops-For/M2000-Interpreter/loops-for-1.m2000 b/Task/Loops-For/M2000-Interpreter/loops-for-1.m2000 new file mode 100644 index 0000000000..00945aafb2 --- /dev/null +++ b/Task/Loops-For/M2000-Interpreter/loops-for-1.m2000 @@ -0,0 +1,4 @@ +MODULE check { +FOR I=1 TO 5:FOR I=I to 1:?"*";:NEXT:?:NEXT +} +check diff --git a/Task/Loops-For/M2000-Interpreter/loops-for-2.m2000 b/Task/Loops-For/M2000-Interpreter/loops-for-2.m2000 new file mode 100644 index 0000000000..1603228d5e --- /dev/null +++ b/Task/Loops-For/M2000-Interpreter/loops-for-2.m2000 @@ -0,0 +1,17 @@ +module check { + For i=1 to 5 + For j=1 to i + Print "*"; + Next j + Print + Next i + Print "End1" + For i=1 to 5 { + For j=1 to i { + Print "*"; + } + Print + } + Print "End2" +} +check diff --git a/Task/Loops-For/M2000-Interpreter/loops-for.m2000 b/Task/Loops-For/M2000-Interpreter/loops-for.m2000 deleted file mode 100644 index 7d6e060448..0000000000 --- a/Task/Loops-For/M2000-Interpreter/loops-for.m2000 +++ /dev/null @@ -1,14 +0,0 @@ -For i=1 to 5 - For j=1 to i - Print "*"; - Next j - Print -Next i -Print "End1" -For i=1 to 5 { - For j=1 to i { - Print "*"; - } - Print -} -Print "End2" diff --git a/Task/Loops-Foreach/Ballerina/loops-foreach.ballerina b/Task/Loops-Foreach/Ballerina/loops-foreach.ballerina new file mode 100644 index 0000000000..be3ab5ec8e --- /dev/null +++ b/Task/Loops-Foreach/Ballerina/loops-foreach.ballerina @@ -0,0 +1,8 @@ +import ballerina/io; + +public function main() { + string[] birds = ["Swan", "Eagle", "Wren"]; + foreach string bird in birds { + io:println(bird); + } +} diff --git a/Task/Loops-Foreach/Uxntal/loops-foreach.uxnatl b/Task/Loops-Foreach/Uxntal/loops-foreach.uxnatl new file mode 100644 index 0000000000..85cd75c797 --- /dev/null +++ b/Task/Loops-Foreach/Uxntal/loops-foreach.uxnatl @@ -0,0 +1,44 @@ +%newline { [ LIT2 0a -Console/write ] DEO } +%space { [ LIT2 20 -Console/write ] DEO } + +|18 @Console/write + +|100 + +@on-reset ( -> ) + ;array ;print-element foreach + newline + + ;array ;double foreach + + ;array ;print-element foreach + newline + + BRK + +@double ( addr* -- addr* ) + STH2k LDAk + DUP ADD + STH2r STA + JMP2r + +@print-element ( addr* -- addr* ) + LDAk print-byte space + JMP2r + +@print-byte ( byte -- ) + DUP #04 SFT /nibble + &nibble ( byte -- ) + #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO + JMP2r + +@foreach ( bytes* fn* -- bytes* ) + STH2 + LDA2k SWP2 INC2 INC2 + &l ( -- ) + STH2kr JSR2 + INC2 GTH2k ?&l + POP2r POP2 POP2 + JMP2r + +@array ={ 00 01 02 02 04 } diff --git a/Task/Loops-Increment-loop-index-within-loop-body/ALGOL-60/loops-increment-loop-index-within-loop-body.alg b/Task/Loops-Increment-loop-index-within-loop-body/ALGOL-60/loops-increment-loop-index-within-loop-body.alg new file mode 100644 index 0000000000..4e936cae74 --- /dev/null +++ b/Task/Loops-Increment-loop-index-within-loop-body/ALGOL-60/loops-increment-loop-index-within-loop-body.alg @@ -0,0 +1,43 @@ +begin + +boolean procedure isprime(n); +value n; integer n; +begin + if n < 2 then + isprime := false + else if n = entier(n / 2) * 2 then + isprime := (n = 2) + else + begin + comment - check odd divisors up to sqrt(n); + integer i, limit; + boolean divisible; + i := 3; + limit := entier(sqrt(n)); + divisible := false; + for i := i while i <= limit and not divisible do + begin + if entier(n / i) * i = n then + divisible := true; + i := i + 2 + end; + isprime := not divisible; + end; +end; + +integer i, count; + +count := 0; +for i := 42, i + 1 while count < 26 do + begin + if isprime(i) then + begin + count := count + 1; + outinteger(1,count); + outinteger(1,i); + i := i + (i - 1); + outstring(1,"\n"); + end; + end; + +end diff --git a/Task/Loops-Increment-loop-index-within-loop-body/Ballerina/loops-increment-loop-index-within-loop-body.ballerina b/Task/Loops-Increment-loop-index-within-loop-body/Ballerina/loops-increment-loop-index-within-loop-body.ballerina new file mode 100644 index 0000000000..242fca7859 --- /dev/null +++ b/Task/Loops-Increment-loop-index-within-loop-body/Ballerina/loops-increment-loop-index-within-loop-body.ballerina @@ -0,0 +1,39 @@ +import ballerina/io; + +function isPrime(int n) returns boolean { + if n < 2 { return false; } + if n % 2 == 0 { return n == 2; } + if n % 3 == 0 { return n == 3; } + int d = 5; + while d * d <= n { + if n % d == 0 { return false; } + d += 2; + if n % d == 0 { return false; } + d += 4; + } + return true; +} + +function commatize(int n) returns string { + string s = n.toString(); + if n < 0 { s = s.substring(1); } + int le = s.length(); + foreach int i in int:range(le - 3, 0, -3) { + s = s.substring(0, i) + "," + s.substring(i); + } + if n >= 0 { return s; } + return "-" + s; +} + +public function main() { + int c = 0; + int i = 42; + while c < 42 { + if isPrime(i) { + c += 1; + io:println(commatize(c).padStart(2), ": ", commatize(i).padStart(18)); + i = 2 * i - 1; + } + i += 1; + } +} diff --git a/Task/Loops-Increment-loop-index-within-loop-body/Icon/loops-increment-loop-index-within-loop-body.icon b/Task/Loops-Increment-loop-index-within-loop-body/Icon/loops-increment-loop-index-within-loop-body.icon new file mode 100644 index 0000000000..225a4cef48 --- /dev/null +++ b/Task/Loops-Increment-loop-index-within-loop-body/Icon/loops-increment-loop-index-within-loop-body.icon @@ -0,0 +1,40 @@ +procedure main() + I_START := 42 + LIMIT := I_START + + i := I_START + n := 0 + until n = LIMIT do { + if is_prime(i) then { + n +:= 1 + write(right(n,2),": ",comma_string(i)) + i +:= i + } else + i +:= 1 + } +end + +procedure is_prime(n) + if n < 2 then fail + if n%2 = 0 then return n = 2 + if n%3 = 0 then return n = 3 + d := 5 + while d*d <= n do { + if n%d = 0 then fail + d +:= 2 + if n%d = 0 then fail + d +:= 4 + } + return n +end + +procedure comma_string(n) + s := "" + n ? { + tab(0) + while s := "," || move(-3) || s + if pos(1) then s := s[2:0] + else s := tab(1) || s + } + return s +end diff --git a/Task/Loops-Increment-loop-index-within-loop-body/S-BASIC/loops-increment-loop-index-within-loop-body.basic b/Task/Loops-Increment-loop-index-within-loop-body/S-BASIC/loops-increment-loop-index-within-loop-body.basic new file mode 100644 index 0000000000..0638a054ae --- /dev/null +++ b/Task/Loops-Increment-loop-index-within-loop-body/S-BASIC/loops-increment-loop-index-within-loop-body.basic @@ -0,0 +1,41 @@ +$lines + +$constant FALSE = 0 +$constant TRUE = 0FFFFH + +rem - return n mod m +function mod(n, m = integer) = integer +end = n - m * (n / m) + +rem - return true if n is prime, otherwise false +function isprime(n = integer) = integer + var i, limit, result = integer + if n = 2 then + result = TRUE + else if (n < 2) or (mod(n,2) = 0) then + result = FALSE + else + begin + limit = int(sqr(n)) + i = 3 + while (i <= limit) and (mod(n, i) <> 0) do + i = i + 2 + result = not (i <= limit) + end +end = result + +var i, count = integer +count = 0 +for i = 42 to 32760 + if isprime(i) then + begin + count = count + 1 + print using "## ##,###"; count; i + if count >= 10 then + i = 32760 + else + i = i + (i - 1) + end +next i + +end diff --git a/Task/Loops-Increment-loop-index-within-loop-body/SETL/loops-increment-loop-index-within-loop-body.setl b/Task/Loops-Increment-loop-index-within-loop-body/SETL/loops-increment-loop-index-within-loop-body.setl new file mode 100644 index 0000000000..53e7fbebff --- /dev/null +++ b/Task/Loops-Increment-loop-index-within-loop-body/SETL/loops-increment-loop-index-within-loop-body.setl @@ -0,0 +1,29 @@ +program primes42; + loop + init n := 42; p := 0; + step n +:= 1; + until p = 42 do + if prime(n) then + print(lpad(str(p +:= 1), 2) + ": " + lpad(commatize(n), 20)); + n +:= n; + end if; + end loop; + + proc prime(n); + if n<=4 then return n in [2,3]; end if; + if n mod 2=0 or n mod 3=0 then return False; end if; + loop init d := 5; while d*d <= n do + if n mod d=0 then return false; end if; + d +:= 2; + if n mod d=0 then return false; end if; + d +:= 4; + end loop; + return True; + end proc; + + proc commatize(n); + if n<1000 then return str n; end if; + p := "00" + str(n mod 1000); + return commatize(n div 1000) + "," + p(#p-2..#p); + end proc; +end program; diff --git a/Task/Loops-Infinite/8080-Assembly/loops-infinite.8080 b/Task/Loops-Infinite/8080-Assembly/loops-infinite.8080 new file mode 100644 index 0000000000..bb674eb167 --- /dev/null +++ b/Task/Loops-Infinite/8080-Assembly/loops-infinite.8080 @@ -0,0 +1,7 @@ +puts equ 9 + org 100h +spam: mvi c,puts + lxi d,msg + call 5 + jmp spam +msg: db 'SPAM',13,10,'$' diff --git a/Task/Loops-Infinite/APL/loops-infinite.apl b/Task/Loops-Infinite/APL/loops-infinite.apl new file mode 100644 index 0000000000..31386930a9 --- /dev/null +++ b/Task/Loops-Infinite/APL/loops-infinite.apl @@ -0,0 +1 @@ +{⎕←'SPAM'}⍣(0⍨)'' diff --git a/Task/Loops-Infinite/Ballerina/loops-infinite.ballerina b/Task/Loops-Infinite/Ballerina/loops-infinite.ballerina new file mode 100644 index 0000000000..76181e3d77 --- /dev/null +++ b/Task/Loops-Infinite/Ballerina/loops-infinite.ballerina @@ -0,0 +1,7 @@ +import ballerina/io; + +public function main() { + while true { + io:println("SPAM"); + } +} diff --git a/Task/Loops-Infinite/J/loops-infinite-1.j b/Task/Loops-Infinite/J/loops-infinite-1.j index 22a89d8a2f..5cac1e6adc 100644 --- a/Task/Loops-Infinite/J/loops-infinite-1.j +++ b/Task/Loops-Infinite/J/loops-infinite-1.j @@ -1 +1 @@ - ]F.(echo@'SPAM')0 +echo@'SPAM'F.] '' diff --git a/Task/Loops-Infinite/J/loops-infinite-2.j b/Task/Loops-Infinite/J/loops-infinite-2.j index 2c906353a0..3cadb11b3c 100644 --- a/Task/Loops-Infinite/J/loops-infinite-2.j +++ b/Task/Loops-Infinite/J/loops-infinite-2.j @@ -1 +1 @@ -smoutput bind 'SPAM'^:1e99 '' +echo@'SPAM'^:1e99 '' diff --git a/Task/Loops-Infinite/J/loops-infinite-3.j b/Task/Loops-Infinite/J/loops-infinite-3.j new file mode 100644 index 0000000000..ea7c71c2b1 --- /dev/null +++ b/Task/Loops-Infinite/J/loops-infinite-3.j @@ -0,0 +1 @@ +echo@'SPAM'^:1:^:_. '' diff --git a/Task/Loops-Infinite/K/loops-infinite-1.k b/Task/Loops-Infinite/K/loops-infinite-1.k new file mode 100644 index 0000000000..d379f117c3 --- /dev/null +++ b/Task/Loops-Infinite/K/loops-infinite-1.k @@ -0,0 +1 @@ +{1}{`0:"SPAM"}/"" diff --git a/Task/Loops-Infinite/K/loops-infinite-2.k b/Task/Loops-Infinite/K/loops-infinite-2.k new file mode 100644 index 0000000000..8b7a637bd0 --- /dev/null +++ b/Task/Loops-Infinite/K/loops-infinite-2.k @@ -0,0 +1 @@ +while[1; `0:"SPAM"] diff --git a/Task/Loops-Infinite/K/loops-infinite.k b/Task/Loops-Infinite/K/loops-infinite.k deleted file mode 100644 index 6cdd8e40ea..0000000000 --- a/Task/Loops-Infinite/K/loops-infinite.k +++ /dev/null @@ -1 +0,0 @@ - while[1; `0:"SPAM\n"] diff --git a/Task/Loops-Infinite/Miranda/loops-infinite.miranda b/Task/Loops-Infinite/Miranda/loops-infinite.miranda new file mode 100644 index 0000000000..7490112585 --- /dev/null +++ b/Task/Loops-Infinite/Miranda/loops-infinite.miranda @@ -0,0 +1,2 @@ +main :: [sys_message] +main = repeat (Stdout "SPAM\n") diff --git a/Task/Loops-Infinite/Refal/loops-infinite.refal b/Task/Loops-Infinite/Refal/loops-infinite.refal new file mode 100644 index 0000000000..2bc91fdc6c --- /dev/null +++ b/Task/Loops-Infinite/Refal/loops-infinite.refal @@ -0,0 +1 @@ +$ENTRY Go { = ; }; diff --git a/Task/Loops-Infinite/SETL/loops-infinite.setl b/Task/Loops-Infinite/SETL/loops-infinite.setl new file mode 100644 index 0000000000..f54622e636 --- /dev/null +++ b/Task/Loops-Infinite/SETL/loops-infinite.setl @@ -0,0 +1,5 @@ +program spam; + loop do + print("SPAM"); + end loop; +end program; diff --git a/Task/Loops-Infinite/Uxntal/loops-infinite.uxnatl b/Task/Loops-Infinite/Uxntal/loops-infinite.uxnatl index 407bc40473..19d18d3e75 100644 --- a/Task/Loops-Infinite/Uxntal/loops-infinite.uxnatl +++ b/Task/Loops-Infinite/Uxntal/loops-infinite.uxnatl @@ -1,9 +1,11 @@ +|10 @Console/vector $2 &read $5 &type $1 &write $1 &error $1 + |0100 - &l ;SPAM !&l + &loop ;SPAM !&loop @ ( str* -- ) - &while ( -- ) - LDAk #18 DEO + &while + LDAk .Console/write DEO INC2 LDAk ?&while POP2 JMP2r diff --git a/Task/Loops-N-plus-one-half/Ballerina/loops-n-plus-one-half.ballerina b/Task/Loops-N-plus-one-half/Ballerina/loops-n-plus-one-half.ballerina new file mode 100644 index 0000000000..72a085465a --- /dev/null +++ b/Task/Loops-N-plus-one-half/Ballerina/loops-n-plus-one-half.ballerina @@ -0,0 +1,8 @@ +import ballerina/io; + +public function main() { + foreach int i in 1...10 { + io:print(i); + io:print(i < 10 ? ", " : "\n"); + } +} diff --git a/Task/Loops-N-plus-one-half/Crystal/loops-n-plus-one-half.cr b/Task/Loops-N-plus-one-half/Crystal/loops-n-plus-one-half.cr new file mode 100644 index 0000000000..6e12440371 --- /dev/null +++ b/Task/Loops-N-plus-one-half/Crystal/loops-n-plus-one-half.cr @@ -0,0 +1,6 @@ +(1..).each do |i| + print i + break if i == 10 + print ", " +end +puts diff --git a/Task/Loops-N-plus-one-half/Uxntal/loops-n-plus-one-half.uxnatl b/Task/Loops-N-plus-one-half/Uxntal/loops-n-plus-one-half.uxnatl new file mode 100644 index 0000000000..71a6de9be5 --- /dev/null +++ b/Task/Loops-N-plus-one-half/Uxntal/loops-n-plus-one-half.uxnatl @@ -0,0 +1,34 @@ +%newline { [ LIT2 0a -Console/write ] DEO } +%comma { [ LIT2 ", -Console/write ] DEO } +%space { [ LIT2 20 -Console/write ] DEO } + +|18 @Console/write + +|100 + +#0b01 +&loop + DUP print/dec + DUP #0a NEQ ?{ + newline !&break } + comma space + INC !&loop + + &break + POP2 + +BRK + +@print/dec ( dec -- ) + DUP #64 DIV /num + DUP #0a DIV /num + ( >> ) + +@print/num_ ( num -- ) + #0a DIVk MUL SUB [ LIT "0 ] ADD .Console/write DEO + JMP2r + +@print/num ( num -- ) + DUP ?/num_ + POP + JMP2r diff --git a/Task/Loops-Nested/Ballerina/loops-nested.ballerina b/Task/Loops-Nested/Ballerina/loops-nested.ballerina new file mode 100644 index 0000000000..3478634506 --- /dev/null +++ b/Task/Loops-Nested/Ballerina/loops-nested.ballerina @@ -0,0 +1,23 @@ +import ballerina/io; +import ballerina/random; + +public function main() returns error? { + int[20][20] a = []; + foreach int i in 0...19 { + foreach int j in 0...19 { + a[i][j] = check random:createIntInRange(1, 21); + } + } + boolean found = false; + foreach int i in 0...19 { + foreach int j in 0...19 { + io:print(a[i][j].toString().padStart(3)); + if a[i][j] == 20 { + found = true; + break; + } + } + io:println(); + if found { break; } + } +} diff --git a/Task/Loops-Nested/Icon/loops-nested-1.icon b/Task/Loops-Nested/Icon/loops-nested-1.icon index 9aef91e5d8..fa607e1622 100644 --- a/Task/Loops-Nested/Icon/loops-nested-1.icon +++ b/Task/Loops-Nested/Icon/loops-nested-1.icon @@ -2,9 +2,14 @@ procedure main() every !(!(L := list(10)) := list(10)) := ?20 # setup a 2d array of random numbers up to 20 -every i := 1 to *L do # using nested loops - every j := 1 to *L[i] do - if L[i,j] = 20 then - break break write("L[",i,",",j,"]=20") - +every i := 1 to *L do{ # using nested loops + every j := 1 to *L[i] do{ + writes(" ",L[i,j]) + if L[i,j] = 20 then{ + write() + break break + } + } + write() +} end diff --git a/Task/Loops-Nested/Icon/loops-nested-2.icon b/Task/Loops-Nested/Icon/loops-nested-2.icon index f6ed64f558..ac36bec12b 100644 --- a/Task/Loops-Nested/Icon/loops-nested-2.icon +++ b/Task/Loops-Nested/Icon/loops-nested-2.icon @@ -1,4 +1 @@ -every x := L[i := 1 to *L,1 to *L[i]] do - if x = 20 then break write("L[",i,",",j,"]=20") # more succinctly - -every if !!L = 20 then break write("Found !!L=20") # even more so (but looses the values of i and j +e := !!L & write(e) & e = 20 diff --git a/Task/Loops-While/Ballerina/loops-while.ballerina b/Task/Loops-While/Ballerina/loops-while.ballerina index d56c901d69..ad6e887212 100644 --- a/Task/Loops-While/Ballerina/loops-while.ballerina +++ b/Task/Loops-While/Ballerina/loops-while.ballerina @@ -1,5 +1,9 @@ -int i = 1024; -while i > 0 { - io:println(i); - i = i / 2; +import ballerina/io; + +public function main() { + int i = 1024; + while i > 0 { + io:println(i); + i = i / 2; + } } diff --git a/Task/Loops-While/Uxntal/loops-while.uxnatl b/Task/Loops-While/Uxntal/loops-while.uxnatl new file mode 100644 index 0000000000..6bb868c471 --- /dev/null +++ b/Task/Loops-While/Uxntal/loops-while.uxnatl @@ -0,0 +1,21 @@ +%newline { [ LIT2 0a -Console/write ] DEO } + +|18 @Console/write + +|100 + +#0000 #0400 +&while EQU2k ?{ + DUP2 print-hex newline + #01 SFT2 !&while } +POP2 POP2 + +BRK + +@print-hex ( short* -- ) + SWP /byte + &byte ( byte -- ) + DUP #04 SFT /nibble + &nibble ( byte -- ) + #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO + JMP2r diff --git a/Task/Loops-With-multiple-ranges/Ballerina/loops-with-multiple-ranges.ballerina b/Task/Loops-With-multiple-ranges/Ballerina/loops-with-multiple-ranges.ballerina new file mode 100644 index 0000000000..b63acc7fd3 --- /dev/null +++ b/Task/Loops-With-multiple-ranges/Ballerina/loops-with-multiple-ranges.ballerina @@ -0,0 +1,82 @@ +import ballerina/io; + +function pow(int n, int e) returns int { + if e < 1 { return 1; } + int prod = 1; + foreach int i in 1...e { prod *= n; } + return prod; +} + +function commatize(int n) returns string { + string s = n.toString(); + if n < 0 { s = s.substring(1); } + int le = s.length(); + foreach int i in int:range(le - 3, 0, -3) { + s = s.substring(0, i) + "," + s.substring(i); + } + if n >= 0 { return s; } + return "-" + s; +} + +public function main() { + int prod = 1; + int sum = 0; + int x = 5; + int y = -5; + int z = -2; + int one = 1; + int three = 3; + int seven = 7; + int p = pow(11, x); + int j = 0; + + var process = function() { + sum += j.abs(); + if (prod.abs() < (1 << 27) && j != 0) { prod *= j; } + }; + + j = -three; + while j <= pow(3, 3) { + process(); + j += three; + } + + j = -seven; + while j <= seven { + process(); + j += x; + } + + j = 555; + while j <= 550 - y { + process(); + j += 1; + } + + j = 22; + while j >= -28 { + process(); + j -= three; + } + + j = 1927; + while j <= 1939 { + process(); + j += 1; + } + + j = x; + while j >= y { + process(); + j -= -z; + } + + j = p; + while j <= p + one { + process(); + j += 1; + } + + io:println("sum = ", commatize(sum)); + io:println("prod = ", commatize(prod)); +} diff --git a/Task/Loops-Wrong-ranges/Ballerina/loops-wrong-ranges.ballerina b/Task/Loops-Wrong-ranges/Ballerina/loops-wrong-ranges.ballerina new file mode 100644 index 0000000000..7e8774e3e7 --- /dev/null +++ b/Task/Loops-Wrong-ranges/Ballerina/loops-wrong-ranges.ballerina @@ -0,0 +1,29 @@ +import ballerina/io; + +function loop(int begin, int stop, int inc) { + io:print("["); + foreach int param in [begin, stop, inc] { + io:print(param.toString().padStart(3)); + } + io:print("] -> "); + int count = 0; + int lim = 10; + int i = begin; + while i <= stop { + io:print(i, " "); + count += 1; + if count == lim { break; } + i += inc; + } + io:println(); +} + +public function main() { + var tests = [ + [-2, 2, 1], [-2, 2, 0], [-2, 2, -1], [-2, 2, 10], [2, -2, 1], + [2, 2, 1], [2, 2, -1], [2, 2, 0], [0, 0, 0] + ]; + foreach var test in tests { + loop(test[0], test[1], test[2]); + } +} diff --git a/Task/Lucas-Lehmer-test/REXX/lucas-lehmer-test.rexx b/Task/Lucas-Lehmer-test/REXX/lucas-lehmer-test.rexx index 87094454eb..0eef1a6df2 100644 --- a/Task/Lucas-Lehmer-test/REXX/lucas-lehmer-test.rexx +++ b/Task/Lucas-Lehmer-test/REXX/lucas-lehmer-test.rexx @@ -1,57 +1,63 @@ -/*REXX pgm uses the Lucas─Lehmer primality test for prime powers of 2 (Mersenne primes)*/ -@.=0; @.2=1; @.3=1; @.5=1; @.7=1; @.11=1; @.13=1 /*a partial list of some low primes. */ -!.=@.; !.0=1; !.2=1; !.4=1; !.5=1; !.6=1; !.8=1 /*#'s with these last digs aren't prime*/ -parse arg limit . /*obtain optional arguments from the CL*/ -if limit=='' then limit= 200 /*Not specified? Then use the default.*/ -say center('Mersenne prime index list',70-3,"═") /*show a fancy─dancy header (or title).*/ -say right('M'2, 25) " [1 decimal digit]" /*left─justify them to align&look nice.*/ - /* [►] note that J==1 is a special case*/ - do j=1 by 2 to limit /*there're only so many hours in a day.*/ - power= j + (j==1) /*POWER ≡ J except for when J=1. */ - if \isPrime(power) then iterate /*if POWER isn't prime, then ignore it.*/ - $= LL2(power) /*perform the Lucas─Lehmer 2 (LL2) test*/ - if $=='' then iterate /*Did it flunk LL2? Then skip this #.*/ - say right($, 25) MPsize /*left─justify them to align&look nice.*/ - end /*j*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure expose !. @. /*allow 2 stemmed arrays to be accessed*/ - parse arg x '' -1 z /*obtain variable X and last digit.*/ - if @.x then return 1 /*is X already found to be a prime? */ - if !.z then return 0 /*is last decimal digit even or a five?*/ - if x//3==0 then return 0 /*divisible by three? Then not a prime*/ - if x//7==0 then return 0 /*divisible by seven? " " " " */ - do j=11 by 6 until j*j > x /*ensures that J isn't divisible by 3. */ - if x // j ==0 then return 0 /*Is X divisible by J ? */ - if x // (j+2)==0 then return 0 /* " " " " J+2 ? ___ */ - end /*j*/ /* [↑] perform DO loop through √ x */ - @.x=1; return 1 /*indicate number X is a prime. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -LL2: procedure expose MPsize; parse arg ? /*Lucas─Lehmer test on 2**? - 1 */ - if ?==2 then s=0 /*handle special case for an even prime*/ - else s=4 /* [↓] same as NUMERIC FORM SCIENTIFIC*/ - numeric form; q= 2**? /*ensure correct form for REXX numbers.*/ - /*╔═══════════════════════════════════════════════════════════════════════════╗ - ╔═╝ Compute a power of 2 using only 9 decimal digits. One million digits ║ - ║ could be used, but that really slows up computations. So, we start with the║ - ║ default of 9 digits, and then find the ten's exponent in the product (2**?),║ - ║ double it, and then add 6. {2 is all that's needed, but 6 is a lot ║ - ║ safer.} The doubling is for the squaring of S (below, for s*s). ╔═╝ - ╚═══════════════════════════════════════════════════════════════════════════╝*/ - if pos('E', q)\==0 then do /*is number in exponential notation ? */ - parse var q 'E' tenPow /*get the exponent. */ - numeric digits tenPow * 2 + 6 /*expand precision. */ - end /*REXX used dec FP. */ - else numeric digits digits() * 2 + 6 /*use 9*2 + 6 digits*/ - q=2**? - 1 /*compute a power of two, minus one. */ - r= q // 8 /*obtain Q modulus eight. */ - if r==1 | r==7 then nop /*before crunching, do a simple test. */ - else return '' /*modulus Q isn't one or seven. */ - do ?-2; s= (s*s -2) // q /*lather, rinse, repeat ··· */ - end /* [↑] compute and test for a MP. */ - if s\==0 then return '' /*Not a Mersenne prime? Return a null.*/ - sz= length(q) /*obtain number of decimal digs in MP. */ - MPsize=' ['sz "decimal digit"s(sz)']' /*define a literal to display after MP.*/ - return 'M'? /*return "modified" # (Mersenne index).*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -s: if arg(1)==1 then return arg(3); return word(arg(2) 's', 1) /*simple pluralizer*/ +include Settings +numeric digits 5000 + +say 'LUCAS-LEHMER TEST - 10 Mar 2025' +say version +say +call LucasLehmer +call MillerRabin +exit + +LucasLehmer: +say 'Lucas-Lehmer' +call time('r') +do i = 3 by 2 to 1279 + if Prime(i) then + call LL i +end +say '...' +t = '2203 2281 3217 4253 4423' +do w = 1 to Words(t) + call LL Word(t,w) +end +say Format(Time('e'),,3) 'seconds'; say +return + +LL: +arg xx +d = Length(2**xx-1) +if Primell(xx) then + say Left('M'xx,5) '('Right(d,4) 'digits) is Prime' Time('e')/1's' +return + +MillerRabin: +say 'Miller-Rabin' +call time('r') +do i = 3 by 2 to 1279 + if Prime(i) then + call MR i +end +say '...' +t = '2203 2281 3217 4253 4423' +do w = 1 to Words(t) + call MR Word(t,w) +end +say Format(Time('e'),,3) 'seconds'; say +exit + +MR: +arg xx +m = 2**xx-1 +d = Length(m) +if Prime(m) then do + if d < 26 then + a = 'sure' + else + a = 'probable' + say Left('M'xx,5) '('Right(d,4) 'digits) is' a 'Prime' Time('e')/1's' +end +return + +include Numbers +include Functions +include Abend diff --git a/Task/Lucas-Lehmer-test/Raku/lucas-lehmer-test.raku b/Task/Lucas-Lehmer-test/Raku/lucas-lehmer-test-1.raku similarity index 100% rename from Task/Lucas-Lehmer-test/Raku/lucas-lehmer-test.raku rename to Task/Lucas-Lehmer-test/Raku/lucas-lehmer-test-1.raku diff --git a/Task/Lucas-Lehmer-test/Raku/lucas-lehmer-test-2.raku b/Task/Lucas-Lehmer-test/Raku/lucas-lehmer-test-2.raku new file mode 100644 index 0000000000..f3213f81df --- /dev/null +++ b/Task/Lucas-Lehmer-test/Raku/lucas-lehmer-test-2.raku @@ -0,0 +1,16 @@ +multi is_mersenne_prime(2) { True } +multi is_mersenne_prime(Int $p) { + my $m_p = 1 +< $p - 1; + my $s = 4; + $s = $s.expmod(2, $m_p) - 2 for 3 .. $p; + !$s +} + +# Exhaustive search for Mersenne primes up to 4600 - about half a second +my $start = now; +.say for (flat 2, (1..2300).map(* * 2 + 1)).hyper.map: + { next unless .&is-prime && .&is_mersenne_prime; "M$_ {(now - $start).round(.001)} running total seconds" }; + +# Cheat and just verify Mersenne primes > 4600 +.say for (9689, 9941, 11213, 19937, 21701, 23209, 44497, 86243, 110503).hyper(:1batch).map: + { next unless .&is_mersenne_prime; "M$_ {(now - $start).round(.001)} running total seconds" }; diff --git a/Task/Ludic-numbers/EasyLang/ludic-numbers.easy b/Task/Ludic-numbers/EasyLang/ludic-numbers.easy index 06bb876321..9b44d4b840 100644 --- a/Task/Ludic-numbers/EasyLang/ludic-numbers.easy +++ b/Task/Ludic-numbers/EasyLang/ludic-numbers.easy @@ -1,4 +1,4 @@ -proc initLudicArray n . res[] . +proc initLudicArray &res[] n . len res[] n res[1] = 1 for i = 2 to n @@ -9,7 +9,7 @@ proc initLudicArray n . res[] . res[i] = k + 2 . . -initLudicArray 2005 arr[] +initLudicArray arr[] 2005 for i = 1 to 25 write arr[i] & " " . diff --git a/Task/Ludic-numbers/REXX/ludic-numbers.rexx b/Task/Ludic-numbers/REXX/ludic-numbers.rexx index af1ecf56a8..5907944e77 100644 --- a/Task/Ludic-numbers/REXX/ludic-numbers.rexx +++ b/Task/Ludic-numbers/REXX/ludic-numbers.rexx @@ -1,41 +1,52 @@ -/*REXX program gens/shows (a range of) ludic numbers, or a count when a range is used.*/ -parse arg N count bot top triples . /*obtain optional arguments from the CL*/ -if N=='' | N=="," then N= 25 /*Not specified? Then use the default.*/ -if count=='' | count=="," then count= 1000 /* " " " " " " */ -if bot=='' | bot=="," then bot= 2000 /* " " " " " " */ -if top=='' | top=="," then top= 2005 /* " " " " " " */ -if triples=='' | triples=="," then triples= 249 /* " " " " " " */ -#= 0 /*the number of ludic numbers (so far).*/ -$= ludic( max(N, count, bot, top, triples) ) /*generate enough ludic nums*/ -say 'The first ' N " ludic numbers: " subword($,1,25) /*display 1st N ludic nums*/ - do j=1 until word($, j) > count /*search up to a specific #.*/ - end /*j*/ +-- 22 Mar 2025 +include Settings + +say 'LUDIC NUMBERS' +say version say -say "There are " j - 1 ' ludic numbers that are ≤ ' count +call Ludics 2000 +call Range 1 25 +call Below 1000 +call Ludics 22000 +call Range 2000 2005 +call Triplets 250 +say Time('e')/1 'seconds' +exit + +Range: +procedure expose ludi. +arg xx yy +if yy = '' then + yy = xx +say 'The Ludic numbers from no' xx 'up to' yy 'are' +do i = xx to yy + call Charout ,ludi.i' ' +end +say; say +return + +Below: +procedure expose ludi. +arg xx +do i = 1 until ludi.i >= xx +end +say 'There are' i-1 'Ludic numbers <=' xx say -say "The " bot '───►' top ' (inclusive) ludic numbers are: ' subword($, bot) -@= /*list of ludic triples found (so far).*/ - do j=1 for words($) - _= word($, j) /*it is known that ludic _ exists. */ - if _>=triples then leave /*only process up to a specific number.*/ - if wordpos(_+2, $)==0 | wordpos(_+6, $)==0 then iterate /*Not triple? Skip it.*/ - #= # + 1 /*bump the triple counter. */ - @= @ '◄'_ _+2 _+6"► " /*append the newly found triple ──► @ */ - end /*j*/ -say -if @=='' then say 'From 1──►'triples", no triples found." - else say 'From 1──►'triples", " # ' triples found:' @ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -ludic: procedure; parse arg m,,@; $= 1 2 /*$≡ludic numbers superset; @≡sequence*/ - do j=3 by 2 to m*15; @= @ j /*construct an initial list of numbers.*/ - end /*j*/ - @= @' '; n= words(@) /*append a blank to the number sequence*/ - do while n\==0; f= word(@, 1) /*examine the first word in the @ list.*/ - $= $ f /*add the word to the $ list. */ - do d=1 by f while d<=n; n= n-1 /*use 1st number, elide all occurrences*/ - @= changestr(' 'word(@, d)" ", @, ' . ') /*cross─out a number in @ */ - end /*d*/ /* [↑] done eliding the "1st" number. */ - @= translate(@, , .) /*change dots to blanks; count numbers.*/ - end /*while*/ /* [↑] done eliding ludic numbers. */ - return subword($, 1, m) /*return a range of ludic numbers. */ +return + +Triplets: +procedure expose ludi. work. +arg xx +say 'Found triplets below' xx +do i = 1 until l3 >= xx + l1 = i; l2 = i+2; l3 = i+6 + if work.l1 & work.l2 & work.l3 then do + call Charout ,'['l1 l2 l3'] ' + end +end +say; say +return + +include Sequences +include Functions +include Abend diff --git a/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers.lua b/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-1.lua similarity index 75% rename from Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers.lua rename to Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-1.lua index 0898194946..892105fe3a 100644 --- a/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers.lua +++ b/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-1.lua @@ -1,4 +1,4 @@ -function luhn_test(cc_number) +function luhn(cc_number) assert(type(cc_number) == 'string') local sum = 0 local is_odd = true @@ -14,7 +14,3 @@ function luhn_test(cc_number) end -- for return (sum % 10) == 0 end -- function luhn_test - -for _, val in ipairs{"49927398716", "49927398717", "1234567812345678", "1234567812345670"} do - print(val, luhn_test(val)) -end -- for diff --git a/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-2.lua b/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-2.lua new file mode 100644 index 0000000000..09d98492c9 --- /dev/null +++ b/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-2.lua @@ -0,0 +1,8 @@ +function luhn(digits) + local sum = 0 + for odd,even in digits:reverse():gmatch"(.)(.?)" do + local number = 2 * (tonumber(even) or 0) + sum = sum + odd + number%10 + number//10 + end + return sum%10==0 +end diff --git a/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-3.lua b/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-3.lua new file mode 100644 index 0000000000..e55e3ca948 --- /dev/null +++ b/Task/Luhn-test-of-credit-card-numbers/Lua/luhn-test-of-credit-card-numbers-3.lua @@ -0,0 +1,3 @@ +for _, val in ipairs{"49927398716", "49927398717", "1234567812345678", "1234567812345670"} do + print(val, luhn(val)) +end diff --git a/Task/M-bius-function/ANSI-BASIC/m-bius-function.basic b/Task/M-bius-function/ANSI-BASIC/m-bius-function.basic new file mode 100644 index 0000000000..0abcfa77e7 --- /dev/null +++ b/Task/M-bius-function/ANSI-BASIC/m-bius-function.basic @@ -0,0 +1,28 @@ +100 REM Moebius function +110 DECLARE EXTERNAL FUNCTION Moebius +120 FOR T = 0 TO 9 +130 FOR U = 1 TO 10 +140 PRINT USING "## ": Moebius(10 * T + U); +150 NEXT U +160 PRINT +170 NEXT T +180 END +190 REM *** +200 EXTERNAL FUNCTION Moebius(N) +210 LET M = 1 +220 IF N <> 1 THEN +230 LET F = 2 +240 DO +250 IF MOD(N, (F * F)) = 0 THEN +260 LET M = 0 +270 ELSE +280 IF MOD(N, F) = 0 THEN +290 LET M = -M +300 LET N = N / F +310 END IF +320 LET F = F + 1 +330 END IF +340 LOOP WHILE (F <= N) AND (M <> 0) +350 END IF +360 LET Moebius = M +370 END FUNCTION diff --git a/Task/M-bius-function/ASIC/m-bius-function.asic b/Task/M-bius-function/ASIC/m-bius-function.asic new file mode 100644 index 0000000000..93962d58be --- /dev/null +++ b/Task/M-bius-function/ASIC/m-bius-function.asic @@ -0,0 +1,37 @@ +REM Moebius function +FOR T = 0 TO 9 + FOR U = 1 TO 10 + N = 10 * T + N = N + U + GOSUB CalcMoebius: + PRINT M; + NEXT U + PRINT +NEXT T +END + +CalcMoebius: +REM Calculate Moebius(N). Result in M. +REM NOTE. N changes its value. +M = 1 +IF N <> 1 THEN + F = 2 + StartLoop: + FTo2 = F * F + NModFTo2 = N MOD FTo2 + IF NModFTo2 = 0 THEN + M = 0 + ELSE + NModF = N MOD F + IF NModF = 0 THEN + M = -M + N = N / F + ENDIF + F = F + 1 + ENDIF + IF M = 0 THEN AfterLoop: + IF F > N THEN AfterLoop: + GOTO StartLoop: + AfterLoop: +ENDIF +RETURN diff --git a/Task/M-bius-function/EasyLang/m-bius-function.easy b/Task/M-bius-function/EasyLang/m-bius-function.easy index 2826147573..764f397637 100644 --- a/Task/M-bius-function/EasyLang/m-bius-function.easy +++ b/Task/M-bius-function/EasyLang/m-bius-function.easy @@ -6,12 +6,8 @@ for i to mu_max . for i = 2 to sqroot if mu[i] = 1 - for j = i step i to mu_max - mu[j] *= -i - . - for j = i * i step i * i to mu_max - mu[j] = 0 - . + for j = i step i to mu_max : mu[j] *= -i + for j = i * i step i * i to mu_max : mu[j] = 0 . . for i = 2 to mu_max @@ -25,10 +21,8 @@ for i = 2 to mu_max mu[i] = -1 . . -numfmt 0 3 +numfmt 3 0 for i = 1 to 100 write mu[i] - if i mod 10 = 0 - print "" - . + if i mod 10 = 0 : print "" . diff --git a/Task/M-bius-function/JavaScript/m-bius-function-1.js b/Task/M-bius-function/JavaScript/m-bius-function-1.js new file mode 100644 index 0000000000..90052b19c4 --- /dev/null +++ b/Task/M-bius-function/JavaScript/m-bius-function-1.js @@ -0,0 +1,32 @@ +// Moebius function + +function moebius(n) { + m = 1; + if (n != 1) { + f = 2; + do { + if (n % (f * f) == 0) { + m = 0; + } else { + if (n % f == 0) { + m = -m; + n /= f; + } + f++; + } + } while (f <= n && m != 0); + } + return m; +} + +document.write(""); +for (t = 0; t <= 9; t++) { + document.write(""); + for (u = 1; u <= 10; u++) { + document.write(""); + } + document.write(""); +} +document.write("
"); + document.write(moebius(10 * t + u)); + document.write("
"); diff --git a/Task/M-bius-function/JavaScript/m-bius-function-2.js b/Task/M-bius-function/JavaScript/m-bius-function-2.js new file mode 100644 index 0000000000..9fa62b473a --- /dev/null +++ b/Task/M-bius-function/JavaScript/m-bius-function-2.js @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Task/M-bius-function/K/m-bius-function.k b/Task/M-bius-function/K/m-bius-function.k new file mode 100644 index 0000000000..9d6ca736fe --- /dev/null +++ b/Task/M-bius-function/K/m-bius-function.k @@ -0,0 +1,8 @@ +mus:{ / values of mu(i) for i below x + (~~!x) { / initial value: 0 1 1 1 1 ... + y[z *1+!(-z )!x-1]*:-1 / flip sign + y[z*z*1+!(-z*z)!x-1]:0 / set squares to zero + y}[x]/ `pri x} / for each prime below x +(μ:):{mus[1+0|/,//x]x} +`0:"The first 100 values of the μ function:" +`0:,/'-3$$μ 10 10#1+!100 diff --git a/Task/M-bius-function/Modula-2/m-bius-function.mod2 b/Task/M-bius-function/Modula-2/m-bius-function.mod2 new file mode 100644 index 0000000000..5a56c95bd7 --- /dev/null +++ b/Task/M-bius-function/Modula-2/m-bius-function.mod2 @@ -0,0 +1,41 @@ +MODULE Moebius; +(* Moebius function *) +FROM STextIO IMPORT + WriteLn, WriteString; +FROM SWholeIO IMPORT + WriteInt; + +VAR + T, U: INTEGER; + +PROCEDURE Moebius(N: INTEGER): INTEGER; +VAR + M, F: INTEGER; +BEGIN + M := 1; + IF N <> 1 THEN + F := 2; + REPEAT + IF N MOD (F * F) = 0 THEN + M := 0 + ELSE + IF N MOD F = 0 THEN + M := -M; + N := N DIV F + END; + F := F + 1 + END + UNTIL (F > N) OR (M = 0) + END; + RETURN M +END Moebius; + +BEGIN + FOR T := 0 TO 9 DO + FOR U := 1 TO 10 DO + WriteInt(Moebius(10 * T + U), 2); + WriteString(' ') + END; + WriteLn + END +END Moebius. diff --git a/Task/M-bius-function/PHP/m-bius-function.php b/Task/M-bius-function/PHP/m-bius-function.php new file mode 100644 index 0000000000..071a320dcf --- /dev/null +++ b/Task/M-bius-function/PHP/m-bius-function.php @@ -0,0 +1,29 @@ + diff --git a/Task/M-bius-function/REXX/m-bius-function-1.rexx b/Task/M-bius-function/REXX/m-bius-function-1.rexx deleted file mode 100644 index 43b2b21283..0000000000 --- a/Task/M-bius-function/REXX/m-bius-function-1.rexx +++ /dev/null @@ -1,49 +0,0 @@ -/*REXX pgm computes & shows a value grid of the Möbius function for a range of integers.*/ -call time('r') -parse arg LO HI grp . /*obtain optional arguments from the CL*/ -numeric digits 100 -if LO=='' | LO=="," then LO= 0 /*Not specified? Then use the default.*/ -if HI=='' | HI=="," then HI= 199 /* " " " " " " */ -if grp=='' | grp=="," then grp= 20 /* " " " " " " */ - /* uuuuuuuuuuuu */ -call genP HI /*generate primes up to the v HI */ -say center(' The Moebius sequence from ' LO " --> " HI" ", max(50, grp*3), '=') /*title*/ -dd='' /*variable holds output grid of GRP hhs.*/ - do j=LO to HI; dd= dd right( moebius(j), 2) /*process some numbers from LO --> HI.*/ - if words(dd)==grp then do; say substr(dd, 2); dd='' /*show grid if fully populated,*/ - end /* and nullify it for more hhs.*/ - end /*j*/ /*for small grids, using wordCnt is OK.*/ - -if dd\=='' then say substr(dd, 2) /*handle any residual numbers not shown*/ -say format(time('e'),,3) 'seconds' -exit /*stick a fork in it, we're all done. */ -/*--------------------------------------------------------------------------------------*/ -moebius: procedure expose aa.; parse arg x /*obtain a integer to be tested for mu.*/ - if x<1 then return '*' /*special? Then return symbol for null.*/ - hh= 0 /*start with a value of zero. */ - do k=1; p= aa.k /*get the Kth (pre-generated) prime.*/ - if p>x then leave /*prime (P) > X? Then we're done. */ - if p*p>x then do; hh= hh+1; leave /*prime (P**2 > X? Bump hh and leave.*/ - end - if x//p==0 then do; hh= hh+1 /*X divisible by P? Bump mu number. */ - x= x % p /* Divide by prime. */ - if x//p==0 then return 0 /*X÷by P? Then return zero*/ - end - end /*k*/ /*hh (below) is almost always small, <9*/ - if hh//2==0 then return 1 /*Is hh even? Then return postive 1 */ - return -1 /* " " odd? " " negative 1. */ -/*--------------------------------------------------------------------------------------*/ -genP: aa.1=2; aa.2=3; aa.3=5; aa.4=7; aa.5=11; aa.6= 13; nP=6 /*assign low primes; hh primes.*/ - do lim=nP until lim*lim>=HI /*only keep primes up to the sqrt(HI).*/ - end /*lim*/ - do j=aa.nP+4 by 2 to HI /*only find odd primes from here on. */ - parse var j '' -1 uu;if uu==5 then iterate /*Is last digit a "5"? Then not prime*/ - if j// 3==0 then iterate /*is J divisible by 3? " " " */ - if j// 7==0 then iterate /* " " " " 7? " " " */ - if j//11==0 then iterate /* " " " " 11? " " " */ - if j//13==0 then iterate /* " " " " 13? " " " */ - do k=7 while k*k<=j /*divide by some generated odd primes. */ - if j // aa.k==0 then iterate j /*Is J divisible by P? Then not prime*/ - end /*k*/ /* [?] a prime (J) has been found. */ - nP= nP+1; if nP<=HI then aa.nP= j /*bump prime count; assign prime to aa.*/ - end /*j*/; return diff --git a/Task/M-bius-function/REXX/m-bius-function-2.rexx b/Task/M-bius-function/REXX/m-bius-function-2.rexx deleted file mode 100644 index 65f32f2d38..0000000000 --- a/Task/M-bius-function/REXX/m-bius-function-2.rexx +++ /dev/null @@ -1,41 +0,0 @@ -include Settings - -say version; say 'Moebius sequence'; say -parse arg LO HI grp . /*obtain optional arguments from the CL*/ -numeric digits 100 -if LO=='' | LO=="," then LO= 0 /*Not specified? Then use the default.*/ -if HI=='' | HI=="," then HI= 199 /* " " " " " " */ -if grp=='' | grp=="," then grp= 20 /* " " " " " " */ - /* ______ */ -say Center(' The Moebius sequence from ' LO " --> " HI" ", Max(50, grp*3), '=') /*title*/ -dd='' /*variable holds output grid of GRP #s.*/ - do j=LO to HI; dd= dd Right( Moebius(j), 2) /*process some numbers from LO --> HI.*/ - if Words(dd)==grp then do; say Substr(dd, 2); dd='' /*show grid if fully populated,*/ - end /* and nullify it for more #s.*/ - end /*j*/ /*for small grids, using wordCnt is OK.*/ -if dd\=='' then say Substr(dd, 2) /*handle any residual numbers not shown*/ -say Format(Time('e'),,3) 'seconds' -exit /*stick a fork in it, we're all done. */ - -Moebius: -/* Moebius sequence */ -procedure expose fact. ufac. -arg x -/* Special value */ -if x = 0 then - return '*' -/* Using # of (unique) prime factors */ -call Factors(x) -call Ufactors(x) -if fact.0 = ufac.0 then - if IsEven(fact.factor.0) then - return 1 - else - return -1 -else - return 0 - -include Functions -include Numbers -include Sequences -include Abend diff --git a/Task/M-bius-function/REXX/m-bius-function.rexx b/Task/M-bius-function/REXX/m-bius-function.rexx new file mode 100644 index 0000000000..f5a4186e1b --- /dev/null +++ b/Task/M-bius-function/REXX/m-bius-function.rexx @@ -0,0 +1,30 @@ +include Settings + +say 'MOEBIUS FUNCTION - 4 Mar 2025' +say version +say +numeric digits 100 +call sequence 1,200 +call sequence 100001,100200 +call sequence 1000000001,1000000200 +call sequence 10000000000001,10000000000200 +exit + +Sequence: +arg x,y +say 'Moebius sequence from' x 'to' y +n = 0 +do i = x to y + n = n+1 + call charout ,right(Moebius(i),3) + if n//20 = 0 then + say +end +say Format(Time('e'),,3) 'seconds' +say +return + +include Functions +include Numbers +include Sequences +include Abend diff --git a/Task/M-bius-function/RapidQ/m-bius-function.rapidq b/Task/M-bius-function/RapidQ/m-bius-function.rapidq new file mode 100644 index 0000000000..be91cf2377 --- /dev/null +++ b/Task/M-bius-function/RapidQ/m-bius-function.rapidq @@ -0,0 +1,36 @@ +REM Levenshtein distance +DECLARE FUNCTION LevDist(S$, T$) AS INTEGER +DECLARE FUNCTION MIN(A, B) AS INTEGER +PRINT "The Levenshtein distance..." +PRINT "between 'kitten' and 'sitting' is "; LevDist("kitten","sitting") +PRINT "between 'rosettacode' and 'raisethysword' is "; LevDist("rosettacode","raisethysword") +END + +FUNCTION LevDist(S$, T$) AS INTEGER +N = LEN(T$): M = LEN(S$) +DIM D(0 TO N, 0 TO N) +FOR I = 0 TO M + D(I, 0) = I +NEXT I +FOR J = 0 TO N + D(0, J) = J +NEXT J +FOR J = 1 TO N + FOR I = 1 TO M + IF MID$(S$, I, 1) = MID$(T$, J, 1) THEN + D(I, J) = D(I - 1, J - 1) + ELSE + D(I, J) = Min(D(I - 1, J) + 1, Min(D(I, J - 1) + 1, D(I - 1, J - 1) + 1)) + END IF + NEXT I +NEXT J +LevDist = D(M, N) +END FUNCTION + +FUNCTION Min(A, B) AS INTEGER +IF A < B THEN + Min = A +ELSE + Min = B +END IF +END FUNCTION diff --git a/Task/MD5-Implementation/EasyLang/md5-implementation.easy b/Task/MD5-Implementation/EasyLang/md5-implementation.easy index 2db0a4b538..c4286a9e53 100644 --- a/Task/MD5-Implementation/EasyLang/md5-implementation.easy +++ b/Task/MD5-Implementation/EasyLang/md5-implementation.easy @@ -1,12 +1,12 @@ len md5k[] 64 -proc md5init . . +proc md5init . for i = 1 to 64 md5k[i] = floor (0x100000000 * abs sin (i * 180 / pi)) . . md5init # -proc md5 inp$ . s$ . +func$ md5 inp$ . subr addinp if inp4 = 1 inp[] &= 0 @@ -60,21 +60,20 @@ proc md5 inp$ . s$ . f = bitxor h1 d g = (3 * i + 2) mod 16 else - h1 = bitor b bitnot d + h1 = bitor b bitand bitnot d 0xffffffff f = bitxor c h1 g = (7 * i - 7) mod 16 . - f = (f + a + md5k[i] + inp[chunk + g]) + f = bitand (f + a + md5k[i] + inp[chunk + g]) 0xffffffff a = d d = c c = b h1 = bitshift f s[i] h2 = bitshift f (s[i] - 32) - b = (b + h1 + h2) + b = bitand (b + h1 + h2) 0xffffffff . a0 += a ; b0 += b ; c0 += c ; d0 += d . - s$ = "" for a in [ a0 b0 c0 d0 ] for i = 1 to 4 b = a mod 256 @@ -88,14 +87,15 @@ proc md5 inp$ . s$ . . . . + return s$ . repeat s$ = input until error = 1 - md5 s$ h$ - print h$ + print md5 s$ . input_data + a abc message digest diff --git a/Task/MD5-Implementation/JavaScript/md5-implementation.js b/Task/MD5-Implementation/JavaScript/md5-implementation.js new file mode 100644 index 0000000000..5b20385092 --- /dev/null +++ b/Task/MD5-Implementation/JavaScript/md5-implementation.js @@ -0,0 +1,209 @@ +// MD5 Constants +const INITIAL_A = 0x67452301; +const INITIAL_B = 0xEFCDAB89; // No need for L suffix or static_cast +const INITIAL_C = 0x98BADCFE; // No need for L suffix or static_cast +const INITIAL_D = 0x10325476; + +const SHIFT_AMOUNTS = [ + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 +]; + +// K constants (T table) - Sine values +const K = [ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 +]; + +/** + * Left-rotate a 32-bit integer by a number of bits. + * @param {number} x - The integer to rotate. + * @param {number} n - The number of bits to rotate by. + * @returns {number} The rotated integer. + */ +function rotl(x, n) { + // Ensure x is treated as 32-bit for the shifts + return ((x << n) | (x >>> (32 - n))) | 0; +} + +/** + * Converts a Uint8Array (byte array) to a hexadecimal string. + * @param {Uint8Array} bytes - The byte array to convert. + * @returns {string} The hexadecimal string representation. + */ +function bytesToHexString(bytes) { + let hexString = ""; + for (const byte of bytes) { + hexString += byte.toString(16).padStart(2, '0'); + } + return hexString; +} + +/** + * Converts a string to a Uint8Array using UTF-8 encoding. + * @param {string} text - The string to convert. + * @returns {Uint8Array} The resulting byte array. + */ +function stringToBytes(text) { + return new TextEncoder().encode(text); +} + +/** + * Computes the MD5 hash of a byte array. + * @param {Uint8Array} message - The input message as a byte array. + * @returns {Uint8Array} The 16-byte MD5 hash. + */ +function computeMD5(message) { + const messageLengthBytes = message.length; + const messageLengthBits = BigInt(messageLengthBytes) * 8n; // Use BigInt for potentially large lengths + + // Calculate padding length + // Need (length + 1 + k) % 64 == 56 bytes (or 448 bits) + // So, length + 1 + k = 64n + 56 + // k = 64n + 56 - length - 1 + // Minimum k is when 64n is just >= length + 1 - 56 + 1 = length - 54 + // Padding length includes the 0x80 byte and the 8 length bytes. + // Total length must be multiple of 64 bytes (512 bits). + const numBlocks = Math.ceil((messageLengthBytes + 1 + 8) / 64); + const totalLength = numBlocks * 64; + const paddingLength = totalLength - messageLengthBytes; + + // Create padded message buffer + const paddedMessage = new Uint8Array(totalLength); + paddedMessage.set(message); // Copy original message + + // Append the '1' bit (0x80 byte) + paddedMessage[messageLengthBytes] = 0x80; + + // Append the 64-bit message length (little-endian) + // Note: JavaScript bitwise ops work on 32 bits. Handle 64-bit length carefully. + const lengthOffset = totalLength - 8; + for (let i = 0; i < 8; ++i) { + paddedMessage[lengthOffset + i] = Number((messageLengthBits >> (BigInt(i) * 8n)) & 0xFFn); + } + + // Initialize hash state variables (ensure they are 32-bit ints) + let a = INITIAL_A | 0; + let b = INITIAL_B | 0; + let c = INITIAL_C | 0; + let d = INITIAL_D | 0; + + const buffer = new Array(16); // Reusable buffer for 16 words (32-bit integers) + + // Process the message in 64-byte (512-bit) blocks + for (let i = 0; i < numBlocks; ++i) { + const blockOffset = i * 64; + + // Prepare the 16-word buffer from the current block (little-endian) + for (let j = 0; j < 16; ++j) { + const wordIndex = blockOffset + j * 4; + buffer[j] = ( + (paddedMessage[wordIndex]) | + (paddedMessage[wordIndex + 1] << 8) | + (paddedMessage[wordIndex + 2] << 16) | + (paddedMessage[wordIndex + 3] << 24) + ) | 0; // Ensure 32-bit integer + } + + // Save current hash state + let originalA = a; + let originalB = b; + let originalC = c; + let originalD = d; + + // Main loop (64 rounds) + for (let j = 0; j < 64; ++j) { + let f, bufferIndex; + const div16 = Math.floor(j / 16); + + switch (div16) { + case 0: // Round 1: F = (B & C) | (~B & D) + f = (b & c) | (~b & d); + bufferIndex = j; + break; + case 1: // Round 2: G = (B & D) | (C & ~D) + f = (b & d) | (c & ~d); + bufferIndex = (j * 5 + 1) % 16; + break; + case 2: // Round 3: H = B ^ C ^ D + f = b ^ c ^ d; + bufferIndex = (j * 3 + 5) % 16; + break; + case 3: // Round 4: I = C ^ (B | ~D) + f = c ^ (b | ~d); + bufferIndex = (j * 7) % 16; + break; + } + + // Ensure intermediate results are 32-bit + f = f | 0; + const term1 = a | 0; + const term2 = buffer[bufferIndex] | 0; + const term3 = K[j] | 0; + const shift = SHIFT_AMOUNTS[j]; // Use direct index j for SHIFT_AMOUNTS + + // Perform the round calculation: temp = B + rotl(A + F + M[g] + K[i], s) + let sum = (term1 + f + term2 + term3) | 0; + let rotatedSum = rotl(sum, shift); + let temp = (b + rotatedSum) | 0; + + // Update hash variables + a = d; + d = c; + c = b; + b = temp; + } + + // Add the original hash state back (with 32-bit wrap) + a = (a + originalA) | 0; + b = (b + originalB) | 0; + c = (c + originalC) | 0; + d = (d + originalD) | 0; + } + + // Construct final 16-byte hash (little-endian) + const md5Bytes = new Uint8Array(16); + let count = 0; + for (const word of [a, b, c, d]) { + for (let i = 0; i < 4; ++i) { + md5Bytes[count++] = (word >> (i * 8)) & 0xFF; + } + } + + return md5Bytes; +} + +// --- Main execution (equivalent to C++ main) --- +const tests = [ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" +]; + +console.log("MD5 Hashes:"); +for (const test of tests) { + const messageBytes = stringToBytes(test); + const hashBytes = computeMD5(messageBytes); + const hexHash = bytesToHexString(hashBytes); + console.log(`${hexHash} <== "${test}"`); +} diff --git a/Task/MD5/EasyLang/md5.easy b/Task/MD5/EasyLang/md5.easy index 727b788834..aa9905db3b 100644 --- a/Task/MD5/EasyLang/md5.easy +++ b/Task/MD5/EasyLang/md5.easy @@ -1,5 +1,5 @@ len md5k[] 64 -proc md5init . . +proc md5init . for i = 1 to 64 md5k[i] = floor (0x100000000 * abs sin (i * 180 / pi)) . @@ -8,14 +8,10 @@ md5init # func$ md5 inp$ . subr addinp - if inp4 = 1 - inp[] &= 0 - . + if inp4 = 1 : inp[] &= 0 inp[len inp[]] += b * inp4 inp4 *= 0x100 - if inp4 = 0x100000000 - inp4 = 1 - . + if inp4 = 0x100000000 : inp4 = 1 . s[] = [ 7 12 17 22 7 12 17 22 7 12 17 22 7 12 17 22 5 9 14 20 5 9 14 20 5 9 14 20 5 9 14 20 4 11 16 23 4 11 16 23 4 11 16 23 4 11 16 23 6 10 15 21 6 10 15 21 6 10 15 21 6 10 15 21 ] inp[] = [ ] @@ -61,16 +57,16 @@ func$ md5 inp$ . g = (3 * i + 2) mod 16 else h1 = bitor b bitnot d - f = bitxor c h1 + f = bitand 0xffffffff bitxor c h1 g = (7 * i - 7) mod 16 . - f = (f + a + md5k[i] + inp[chunk + g]) + f = bitand 0xffffffff (f + a + md5k[i] + inp[chunk + g]) a = d d = c c = b h1 = bitshift f s[i] h2 = bitshift f (s[i] - 32) - b = (b + h1 + h2) + b = bitand 0xffffffff (b + h1 + h2) . a0 += a ; b0 += b ; c0 += c ; d0 += d . @@ -80,9 +76,7 @@ func$ md5 inp$ . a = a div 256 for h in [ b div 16 b mod 16 ] h += 48 - if h > 57 - h += 39 - . + if h > 57 : h += 39 s$ &= strchar h . . diff --git a/Task/Mad-Libs/ALGOL-68/mad-libs.alg b/Task/Mad-Libs/ALGOL-68/mad-libs.alg index 4731d9f18e..d82253860f 100644 --- a/Task/Mad-Libs/ALGOL-68/mad-libs.alg +++ b/Task/Mad-Libs/ALGOL-68/mad-libs.alg @@ -1,123 +1,111 @@ -# Mad Libs style story generation # +BEGIN # Mad Libs style story generation # -# gets the story template from the file f. The template terminates with # -# a blank line # -# The user is then promoted for the replacements for the markers # -# and the story is printed with the substitutions made # -PROC story = ( REF FILE f )VOID: -BEGIN - - # a linked list of strings, used to hold the story template # - MODE STRINGLIST = STRUCT( STRING text, REF STRINGLIST next ); - - # a linked list of pairs of strings, used to hold the replacements # - MODE REPLACEMENTLIST = STRUCT( STRING word - , STRING replacement - , REF REPLACEMENTLIST next - ); - - # NIL reference for marking the end of a STRINGLIST # - REF STRINGLIST nil stringlist = NIL; - - # NIL reference for marking the end of a REPLACEMENTLIST # - REF REPLACEMENTLIST nil replacementlist = NIL; - - - # returns "text" with trailing spaces removed # - OP RTRIM = ( STRING text )STRING: + # gets the story template from the file f. The template terminates with # + # a blank line # + # The user is then promoted for the replacements for the markers # + # and the story is printed with the substitutions made # + PROC story = ( REF FILE f )VOID: BEGIN - INT trim pos := UPB text; - FOR text pos FROM UPB text BY -1 TO LWB text WHILE text[ text pos ] = " " + + # a linked list of strings, used to hold the story template # + MODE STRINGLIST = STRUCT( STRING text, REF STRINGLIST next ); + + # a linked list of pairs of strings, used to hold the replacements # + MODE REPLACEMENTLIST = STRUCT( STRING word + , STRING replacement + , REF REPLACEMENTLIST next + ); + # NIL reference for marking the end of a STRINGLIST # + REF STRINGLIST nil stringlist = NIL; + # NIL reference for marking the end of a REPLACEMENTLIST # + REF REPLACEMENTLIST nil replacementlist = NIL; + + # returns "text" with trailing spaces removed # + OP RTRIM = ( STRING text )STRING: + BEGIN + INT trim pos := UPB text; + FOR text pos FROM UPB text BY -1 TO LWB text WHILE text[ text pos ] = " " + DO + trim pos := text pos - 1 + OD; + text[ LWB text : trim pos ] + END; # RTRIM # + + # looks for word in the dictionary. If it is found, replacement is # + # set to its replacement and TRUE is returned. If word not present, # + # FALSE is returned - uses recursion # + PROC find replacement = ( STRING word + , REF STRING replacement + , REF REPLACEMENTLIST story dictionary + ) BOOL: + IF story dictionary IS nil replacementlist + THEN FALSE + ELIF word OF story dictionary = word + THEN replacement := replacement OF story dictionary; + TRUE + ELSE find replacement( word, replacement, next OF story dictionary ) + FI; # find replacement # + + + # read the story template # + + # the result has a dummy element so "next OF next" is always valid # + REF STRINGLIST story text := HEAP STRINGLIST := ( "dummy", nil stringlist ); + REF REF STRINGLIST next := story text; + + WHILE # read the story template, terminates with a blank line # + STRING text; + get( f, ( text, newline ) ); + text := RTRIM text; + text /= "" DO - trim pos := text pos - 1 + # add the line to the end of the list # + next := ( next OF next ) := HEAP STRINGLIST := ( text, nil stringlist ) OD; - text[ LWB text : trim pos ] - END; # RTRIM # + # find the markers in the story and replace them with the # + # user's chosen text - we ignore the dummy element at the start # - # looks for word in the dictionary. If it is found, replacement is # - # set to its replacement and TRUE is returned. If word not present, # - # FALSE is returned - uses recursion # - PROC find replacement = ( STRING word - , REF STRING replacement - , REF REPLACEMENTLIST dictionary - )BOOL: - IF dictionary IS nil replacementlist - THEN - FALSE - ELIF word OF dictionary = word - THEN - replacement := replacement OF dictionary; - TRUE - ELSE - find replacement( word, replacement, next OF dictionary ) - FI; # find replacement # + REF REPLACEMENTLIST dictionary := nil replacementlist; + REF STRINGLIST line := story text; - - # read the story template # - - # the result has a dummy element so "next OF next" is always valid # - REF STRINGLIST story := HEAP STRINGLIST := ( "dummy", nil stringlist ); - REF REF STRINGLIST next := story; - - # read the story template, terminates with a blank line # - - WHILE - STRING text; - get( f, ( text, newline ) ); - text := RTRIM text; - text /= "" - DO - # add the line to the end of the list # - next := ( next OF next ) := HEAP STRINGLIST := ( text, nil stringlist ) - OD; - - # find the markers in the story and replace them with the # - # user's chosen text - we ignore the dummy element at the start # - - REF REPLACEMENTLIST dictionary := nil replacementlist; - REF STRINGLIST line := story; - - WHILE line := next OF line; - line ISNT nil stringlist - DO - # have a line of text - replace all the markers in it # - STRING word, replacement; - INT start pos, end pos; - WHILE char in string( "<", start pos, text OF line ) - AND char in string( ">", end pos, text OF line ) + WHILE line := next OF line; + line ISNT nil stringlist DO - # have a marker, get it from the line # - word := ( text OF line )[ start pos : end pos ]; - # get its replacement # - IF NOT find replacement( word, replacement, dictionary ) - THEN - # we don't already have a replacement for word # - # get one from the user and add it to the dictionary # - print( ( "What should replace ", word, "? " ) ); - read( ( replacement, newline ) ); - dictionary := HEAP REPLACEMENTLIST := ( word, replacement, dictionary ) - FI; - # replace with the replacement # - text OF line := ( text OF line )[ : start pos - 1 ] - + replacement - + ( text OF line )[ end pos + 1 : ] + # have a line of text - replace all the markers in it # + STRING word, replacement; + INT start pos, end pos; + WHILE char in string( "<", start pos, text OF line ) + AND char in string( ">", end pos, text OF line ) + DO + # have a marker, get it from the line # + word := ( text OF line )[ start pos : end pos ]; + # get its replacement # + IF NOT find replacement( word, replacement, dictionary ) + THEN + # we don't already have a replacement for word # + # get one from the user and add it to the dictionary # + print( ( "What should replace ", word, "? " ) ); + read( ( replacement, newline ) ); + dictionary := HEAP REPLACEMENTLIST := ( word, replacement, dictionary ) + FI; + # replace with the replacement # + text OF line := ( text OF line )[ : start pos - 1 ] + + replacement + + ( text OF line )[ end pos + 1 : ] + OD + OD; + + # print the story, ignoring the dummy element at the start # + + line := story text; + WHILE line := next OF line; + line ISNT nil stringlist + DO + print( ( text OF line, newline ) ) OD - OD; - # print the story, ignoring the dummy element at the start # - - line := story; - - WHILE line := next OF line; - line ISNT nil stringlist - DO - print( ( text OF line, newline ) ) - OD - -END; # story # - -main:( + END; # story # # we read the template from stand in (the keyboard unless it's been # # redirected) we could prompt the user for a template file name, # @@ -125,4 +113,4 @@ main:( print( ( "Please Enter the story template terminated by a blank line", newline ) ); story( stand in ) -) +END diff --git a/Task/Mad-Libs/EasyLang/mad-libs.easy b/Task/Mad-Libs/EasyLang/mad-libs.easy new file mode 100644 index 0000000000..3a604305d3 --- /dev/null +++ b/Task/Mad-Libs/EasyLang/mad-libs.easy @@ -0,0 +1,58 @@ +global name$[] out$[] . +func n2id n$ . + for id to len name$[] : if name$[id] = n$ : return id + name$[] &= n$ + return id +. +print "Enter a story template, terminated by an empty line:" +repeat + s$ = input + print s$ + until s$ = "" + for c$ in strchars s$ + if c$ = "<" + in = 1 + w$ = "" + elif c$ = ">" + in = 0 + id = n2id w$ + out$ &= "<" & id & ">" + elif in = 1 + w$ &= c$ + else + out$ &= c$ + . + . + out$[] &= out$ + out$ = "" +. +for i to len name$[] + write name$[i] & ": " + name$[i] = input + print name$[i] +. +print "" +for s$ in out$[] + for c$ in strchars s$ + if c$ = "<" + in = 1 + w$ = "" + elif c$ = ">" + in = 0 + write name$[number w$] + elif in = 1 + w$ &= c$ + else + write c$ + . + . + print "" +. +# +input_data + went for a walk in the park. +found a . decided to take it home. + +Monica +She +cockerel diff --git a/Task/Mad-Libs/F-Sharp/mad-libs.fs b/Task/Mad-Libs/F-Sharp/mad-libs.fs new file mode 100644 index 0000000000..6b4a70b9a6 --- /dev/null +++ b/Task/Mad-Libs/F-Sharp/mad-libs.fs @@ -0,0 +1,63 @@ +open System +open System.Collections.Generic +open System.Text + +type Template(s: string, d: Dictionary) = + let text = s + let substitutes = d + + new(s: string) = + let d = Dictionary() + + let rec collect (idx: int) = + let start_idx = s.IndexOf('<', idx) + + if start_idx = -1 then + () + else + let end_idx = s.IndexOf('>', start_idx) + + if end_idx = -1 then + failwith "Malformed input" + + d.TryAdd(s[start_idx..end_idx], "") |> ignore + collect (end_idx + 1) + + collect 0 + Template(s, d) + + override _.ToString() = + let mutable s = text + + for KeyValue (name, value) in substitutes do + if value = "" then + s <- s.Replace(name, name + ": ") + else + s <- s.Replace(name, value) + + s + + member _.AskForSubstitutes() = + for KeyValue (name, _) in substitutes do + printf $"Enter a {name}: " + let input = Console.ReadLine() + substitutes[name] <- input.Trim() + +let story = + let rec read (acc: StringBuilder) = + let line = Console.ReadLine() + + if line.Trim() = "" then + acc + else + acc.Append(line + "\n") |> ignore + read acc + + let mutable acc = StringBuilder() + printfn "Enter a multi-line story (finish with blank line):" + (read acc).ToString().Trim() + +let story_template = Template story +story_template.AskForSubstitutes() +printfn "\n" +printfn $"{story_template}" diff --git a/Task/Mad-Libs/Objeck/mad-libs.objeck b/Task/Mad-Libs/Objeck/mad-libs.objeck new file mode 100644 index 0000000000..7b99aec795 --- /dev/null +++ b/Task/Mad-Libs/Objeck/mad-libs.objeck @@ -0,0 +1,34 @@ +use Collection, Query.RegEx; + +class MadLibs { + function : Main(args : String[]) ~ Nil { + input : String; + if(args->Size() = 1) { + input := System.IO.Console->ReadLine(); + } + else { + input := " went for a walk in the park. found a . decided to take it home."; + }; + + replace_sets := Hash->New(); + results := Query.RegEx.RegEx->New("\\<(\\w| )*\\>")->Find(input); + each(result in results) { + temp_word := input->SubString(result->GetStart(), result->GetLength()); + if(<>replace_sets->Has(temp_word)) { + "What word would you like to use to replace '{$temp_word}'? "->Print(); + replace_word := System.IO.Console->ReadLine(); + replace_sets->Insert(temp_word, replace_word); + }; + }; + + replace_pairs := replace_sets->GetKeyValues()>; + each(replace_pair in replace_pairs) { + temp_word := replace_pair->GetFirst(); + replace_word := replace_pair->GetSecond(); + + input := input->ReplaceAll(temp_word, replace_word); + } + + input->PrintLine(); + } +} diff --git a/Task/Magic-8-ball/Crystal/magic-8-ball.cr b/Task/Magic-8-ball/Crystal/magic-8-ball.cr new file mode 100644 index 0000000000..63205eb273 --- /dev/null +++ b/Task/Magic-8-ball/Crystal/magic-8-ball.cr @@ -0,0 +1,13 @@ +answers = ["It is certain.", "It is decidedly so.", + "Without a doubt.", "Yes - definitely.", "You may rely on it.", + "As I see it, yes.", "Most likely.", "Outlook good.", + "Yes.", "Signs point to yes.", "Reply hazy, try again.", + "Ask again later.", "Better not tell you now.", "Cannot predict now.", + "Concentrate and ask again.", "Don't count on it.", "My reply is no.", + "My sources say no.", "Outlook not so good.", "Very doubtful."] + +loop do + print "Your question: "; STDOUT.flush + break if (gets || "").empty? + puts answers.sample +end diff --git a/Task/Magic-constant/ANSI-BASIC/magic-constant.basic b/Task/Magic-constant/ANSI-BASIC/magic-constant.basic new file mode 100644 index 0000000000..9a8dfd7b4f --- /dev/null +++ b/Task/Magic-constant/ANSI-BASIC/magic-constant.basic @@ -0,0 +1,25 @@ +100 REM Magic constant +110 DECLARE EXTERNAL FUNCTION A +120 DECLARE EXTERNAL FUNCTION InvA +130 PRINT "The first 20 magic constants are"; +140 FOR N = 1 TO 20 +150 PRINT A(N); +160 NEXT N +170 PRINT +180 PRINT "The 1,000th magic constant is"; A(1000) +190 LET E = 1 +200 FOR N = 1 TO 20 +210 LET E = E * 10 +220 PRINT "10^"; +230 PRINT USING "##: #########": N, InvA(E) +240 NEXT N +250 END +260 REM Returns the magic constant of a magic square of order N + 2 +270 EXTERNAL FUNCTION A(N) +280 LET N2 = N + 2 +290 LET A = IP((N2 * ((N2 * N2) + 1)) / 2) +300 END FUNCTION +310 REM Returns the order of the magic square whose magic constant is at least X +320 EXTERNAL FUNCTION InvA(X) +330 LET InvA = IP((2 * X) ^ (1 / 3)) + 1 +340 END FUNCTION diff --git a/Task/Magic-constant/C/magic-constant.c b/Task/Magic-constant/C/magic-constant.c new file mode 100644 index 0000000000..9d9f01ace2 --- /dev/null +++ b/Task/Magic-constant/C/magic-constant.c @@ -0,0 +1,32 @@ +/* Magic constant */ +#include +#include + +/* returns the magic constant of a magic square of order n + 2 */ +long a(int n) +{ + long n2 = n + 2; + return (n2 * ((n2 * n2) + 1)) / 2; +} + +/* returns the order of the magic square whose magic constant is at least x */ +long inv_a(double x) +{ + return (long)pow((2. * x), 1. / 3.) + 1; +} + +int main() +{ + int n; + double e = 1.; /* final values can be greater than MAX_LONG */ + printf("The first 20 magic constants are "); + for (n = 1; n <= 20; n++) + printf("%d ", a(n)); + printf("\n"); + printf("The 1,000th magic constant is %d\n", a(1000)); + for (n = 1; n <= 20; n++) + { + e *= 10; + printf("10^%2d: %9d\n", n, inv_a(e)); + } +} diff --git a/Task/Magic-constant/GW-BASIC/magic-constant.basic b/Task/Magic-constant/GW-BASIC/magic-constant.basic new file mode 100644 index 0000000000..f4e8107e76 --- /dev/null +++ b/Task/Magic-constant/GW-BASIC/magic-constant.basic @@ -0,0 +1,24 @@ +100 REM Magic constant +110 PRINT "First 20 magic constants:"; +120 FOR N = 3 TO 20 + 3 - 1 +130 PRINT (N * N * N + N) / 2; +140 NEXT N +150 PRINT +160 PRINT "1000th magic constant: "; +170 N# = 1000! + 3 - 1 +180 MC1000# = INT((N# * N# * N# + N#) / 2) +190 PRINT USING "#########"; MC1000# +200 PRINT "Smallest order magic square with a constant greater than:" +210 THRESH# = 10 +220 M# = 3 +230 FOR X = 1 TO 20 +240 MC# = (M# * M# * M# + M#) / 2 +250 M# = M# + 1 +260 IF MC# <= THRESH# THEN 240 +270 PRINT "10^"; +280 PRINT USING "##:"; X; +290 PRINT USING "########"; M# - 1; +300 THRESH# = THRESH# * 10 +310 IF X MOD 5 = O THEN PRINT ELSE PRINT "| "; +320 NEXT X +330 END diff --git a/Task/Magic-constant/Gambas/magic-constant.gambas b/Task/Magic-constant/Gambas/magic-constant.gambas new file mode 100644 index 0000000000..513345ac1f --- /dev/null +++ b/Task/Magic-constant/Gambas/magic-constant.gambas @@ -0,0 +1,35 @@ +Function a(n As Integer) As Long + + n += 2 + Return n * (n ^ 2 + 1) / 2 + +End Function + +Function inv_a(x As Float) As Long + + Dim k As Long = 0 + + While k * (k ^ 2 + 1) / 2 + 2 < x + k += 1 + Wend + Return k + +End Function + +Public Sub Main() + + Dim n As Long + + Print "The first 20 magic constants are: " + + For n = 1 To 20 + Print a(n); " "; + Next + Print + Print "The 1,000th magic constant is "; a(1000) + + For e As Integer = 1 To 20 + Print "10^"; Format(e, "##"); ": "; Format(inv_a(10 ^ e), "#########") + Next + +End Sub diff --git a/Task/Magic-constant/Modula-2/magic-constant.mod2 b/Task/Magic-constant/Modula-2/magic-constant.mod2 new file mode 100644 index 0000000000..36b207d7ef --- /dev/null +++ b/Task/Magic-constant/Modula-2/magic-constant.mod2 @@ -0,0 +1,46 @@ +MODULE MagicConstant; + +FROM STextIO IMPORT WriteString, WriteLn; +FROM SWholeIO IMPORT WriteInt; +FROM RealMath IMPORT exp, ln; + +VAR + N: CARDINAL; + E: REAL; + +(* Returns the magic constant of a magic square of order N + 2 *) +PROCEDURE A(N: CARDINAL): CARDINAL; +VAR + N2: CARDINAL; +BEGIN + N2 := N + 2; + RETURN (N2 * ((N2 * N2) + 1)) DIV 2 +END A; + +(* Returns the order of the magic square whose magic constant is at least X *) +PROCEDURE InvA(X: REAL): CARDINAL; +BEGIN + RETURN VAL(INTEGER, exp(ln((2. * X)) / 3.) + 1.) + (* Use of power(2. * X, 1. / 3.) + 1. does not give enough precision due to rounded exponent *) +END InvA; + +BEGIN + WriteString("The first 20 magic constants are "); + FOR N := 1 TO 20 DO + WriteInt(A(N), 1); + WriteString(" ") + END; + WriteLn; + WriteString("The 1,000th magic constant is "); + WriteInt(A(1000), 1); + WriteLn; + E := 1.; + FOR N := 1 TO 20 DO (* The results are equal to these from Mathematica for N <= 23 *) + E := E * 10.; + WriteString("10^"); + WriteInt(N, 2); + WriteString(": "); + WriteInt(InvA(E), 9); + WriteLn + END +END MagicConstant. diff --git a/Task/Magic-constant/PHP/magic-constant.php b/Task/Magic-constant/PHP/magic-constant.php new file mode 100644 index 0000000000..7ef4633870 --- /dev/null +++ b/Task/Magic-constant/PHP/magic-constant.php @@ -0,0 +1,27 @@ + diff --git a/Task/Magic-constant/REXX/magic-constant.rexx b/Task/Magic-constant/REXX/magic-constant.rexx new file mode 100644 index 0000000000..c83e1efb0e --- /dev/null +++ b/Task/Magic-constant/REXX/magic-constant.rexx @@ -0,0 +1,62 @@ +-- 8 May 2025 +include Settings + +say 'MAGIC CONSTANT' +say version +say +numeric digits 23 +call Getmagics 6e8 +call Task1 +call Task2 +call Task3 +exit + +Getmagics: +call Time('r') +arg xx +say 'Get magic constants up to' xx +say Magics(xx) 'collected' +say Format(Time('e'),,3) 'seconds' +say +return + +Task1: +call Time('r') +say 'The first 25 magic constants are' +do i = 3 to 28 + call Charout ,magi.i' ' +end +say +say Format(Time('e'),,3) 'seconds' +say +return + +Task2: +call Time('r') +say 'The 1000th magic constant is' +say magi.1002 +say Format(Time('e'),,3) 'seconds' +say +return + +Task3: +call Time('r') +say 'Smallest magic square with constant > 10^n is' +say Left('n',5) Right('order',8) +say '--------------' +e = 1 +do i = 3 to 6e7 + if Magic(i) > 1'E'e then do + say Left('10^'e,5) Right(i,8) + e = e+1 + end +end +say '--------------' +say Format(Time('e'),,3) 'seconds' +say +return + +include Functions +include Sequences +include Numbers +include Abend diff --git a/Task/Magic-constant/Tiny-BASIC/magic-constant.basic b/Task/Magic-constant/Tiny-BASIC/magic-constant.basic new file mode 100644 index 0000000000..8f80640163 --- /dev/null +++ b/Task/Magic-constant/Tiny-BASIC/magic-constant.basic @@ -0,0 +1,21 @@ +10 REM MAGIC CONSTANT +20 PRINT "FIRST 20 MAGIC CONSTANTS:" +30 LET N=3 +40 IF N>20+3-1 GOTO 80 +50 PRINT (N*N*N+N)/2, +60 LET N=N+1 +70 GOTO 40 +80 PRINT +90 PRINT "SMALLEST ORDER MAGIC SQUARE WITH A CONSTANT GREATER THAN:" +100 LET T=10 +110 LET M=3 +120 LET X=1 +130 LET L=(M*M*M+M)/2 +140 LET M=M+1 +150 IF L<=T GOTO 130 +160 PRINT "10^";X;":",M-1 +170 LET X=X+1 +180 IF X>4 GOTO 210 +190 LET T=T*10 +200 GOTO 130 +210 END diff --git a/Task/Magic-squares-of-doubly-even-order/EasyLang/magic-squares-of-doubly-even-order.easy b/Task/Magic-squares-of-doubly-even-order/EasyLang/magic-squares-of-doubly-even-order.easy index c13991f0c6..7f982d68fe 100644 --- a/Task/Magic-squares-of-doubly-even-order/EasyLang/magic-squares-of-doubly-even-order.easy +++ b/Task/Magic-squares-of-doubly-even-order/EasyLang/magic-squares-of-doubly-even-order.easy @@ -1,8 +1,6 @@ func[][] mkarr s . len q[][] s - for i = 1 to s - len q[i][] s - . + for i = 1 to s : len q[i][] s return q[][] . func[][] mk_oms s . @@ -12,13 +10,9 @@ func[][] mk_oms s . for p = 1 to s * s q[r][c] = p tc = c + 1 - if tc > s - tc = 1 - . + if tc > s : tc = 1 tr = r - 1 - if tr < 1 - tr = s - . + if tr < 1 : tr = s if q[tr][tc] <> 0 tc = c tr = r + 1 @@ -35,13 +29,9 @@ func[][] mk_dems s . for r = 1 to s for c = 1 to s sx = c mod 4 - if sx < 1 - sx = 4 - . + if sx < 1 : sx = 4 sy = r mod 4 - if sy < 1 - sy = 4 - . + if sy < 1 : sy = 4 if tmp[sy][sx] = 1 q[r][c] = n + 1 else @@ -52,5 +42,6 @@ func[][] mk_dems s . . return q[][] . -numfmt 0 2 -print mk_dems 8 +numfmt 2 0 +r[][] = mk_dems 8 +for i to len r[][] : print r[i][] diff --git a/Task/Magic-squares-of-odd-order/EasyLang/magic-squares-of-odd-order.easy b/Task/Magic-squares-of-odd-order/EasyLang/magic-squares-of-odd-order.easy index 2a148fff4f..4f029cbc2d 100644 --- a/Task/Magic-squares-of-odd-order/EasyLang/magic-squares-of-odd-order.easy +++ b/Task/Magic-squares-of-odd-order/EasyLang/magic-squares-of-odd-order.easy @@ -1,8 +1,8 @@ func f n x y . return (x + y * 2 + 1) mod n . -numfmt 0 3 -proc msqr n . . +numfmt 3 0 +proc msqr n . for i = 0 to n - 1 for j = 0 to n - 1 write f n (n - j - 1) i * n + f n j i + 1 diff --git a/Task/Magic-squares-of-singly-even-order/EasyLang/magic-squares-of-singly-even-order.easy b/Task/Magic-squares-of-singly-even-order/EasyLang/magic-squares-of-singly-even-order.easy index 6eaddd19df..f5c5f88fe9 100644 --- a/Task/Magic-squares-of-singly-even-order/EasyLang/magic-squares-of-singly-even-order.easy +++ b/Task/Magic-squares-of-singly-even-order/EasyLang/magic-squares-of-singly-even-order.easy @@ -1,8 +1,6 @@ func[][] mkarr s . len q[][] s - for i = 1 to s - len q[i][] s - . + for i = 1 to s : len q[i][] s return q[][] . func[][] mk_oms s . @@ -12,13 +10,9 @@ func[][] mk_oms s . for p = 1 to s * s q[r][c] = p tc = c + 1 - if tc > s - tc = 1 - . + if tc > s : tc = 1 tr = r - 1 - if tr < 1 - tr = s - . + if tr < 1 : tr = s if q[tr][tc] <> 0 tc = c tr = r + 1 @@ -59,5 +53,6 @@ func[][] mk_sems s . . return q[][] . -numfmt 0 2 -print mk_sems 6 +numfmt 2 0 +r[][] = mk_sems 6 +for i to len r[][] : print r[i][] diff --git a/Task/Magnanimous-numbers/EasyLang/magnanimous-numbers.easy b/Task/Magnanimous-numbers/EasyLang/magnanimous-numbers.easy index 10295a4f34..8d06c1bc1f 100644 --- a/Task/Magnanimous-numbers/EasyLang/magnanimous-numbers.easy +++ b/Task/Magnanimous-numbers/EasyLang/magnanimous-numbers.easy @@ -1,40 +1,30 @@ fastfunc isprim num . - if num < 2 - return 0 - . + if num < 2 : return 0 i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 . func ismagnan n . - if n < 10 - return 1 - . + if n < 10 : return 1 p = 10 repeat q = n div p r = n mod p - if isprim (q + r) = 0 - return 0 - . + if isprim (q + r) = 0 : return 0 until q < 10 p *= 10 . return 1 . -proc magnan start stop . . +proc magnan start stop . write start & "-" & stop & ":" while count < stop if ismagnan i = 1 count += 1 - if count >= start - write " " & i - . + if count >= start : write " " & i . i += 1 . diff --git a/Task/Magnanimous-numbers/REXX/magnanimous-numbers.rexx b/Task/Magnanimous-numbers/REXX/magnanimous-numbers.rexx index 174e6fca70..d03e5d56c6 100644 --- a/Task/Magnanimous-numbers/REXX/magnanimous-numbers.rexx +++ b/Task/Magnanimous-numbers/REXX/magnanimous-numbers.rexx @@ -1,45 +1,30 @@ -/*REXX pgm finds/displays magnanimous #s (#s with a inserted + sign to sum to a prime).*/ -parse arg bet.1 bet.2 bet.3 highP . /*obtain optional arguments from the CL*/ -if bet.1=='' | bet.1=="," then bet.1= 1..45 /* " " " " " " */ -if bet.2=='' | bet.2=="," then bet.2= 241..250 /* " " " " " " */ -if bet.3=='' | bet.3=="," then bet.3= 391..400 /* " " " " " " */ -if highP=='' | highP=="," then highP= 1000000 /* " " " " " " */ -call genP /*gen primes up to highP (1 million).*/ +-- 22 Mar 2025 +include Settings - do j=1 for 3 /*process three magnanimous "ranges". */ - parse var bet.j LO '..' HI /*obtain the first range (if any). */ - if HI=='' then HI= LO /*Just a single number? Then use LO. */ - if HI==0 then iterate /*Is HI a zero? Then skip this range.*/ - finds= 0; $= /*#: magnanimous # cnt; $: is a list*/ - do k=0 until finds==HI /* [↓] traipse through the number(s). */ - if \magna(k) then iterate /*Not magnanimous? Then skip this num.*/ - finds= finds + 1 /*bump the magnanimous number count. */ - if finds>=LO then $= $ k /*In range► Then add number ──► $ list*/ - end /*k*/ - say - say center(' 'LO "──►" HI 'magnanimous numbers ', 126, "─") - say strip($) - end /*j*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -magna: procedure expose @. !.; parse arg x 1 L 2 '' -1 R /*obtain #, 1st & last digit.*/ - len= length(x); if len==1 then return 1 /*one digit #s are magnanimous*/ - if x>1001 then if L//2 == R//2 then return 0 /*Has parity? Not magnanimous*/ - do s= 1 for len-1 /*traipse thru #, inserting + */ - parse var x y +(s) z; sum= y + z /*parse 2 parts of #, sum 'em.*/ - if !.sum then iterate /*Is sum prime? So far so good*/ - else return 0 /*Nope? Then not magnanimous.*/ - end /*s*/ - return 1 /*Pass all the tests, it's magnanimous.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13 /*assign low primes; # primes.*/ - !.= 0; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1; !.13=1 /* " semaphores to " */ - #= 6; sq.#= @.# ** 2 /*# primes so far; P squared.*/ - do j=@.#+4 by 2 to highP; parse var j '' -1 _; if _==5 then iterate /*÷ by 5?*/ - if j// 3==0 then iterate; if j// 7==0 then iterate /*÷ by 3?; ÷ by 7?*/ - if j//11==0 then iterate /*" " 11? " " 13?*/ - do k=6 while sq.k<=j /*divide by some generated odd primes. */ - if j//@.k==0 then iterate j /*Is J divisible by P? Then not prime*/ - end /*k*/ /* [↓] a prime (J) has been found. */ - #= #+1; @.#= j; sq.#= j*j; !.j= 1 /*bump #Ps; P──►@.assign P; P^2; P flag*/ - end /*j*/; return +say 'MAGNANIMOUS NUMBERS' +say version +say +call Magnanimouss 1e6 +call Range 1 45 +call Range 241 250 +call Range 391 400 +call Range 430 999 +say Time('e')/1 'seconds' +exit + +Range: +procedure expose magn. +arg xx yy +if yy = '' then + yy = xx +say 'The Magnanimous numbers from no' xx 'up to' yy 'are' +do i = xx to Min(yy,magn.0) + call Charout ,magn.i' ' +end +say; say +return + +include Sequences +include Numbers +include Functions +include Abend diff --git a/Task/Mandelbrot-set/EasyLang/mandelbrot-set.easy b/Task/Mandelbrot-set/EasyLang/mandelbrot-set.easy index d5e23ca019..d5dae7370f 100644 --- a/Task/Mandelbrot-set/EasyLang/mandelbrot-set.easy +++ b/Task/Mandelbrot-set/EasyLang/mandelbrot-set.easy @@ -1,21 +1,19 @@ +# Mandelbrot +# res = 4 maxiter = 200 -# -# better but slower: -# res = 8 -# maxiter = 300 -# +# better but slower: res = 8 maxiter = 300 # mid = res * 50 center_x = 3 * mid / 2 center_y = mid scale = mid # -background 000 -textsize 2 +gbackground 000 +gtextsize 2 # -fastfunc iter cx cy maxiter . - while xx + yy < 4 and it < maxiter +fastfunc iter cx cy max . + while xx + yy < 4 and it < max y = 2 * x * y + cy x = xx - yy + cx xx = x * x @@ -24,39 +22,44 @@ fastfunc iter cx cy maxiter . . return it . -proc draw . . - clear +proc draw . + gclear for scr_y = 0 to 2 * mid - 1 cy = (scr_y - center_y) / scale for scr_x = 0 to 2 * mid - 1 cx = (scr_x - center_x) / scale it = iter cx cy maxiter if it < maxiter - color3 it / 20 it / 100 it / 150 - move scr_x / res scr_y / res - rect 1 / res 1 / res + gcolor3 it / 20 it / 100 it / 150 + grect scr_x / res scr_y / res 1 / res 1 / res . . . - color 990 - move 1 1 - text "Short press to zoom in, long to zoom out" + gcolor 990 + gtext 1 1 "Short press to zoom in, long to zoom out" . -on mouse_down - time0 = systime -. -on mouse_up - center_x += mid - mouse_x * res - center_y += mid - mouse_y * res - if systime - time0 < 0.3 - center_x -= mid - center_x - center_y -= mid - center_y - scale *= 2 - else +on timer + if done = 0 center_x += (mid - center_x) * 3 / 4 center_y += (mid - center_y) * 3 / 4 scale /= 4 + draw + done = 1 + . +. +on mouse_down + done = 0 + center_x += mid - mouse_x * res + center_y += mid - mouse_y * res + timer 0.3 +. +on mouse_up + if done = 0 + center_x -= mid - center_x + center_y -= mid - center_y + scale *= 2 + draw + done = 1 . - draw . draw diff --git a/Task/Mandelbrot-set/Julia/mandelbrot-set-7.jl b/Task/Mandelbrot-set/Julia/mandelbrot-set-7.jl index ee9e72e8f7..2dc45623ad 100644 --- a/Task/Mandelbrot-set/Julia/mandelbrot-set-7.jl +++ b/Task/Mandelbrot-set/Julia/mandelbrot-set-7.jl @@ -1,3 +1,4 @@ +using Base.Threads using Plots gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200) @@ -26,21 +27,45 @@ end x = range(0, 2, length=d+1) y = range(0, 2 * h / d, length=h+1) -A, B = collect(x) .* pi, collect(y) .* pi -C = 8.0 .* exp.((A' .+ B .* im) .* im) +A, B = collect(Float64, x) .* pi, collect(Float64, y) .* pi +C = (- 8.0) .* exp.((A' .+ B .* im) .* im) -E, Z, dZ = zero(C), zero(C), zero(C) -D, I, J = zeros(size(C)), ones(Int64, size(C)), ones(Int64, size(C)) +function iteration(C) + E, I, J = zero(C), ones(Int64, size(C)), ones(Int64, size(C)) + Z, dZ = zero(C), zero(C) -for k in 1:n - M, R = abs2.(Z) .< abs2(r), abs2.(Z) .< abs2.(E) - E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero - E[M], I[M] = (2 .* S[I[M]] .+ E[M]) .* E[M] .+ C[M], I[M] .+ 1 - Z[M], dZ[M] = S[I[M]] .+ E[M], 2 .* Z[M] .* dZ[M] .+ 1 + function iterate(E, I, Z, dZ, C) + E, I = (2 .* S[I] .+ E) .* E .+ C, I .+ 1 + Z, dZ = S[I] .+ E, 2 .* Z .* dZ .+ 1 + return E, I, Z, dZ + end + + for k in 1:n + M = abs2.(Z) .< abs2.(E) + E[M], I[M] = Z[M], J[M] # rebase when z is closer to zero + M = abs2.(Z) .< abs2(r) + E[M], I[M], Z[M], dZ[M] = iterate(E[M], I[M], Z[M], dZ[M], C[M]) + end + + return E, I, Z, dZ end +function calculation(C) + E, I = zero(C), ones(Int64, size(C)) + Z, dZ = zero(C), zero(C) + + @threads for j in 1:size(C)[2] + E[:,j], I[:,j], Z[:,j], dZ[:,j] = iteration(C[:,j]) + end + + return E, I, Z, dZ +end + +E, I, Z, dZ = calculation(C) +D = zeros(Float64, size(C)) + N = abs.(Z) .> 2 # exterior distance estimation D[N] = log.(abs.(Z[N])) .* abs.(Z[N]) ./ abs.(dZ[N]) -heatmap(D' .^ 0.015, c=:nipy_spectral) +heatmap(D' .^ 0.015, c=:gist_ncar) savefig("Mercator_Mandelbrot_deep_map.png") diff --git a/Task/Mandelbrot-set/Python/mandelbrot-set-8.py b/Task/Mandelbrot-set/Python/mandelbrot-set-8.py index 09666f5ed1..d4580ac79d 100644 --- a/Task/Mandelbrot-set/Python/mandelbrot-set-8.py +++ b/Task/Mandelbrot-set/Python/mandelbrot-set-8.py @@ -1,10 +1,11 @@ import numpy as np +import numba as nb import matplotlib.pyplot as plt import decimal as dc # decimal floating point arithmetic with arbitrary precision dc.getcontext().prec = 80 # set precision to 80 digits (about 256 bits) -d, h = 50, 1000 # pixel density (= image width) and image height +d, h = 100, 2000 # pixel density (= image width) and image height n, r = 80000, 100000 # number of iterations and escape radius (r > 2) a = dc.Decimal("-1.256827152259138864846434197797294538253477389787308085590211144291") @@ -15,8 +16,8 @@ u, v = dc.Decimal(0), dc.Decimal(0) for k in range(n+1): S[k] = float(u) + float(v) * 1j - if u ** 2 + v ** 2 < r ** 2: - u, v = u ** 2 - v ** 2 + a, 2 * u * v + b + if u * u + v * v < r * r: + u, v = u * u - v * v + a, 2 * u * v + b else: print("The reference sequence diverges within %s iterations." % k) break @@ -25,20 +26,43 @@ x = np.linspace(0, 2, num=d+1, dtype=np.float64) y = np.linspace(0, 2 * h / d, num=h+1, dtype=np.float64) A, B = np.meshgrid(x * np.pi, y * np.pi) -C = 8.0 * np.exp((A + B * 1j) * 1j) +C = (- 8.0) * np.exp((A + B * 1j) * 1j) -E, Z, dZ = np.zeros_like(C), np.zeros_like(C), np.zeros_like(C) -D, I, J = np.zeros(C.shape), np.zeros(C.shape, dtype=np.int64), np.zeros(C.shape, dtype=np.int64) +@nb.njit(parallel=True) +def calculation(C): + E, I = np.zeros_like(C), np.zeros(C.shape, dtype=np.int64) + Z, dZ = np.zeros_like(C), np.zeros_like(C) -for k in range(n): - Z2 = Z.real ** 2 + Z.imag ** 2 - M, R = Z2 < r ** 2, Z2 < E.real ** 2 + E.imag ** 2 - E[R], I[R] = Z[R], J[R] # rebase when z is closer to zero - E[M], I[M] = (2 * S[I[M]] + E[M]) * E[M] + C[M], I[M] + 1 - Z[M], dZ[M] = S[I[M]] + E[M], 2 * Z[M] * dZ[M] + 1 + def iteration(C): + E, I = np.zeros_like(C), np.zeros(C.shape, dtype=np.int64) + Z, dZ = np.zeros_like(C), np.zeros_like(C) + + def abs2(z): + return z.real * z.real + z.imag * z.imag + + def iterate(E, I, Z, dZ, C): + E, I = (2 * S[I] + E) * E + C, I + 1 + Z, dZ = S[I] + E, 2 * Z * dZ + 1 + return E, I, Z, dZ + + for k in range(n): + M = abs2(Z) < abs2(E) + E[M], I[M] = Z[M], 0 # rebase when z is closer to zero + M = abs2(Z) < abs2(r) + E[M], I[M], Z[M], dZ[M] = iterate(E[M], I[M], Z[M], dZ[M], C[M]) + + return E, I, Z, dZ + + for j in nb.prange(C.shape[1]): + E[:,j], I[:,j], Z[:,j], dZ[:,j] = iteration(C[:,j]) + + return E, I, Z, dZ + +E, I, Z, dZ = calculation(C) +D = np.zeros(C.shape, dtype=np.float64) N = abs(Z) > 2 # exterior distance estimation D[N] = np.log(abs(Z[N])) * abs(Z[N]) / abs(dZ[N]) -plt.imshow(D.T ** 0.015, cmap=plt.cm.nipy_spectral, origin="lower") +plt.imshow(D.T ** 0.015, cmap=plt.cm.gist_ncar, origin="lower") plt.savefig("Mercator_Mandelbrot_deep_map.png", dpi=200) diff --git a/Task/Map-range/ANSI-BASIC/map-range.basic b/Task/Map-range/ANSI-BASIC/map-range.basic new file mode 100644 index 0000000000..a78bcc8db9 --- /dev/null +++ b/Task/Map-range/ANSI-BASIC/map-range.basic @@ -0,0 +1,10 @@ +100 REM Map range +110 DECLARE EXTERNAL FUNCTION MapRange +120 FOR I = 0 TO 10 +130 PRINT USING "## maps to ##.#": I, MapRange(I, 0, 10, -1, 0) +140 NEXT I +150 END +160 REM ***************************************** +170 EXTERNAL FUNCTION MapRange(S, A1, A2, B1, B2) +180 LET MapRange = B1 + (S - A1) * (B2 - B1) / (A2 - A1) +190 END FUNCTION diff --git a/Task/Map-range/Free-Pascal-Lazarus/map-range-1.pas b/Task/Map-range/Free-Pascal-Lazarus/map-range-1.pas new file mode 100644 index 0000000000..c4291235b1 --- /dev/null +++ b/Task/Map-range/Free-Pascal-Lazarus/map-range-1.pas @@ -0,0 +1,13 @@ +Program Map(output); + function MapRange(fromRange, toRange: array of real; value: real): real; + begin + MapRange := (value - fromRange[0]) * (toRange[1] - toRange[0]) / + (fromRange[1] - fromRange[0]) + toRange[0]; + end; + +var + i: integer; +begin + for i := 0 to 10 do + writeln(i: 2, ' maps to: ', MapRange([0.0, 10.0], [-1.0, 0.0], i): 5: 2); +end. diff --git a/Task/Map-range/Free-Pascal-Lazarus/map-range-2.pas b/Task/Map-range/Free-Pascal-Lazarus/map-range-2.pas new file mode 100644 index 0000000000..b2f292aaac --- /dev/null +++ b/Task/Map-range/Free-Pascal-Lazarus/map-range-2.pas @@ -0,0 +1,58 @@ +Program Map(output); + +type + real = double; + tRange = array [0..1] of real; + + tMapRec = record + mrFrom, + mrTo: tRange; + mrScale: real + end; + + function InitRange(rfrom, rTo: real): tRange; + begin + InitRange[0] := rfrom; + InitRange[1] := rTo; + end; + + function InitMapRec(const fromRange, toRange: tRange): tMapRec; + begin + with InitMapRec do + begin + mrFrom := fromRange; + mrTo := toRange; + mrScale := (toRange[1] - toRange[0]) / (fromRange[1] - fromRange[0]); + end; + end; + + function MapRecRange(const value: real; var MR: tMapRec): real; + begin + with MR do + MapRecRange := (value - mrFrom[0]) * mrScale + mrTo[0]; + end; + + function MapRange(const value: real; const fromRange, toRange: tRange): real; + begin + MapRange := (value - fromRange[0]) * (toRange[1] - toRange[0]) / + (fromRange[1] - fromRange[0]) + toRange[0]; + end; + +var + value: real; + rFrom, rTo: tRange; + mr: tMapRec; + i: longint; + +begin + rFrom := InitRange(0, 10); + rTo := InitRange(-1, 0); + mr := InitMapRec(rFrom, rTo); + + for i := 0 to 10 do + begin + value := i; + writeln(i: 4, ' maps to: ', MapRange(value, rFrom, rTo): 10: 6, + MapRecRange(value, mr): 10: 6); + end; +end. diff --git a/Task/Map-range/GW-BASIC/map-range.basic b/Task/Map-range/GW-BASIC/map-range.basic new file mode 100644 index 0000000000..f1129818c2 --- /dev/null +++ b/Task/Map-range/GW-BASIC/map-range.basic @@ -0,0 +1,13 @@ +100 REM Map range +110 DEF FN MR(S) = B1 + (S - A1) * (B2 - B1) / (A2 - A1) +120 A1 = 0: A2 = 10: B1 = -1: B2 = 0 +130 FOR X = A1 TO A2 STEP 2 +140 PRINT USING "## maps to ##.#"; X; FN MR(X) +150 NEXT X +160 REM Inverse mapping to illustrate change of parameters +170 PRINT: PRINT "Inverse mapping:" +180 A1 = -1: A2 = 0: B1 = 0: B2 = 10 +190 FOR X = A1 TO A2 STEP .2 +200 PRINT USING "##.# maps to ##"; X; FN MR(X) +210 NEXT X +220 END diff --git a/Task/Map-range/Liberty-BASIC/map-range.basic b/Task/Map-range/Liberty-BASIC/map-range.basic index 8c6669ef67..5d604e7876 100644 --- a/Task/Map-range/Liberty-BASIC/map-range.basic +++ b/Task/Map-range/Liberty-BASIC/map-range.basic @@ -1,8 +1,10 @@ -For i = 0 To 10 - Print "f(";i;") maps to ";mapToRange(i, 0, 10, -1, 0) -Next i -End +' map range +for i = 0 to 10 + print using("##.#", i); " maps to "; + print using("##.#", mapRange(i, 0, 10, -1, 0)) +next i +end -Function mapToRange(value, inputMin, inputMax, outputMin, outputMax) - mapToRange = (((value - inputMin) * (outputMax - outputMin)) / (inputMax - inputMin)) + outputMin -End Function +function mapRange(s, a1, a2, b1, b2) + mapRange = b1 + (s - a1) * (b2 - b1) / (a2 - a1) +end function diff --git a/Task/Map-range/Modula-2/map-range.mod2 b/Task/Map-range/Modula-2/map-range.mod2 new file mode 100644 index 0000000000..8ee51378e0 --- /dev/null +++ b/Task/Map-range/Modula-2/map-range.mod2 @@ -0,0 +1,22 @@ +MODULE MapRange; + +FROM STextIO IMPORT WriteLn, WriteString; +FROM SWholeIO IMPORT WriteInt; +FROM SRealIO IMPORT WriteFixed; + +VAR + I: INTEGER; + +PROCEDURE MapRange(S, A1, A2, B1, B2: REAL): REAL; +BEGIN + RETURN B1 + (S - A1) * (B2 - B1) / (A2 - A1) +END MapRange; + +BEGIN + FOR I := 0 TO 10 DO + WriteInt(I, 2); + WriteString(" maps to "); + WriteFixed(MapRange(FLOAT(I), 0., 10., -1., 0.), 1, 4); + WriteLn; + END; +END MapRange. diff --git a/Task/Map-range/PHP/map-range.php b/Task/Map-range/PHP/map-range.php new file mode 100644 index 0000000000..90f7f1821b --- /dev/null +++ b/Task/Map-range/PHP/map-range.php @@ -0,0 +1,15 @@ + diff --git a/Task/Map-range/Pascal/map-range-1.pas b/Task/Map-range/Pascal/map-range-1.pas deleted file mode 100644 index 33e3a87d57..0000000000 --- a/Task/Map-range/Pascal/map-range-1.pas +++ /dev/null @@ -1,13 +0,0 @@ -Program Map(output); - -function MapRange(fromRange, toRange: array of real; value: real): real; - begin - MapRange := (value-fromRange[0]) * (toRange[1]-toRange[0]) / (fromRange[1]-fromRange[0]) + toRange[0]; - end; - -var - i: integer; -begin - for i := 0 to 10 do - writeln (i, ' maps to: ', MapRange([0.0, 10.0], [-1.0, 0.0], i):4:2); -end. diff --git a/Task/Map-range/Pascal/map-range-2.pas b/Task/Map-range/Pascal/map-range-2.pas deleted file mode 100644 index ce16131c1b..0000000000 --- a/Task/Map-range/Pascal/map-range-2.pas +++ /dev/null @@ -1,56 +0,0 @@ -Program Map(output); - -type - real = double; - tRange = Array [0..1] of real; - tMapRec = record - mrFrom, - mrTo : tRange; - mrScale : real - end; - -function InitRange(rfrom,rTo:real):tRange; -begin - InitRange[0] :=rfrom; - InitRange[1] :=rTo; -end; - -function InitMapRec(const fromRange, toRange: tRange):tMapRec; -begin - With InitMapRec do - Begin - mrFrom := fromRange; - mrTo := toRange; - mrScale := (toRange[1]-toRange[0]) / (fromRange[1]-fromRange[0]); - end; -end; - -function MapRecRange(const value: real;var MR :tMapRec): real; -begin - with MR do - MapRecRange := (value-mrFrom[0]) * mrScale + mrTo[0]; -end; - -function MapRange(const value: real;const fromRange, toRange: tRange): real; -begin - MapRange := (value-fromRange[0]) * (toRange[1]-toRange[0]) / (fromRange[1]-fromRange[0]) + toRange[0]; -end; - -var - value:real; - rFrom,rTo : tRange; - mr : tMapRec; - i: LongInt; - -begin - rFrom:= InitRange( 0, 10); - rTo := InitRange( -1, 0); - mr:= InitMapRec(rFrom,rTo); - - for i := 0 to 10 do - Begin - value := i; - writeln (i:4, ' maps to: ', MapRange(value,rFrom, rTo):10:6, - MapRecRange(value,mr):10:6); - end; -end. diff --git a/Task/Map-range/QBasic/map-range.basic b/Task/Map-range/QBasic/map-range.basic new file mode 100644 index 0000000000..d9f3d649fe --- /dev/null +++ b/Task/Map-range/QBasic/map-range.basic @@ -0,0 +1,10 @@ +REM Map range +DECLARE FUNCTION MapRange (S, A1, A2, B1, B2) +FOR I = 0 TO 10 + PRINT USING "## maps to ##.#"; I; MapRange(I, 0, 10, -1, 0) +NEXT I +END + +FUNCTION MapRange (S, A1, A2, B1, B2) + MapRange = B1 + (S - A1) * (B2 - B1) / (A2 - A1) +END FUNCTION diff --git a/Task/Map-range/RapidQ/map-range.rapidq b/Task/Map-range/RapidQ/map-range.rapidq new file mode 100644 index 0000000000..79151aad00 --- /dev/null +++ b/Task/Map-range/RapidQ/map-range.rapidq @@ -0,0 +1,11 @@ +' Map range +DECLARE FUNCTION MapRange (S#, A1#, A2#, B1#, B2#) AS DOUBLE +FOR I = 0 TO 10 + PRINT FORMAT$("%4.1f", I); " maps to "; + PRINT FORMAT$("%4.1f", MapRange(I, 0, 10, -1, 0)) +NEXT I +END + +FUNCTION MapRange (S#, A1#, A2#, B1#, B2#) AS DOUBLE + MapRange = B1# + (S# - A1#) * (B2# - B1#) / (A2# - A1#) +END FUNCTION diff --git a/Task/Map-range/TypeScript/map-range.ts b/Task/Map-range/TypeScript/map-range.ts new file mode 100644 index 0000000000..5eb4f6f01b --- /dev/null +++ b/Task/Map-range/TypeScript/map-range.ts @@ -0,0 +1,14 @@ +function mapRange( + a: number[], + b: number[], + s: number +): number { + return b[0] + (s-a[0]) * (b[1]-b[0]) / (a[1]-a[0]); +} + +const a = [0, 10]; +const b = [-1, 0]; + +for (let s = 0; s < 11; s++) { + console.log(`${s} -> ${mapRange(a, b, s)}`); +} diff --git a/Task/Mastermind/EasyLang/mastermind.easy b/Task/Mastermind/EasyLang/mastermind.easy index 0ad14ab4a5..b67a1981c7 100644 --- a/Task/Mastermind/EasyLang/mastermind.easy +++ b/Task/Mastermind/EasyLang/mastermind.easy @@ -1,94 +1,75 @@ -# Mastermind:w90 -# col[] = [ 802 990 171 229 950 808 ] len code[] 4 len guess[] 4 +row = 0 # -subr init_vars - row = 0 -. -proc draw_rate r black white . . - for j range0 2 - for c range0 2 - move c * 3.5 + 71.5 r * 11.5 + 9.4 - j * 3.5 - if black > 0 - color 000 - circle 1.4 - black -= 1 - elif white > 0 - color 999 - circle 1.4 - white -= 1 - else - color 310 - circle 0.7 - . +proc draw_rate r black white . + for j range0 2 : for c range0 2 + x = c * 3.5 + 71.5 + y = r * 11.5 + 9.4 - j * 3.5 + if black > 0 + gcolor 000 + gcircle x y 1.4 + black -= 1 + elif white > 0 + gcolor 999 + gcircle x y 1.4 + white -= 1 + else + gcolor 310 + gcircle x y 0.7 . . . -proc show_code . . - color 531 - move 22 92 - rect 46 8 +proc show_code . + gcolor 531 + grect 22 92 46 8 for i to 4 - move i * 8 + 20 97 - color col[code[i]] - circle 2 + gcolor col[code[i]] + gcircle i * 8 + 20 97 2 . . -proc draw_guess . . +proc draw_guess . for c to 4 - move c * 12 + 8 row * 11.5 + 7.5 - color col[guess[c]] - circle 3.8 + gcolor col[guess[c]] + gcircle c * 12 + 8 row * 11.5 + 7.5 3.8 . . -proc next_row . . - color 420 - linewidth 11 - move 17 row * 11.5 + 7.5 - line 60 row * 11.5 + 7.5 +proc next_row . + gcolor 420 + glinewidth 11 + gline 17 row * 11.5 + 7.5 60 row * 11.5 + 7.5 draw_guess - move 73.5 row * 11.5 + 7.5 - color 310 - circle 5.0 - color 753 - move 71.5 row * 11.5 + 5 - textsize 7 - text "✓" + gcolor 310 + gcircle 73.5 row * 11.5 + 7.5 5.0 + gcolor 753 + gtextsize 7 + gtext 71.5 row * 11.5 + 5 "✓" . -proc rate . . - move 73.5 row * 11.5 + 7.5 - color 531 - circle 5.2 +proc rate . + gcolor 531 + gcircle 73.5 row * 11.5 + 7.5 5.2 c[] = code[] g[] = guess[] - for i to 4 - if c[i] = g[i] - black += 1 - c[i] = -1 - g[i] = -2 - . + for i to 4 : if c[i] = g[i] + black += 1 + c[i] = -1 + g[i] = -2 . - for i to 4 - for j to 4 - if c[i] = g[j] - white += 1 - c[i] = -1 - g[j] = -2 - . + for i to 4 : for j to 4 + if c[i] = g[j] + white += 1 + c[i] = -1 + g[j] = -2 . . draw_rate row black white - color 531 - linewidth 12 - move 17 row * 11.5 + 7.5 - line 60 row * 11.5 + 7.5 + gcolor 531 + glinewidth 12 + gline 17 row * 11.5 + 7.5 60 row * 11.5 + 7.5 draw_guess row += 1 - if black = 4 - row = 8 - . + if black = 4 : row = 8 if row = 8 show_code timer 2 @@ -97,42 +78,32 @@ proc rate . . . . on timer - row = -2 + row = -1 . -proc new . . - init_vars - for i to 4 - code[i] = random 6 - . - color 531 - move 10 10 - rect 70 80 - linewidth 10 - move 5 95 - line 5 5 - line 85 5 - line 85 95 - line 5 95 - color 310 - linewidth 7 - move 28 96.5 - line 58 96.5 - move 30 95 - color 864 - textsize 4 - text "Mastermind" - color 310 - linewidth 0.5 - move 10 90 - line 10 4 - move 67 90 - line 67 4 - move 80 90 - line 80 4 +proc new . + row = 0 + for i to 4 : code[i] = random 6 + gcolor 531 + grect 10 10 70 80 + glinewidth 10 + gline 5 95 5 5 + gline 5 5 85 5 + gline 85 5 85 95 + gline 85 95 5 95 + gcolor 310 + glinewidth 7 + gline 28 96.5 58 96.5 + gcolor 864 + gtextsize 4 + gtext 30 95 "Mastermind" + gcolor 310 + glinewidth 0.5 + gline 10 90 10 4 + gline 67 90 67 4 + gline 80 90 80 4 for r range0 8 for c range0 4 - move c * 12 + 20 r * 11.5 + 7.5 - circle 2 + gcircle c * 12 + 20 r * 11.5 + 7.5 2 . draw_rate r 0 0 . @@ -142,13 +113,13 @@ proc new . . guess[4] = 2 next_row . -proc do_move . . +proc do_move . c = (mouse_x - 15) div 12 guess[c + 1] = guess[c + 1] mod 6 + 1 draw_guess . on mouse_down - if row = -2 + if row = -1 new elif mouse_y > row * 11.5 + 0.5 and mouse_y < row * 11.5 + 10.5 and row < 8 if mouse_x > 15 and mouse_x < 61 diff --git a/Task/Matrix-chain-multiplication/EasyLang/matrix-chain-multiplication.easy b/Task/Matrix-chain-multiplication/EasyLang/matrix-chain-multiplication.easy index 091dd80778..5c013f5f84 100644 --- a/Task/Matrix-chain-multiplication/EasyLang/matrix-chain-multiplication.easy +++ b/Task/Matrix-chain-multiplication/EasyLang/matrix-chain-multiplication.easy @@ -1,5 +1,5 @@ global m[][] s[][] dims[] . -proc mat_chain_order . . +proc mat_chain_order . n = len dims[] - 1 m[][] = [ ] ; len m[][] n s[][] = [ ] ; len s[][] n @@ -27,7 +27,7 @@ func$ path a b . . return "(" & path a s[a][b] & path (s[a][b] + 1) b & ")" . -proc pr_chain_order . . +proc pr_chain_order . print "Order : " & path 1 len s[][] . dims[][] = [ [ 5 6 3 1 ] [ 1 5 25 30 100 70 2 1 100 250 1 1000 2 ] [ 1000 1 500 12 1 700 2500 3 2 5 14 10 ] ] diff --git a/Task/Matrix-multiplication/VBScript/matrix-multiplication.vb b/Task/Matrix-multiplication/VBScript/matrix-multiplication.vb index f86de4287d..89d5caa161 100644 --- a/Task/Matrix-multiplication/VBScript/matrix-multiplication.vb +++ b/Task/Matrix-multiplication/VBScript/matrix-multiplication.vb @@ -7,13 +7,21 @@ matrix2(0,0) = 9 : matrix2(0,1) = 2 : matrix2(0,2) = 1 matrix2(1,0) = -7 : matrix2(1,1) = 3 : matrix2(1,2) = -10 matrix2(2,0) = 4 : matrix2(2,1) = 5 : matrix2(2,2) = -6 -Call multiply_matrix(matrix1,matrix2) +function getMatrixProduct(firstMatrix,secondMatrix) + if ubound(firstMatrix,2) <> ubound(secondMatrix,1) then exit function + redim resultMatrix(ubound(firstMatrix,1),ubound(secondMatrix,2)) + for i = 0 to ubound(firstMatrix,1) : for j = 0 to ubound(secondMatrix,2) : for k = 0 to ubound(firstMatrix,2) + resultMatrix(i,j) = resultMatrix(i,j) + (firstMatrix(i,k) * secondMatrix(k,j)) + next : next : next + getMatrixProduct = resultMatrix +End function -Sub multiply_matrix(arr1,arr2) - For i = 0 To UBound(arr1) - For j = 0 To 2 - WScript.StdOut.Write (arr1(i,j) * arr2(i,j)) & vbTab - Next - WScript.StdOut.WriteLine - Next -End Sub +dim resultMatrix : resultMatrix = getMatrixProduct(matrix1,matrix2) +dim outputString +for a = 0 to ubound(resultMatrix,1) + for b = 0 to ubound(resultMatrix,2) + outputString = outputString & resultMatrix(a,b) & vbTab + next + outputString = outputString & vbCrlf +next +msgbox outputString diff --git a/Task/Matrix-transposition/EasyLang/matrix-transposition.easy b/Task/Matrix-transposition/EasyLang/matrix-transposition.easy index 2fa5821aa3..2e997c99c4 100644 --- a/Task/Matrix-transposition/EasyLang/matrix-transposition.easy +++ b/Task/Matrix-transposition/EasyLang/matrix-transposition.easy @@ -1,4 +1,4 @@ -proc transpose . m[][] . +proc transpose &m[][] . len n[][] len m[1][] for i to len n[][] for j to len m[][] diff --git a/Task/Matrix-transposition/Uiua/matrix-transposition.uiua b/Task/Matrix-transposition/Uiua/matrix-transposition.uiua new file mode 100644 index 0000000000..115cea314a --- /dev/null +++ b/Task/Matrix-transposition/Uiua/matrix-transposition.uiua @@ -0,0 +1,2 @@ +$matrix°△2_5 +$transposed⊸⍉ diff --git a/Task/Mayan-numerals/EasyLang/mayan-numerals.easy b/Task/Mayan-numerals/EasyLang/mayan-numerals.easy index 55ec0fd97a..60ebc7b13a 100644 --- a/Task/Mayan-numerals/EasyLang/mayan-numerals.easy +++ b/Task/Mayan-numerals/EasyLang/mayan-numerals.easy @@ -1,7 +1,5 @@ func[] base20 n . - if n < 20 - return [ n ] - . + if n < 20 : return [ n ] r[] = base20 (n div 20) r[] &= n mod 20 return r[] @@ -24,13 +22,11 @@ func$[] mayan d . . return r$[] . -proc drawma . mayans$[][] . +proc drawma &mayans$[][] . idx = len mayans$[][] write "╔" for i to idx - for j to 4 - write "═" - . + for j to 4 : write "═" if i < idx write "╦" else @@ -39,16 +35,12 @@ proc drawma . mayans$[][] . . for i to 4 write "║" - for j to idx - write mayans$[j][i] & "║" - . + for j to idx : write mayans$[j][i] & "║" print "" . write "╚" for i to idx - for j to 4 - write "═" - . + for j to 4 : write "═" if i < idx write "╩" else diff --git a/Task/Maze-generation/EasyLang/maze-generation.easy b/Task/Maze-generation/EasyLang/maze-generation.easy index cc5c352028..7481497c93 100644 --- a/Task/Maze-generation/EasyLang/maze-generation.easy +++ b/Task/Maze-generation/EasyLang/maze-generation.easy @@ -3,23 +3,23 @@ n = 2 * size + 1 f = 100 / (n - 0.5) len m[] n * n # -background 000 -proc show_maze . . - clear +gbackground 000 +proc show_maze . + gclear + sz = f * 1.5 + f2 = f / 2 for i = 1 to len m[] if m[i] = 0 x = (i - 1) mod n y = (i - 1) div n - color 999 - move x * f - f / 2 y * f - f / 2 - rect f * 1.5 f * 1.5 + gcolor 999 + grect x * f - f2 y * f - f2 sz sz . . sleep 0.01 . offs[] = [ 1 n -1 (-n) ] -# -proc m_maze pos . . +proc m_maze pos . m[pos] = 0 show_maze d[] = [ 1 2 3 4 ] @@ -34,7 +34,7 @@ proc m_maze pos . . . . endpos = n * n - 1 -proc make_maze . . +proc make_maze . for i = 1 to len m[] m[i] = 1 . @@ -47,7 +47,6 @@ proc make_maze . . h = 2 * random 15 - n + n * 2 * random 15 m_maze h m[endpos] = 0 - endpos += n . make_maze show_maze diff --git a/Task/Maze-solving/EasyLang/maze-solving.easy b/Task/Maze-solving/EasyLang/maze-solving.easy index 52f27f223c..b5e6fcee73 100644 --- a/Task/Maze-solving/EasyLang/maze-solving.easy +++ b/Task/Maze-solving/EasyLang/maze-solving.easy @@ -3,22 +3,23 @@ n = 2 * size + 1 f = 100 / (n - 0.5) len m[] n * n # -background 000 -proc show_maze . . - clear +gbackground 000 +proc show_maze . + gclear + sz = f * 1.5 + f2 = f / 2 for i = 1 to len m[] if m[i] = 0 x = (i - 1) mod n y = (i - 1) div n - color 999 - move x * f - f / 2 y * f - f / 2 - rect f * 1.5 f * 1.5 + gcolor 999 + grect x * f - f2 y * f - f2 sz sz . . sleep 0.01 . offs[] = [ 1 n -1 (-n) ] -proc m_maze pos . . +proc m_maze pos . m[pos] = 0 show_maze d[] = [ 1 2 3 4 ] @@ -33,7 +34,7 @@ proc m_maze pos . . . . endpos = n * n - 1 -proc make_maze . . +proc make_maze . for i = 1 to len m[] m[i] = 1 . @@ -50,18 +51,15 @@ proc make_maze . . make_maze show_maze # -proc mark pos col . . +proc mark pos col . x = (pos - 1) mod n y = (pos - 1) div n - color col - move x * f + f / 4 y * f + f / 4 - circle f / 3.5 + gcolor col + gcircle x * f + f / 4 y * f + f / 4 f / 3.5 . -global found . -proc solve dir0 pos . . - if found = 1 - return - . +found = 0 +proc solve dir0 pos . + if found = 1 : return mark pos 900 sleep 0.05 if pos = endpos diff --git a/Task/Median-filter/Rust/median-filter.rs b/Task/Median-filter/Rust/median-filter.rs new file mode 100644 index 0000000000..beade0f55d --- /dev/null +++ b/Task/Median-filter/Rust/median-filter.rs @@ -0,0 +1,510 @@ +use std::env; +use std::fs::File; +use std::io::{self, BufRead, BufReader, BufWriter, Read, Write}; +use std::path::Path; +use std::process; + +// --- Data Structures --- + +// Equivalent to rgb_t +#[derive(Clone, Copy, Debug, Default)] +#[repr(C)] // Ensure memory layout is R, G, B for potential raw I/O +struct Rgb { + r: u8, + g: u8, + b: u8, +} + +// Equivalent to image_t, but using Vec for safe memory management +#[derive(Debug)] +struct Image { + width: usize, + height: usize, + pixels: Vec, // Flat pixel buffer +} + +impl Image { + // Creates a new black image + fn new(width: usize, height: usize) -> Self { + Image { + width, + height, + pixels: vec![Rgb::default(); width * height], + } + } + + // Helper to get a pixel reference (immutable) + fn get_pixel(&self, row: usize, col: usize) -> Option<&Rgb> { + if row < self.height && col < self.width { + self.pixels.get(row * self.width + col) + } else { + None + } + } + + // Helper to get a pixel reference (mutable) + fn get_pixel_mut(&mut self, row: usize, col: usize) -> Option<&mut Rgb> { + if row < self.height && col < self.width { + self.pixels.get_mut(row * self.width + col) + } else { + None + } + } + + // Helper for direct index access (use with caution or after bounds check) + fn index(&self, row: usize, col: usize) -> usize { + row * self.width + col + } +} + +// Equivalent to color_histo_t +#[derive(Debug)] +struct ColorHisto { + r: [i32; 256], + g: [i32; 256], + b: [i32; 256], + n: i32, // Total number of pixels counted +} + +impl ColorHisto { + fn new() -> Self { + ColorHisto { + r: [0; 256], + g: [0; 256], + b: [0; 256], + n: 0, + } + } + + // Add a pixel's color to the histogram + fn add_pixel(&mut self, pixel: Rgb) { + self.r[pixel.r as usize] += 1; + self.g[pixel.g as usize] += 1; + self.b[pixel.b as usize] += 1; + self.n += 1; + } + + // Remove a pixel's color from the histogram + fn del_pixel(&mut self, pixel: Rgb) { + self.r[pixel.r as usize] -= 1; + self.g[pixel.g as usize] -= 1; + self.b[pixel.b as usize] -= 1; + self.n -= 1; + } +} + +// --- PPM Reading/Writing --- + +// Helper to read ASCII numbers, skipping comments and whitespace +// This is more robust than the C version's reliance on fscanf specifics. +fn read_ascii_int(reader: &mut R) -> io::Result { + let mut buf = Vec::new(); + let mut digits = Vec::new(); + + loop { + buf.clear(); + // Read until comment or EOF. Limit read size to avoid large allocations on invalid input. + // reader.read_until(b'#', &mut buf)?; // Reads potentially large chunks + + // Read byte by byte for finer control over comments and whitespace + let byte_read = reader.read_until(b'#', &mut buf); + match byte_read { + Ok(0) => break, // EOF + Ok(_) => {}, + Err(e) => return Err(e), + } + + + // Process non-comment part + let mut comment_found = false; + for &byte in &buf { + if byte == b'#' { + comment_found = true; + // Skip the rest of the comment line + reader.read_until(b'\n', &mut Vec::new())?; + // Reset digits found before comment on the same "line" + // only if we haven't added non-whitespace digits yet. + // Check if the last character ADDED (if any) was whitespace. + // If digits is empty OR the last added char was whitespace, clear. + // --- FIX START --- + if digits.last().map_or(true, |last_byte_ref| last_byte_ref.is_ascii_whitespace()) { + // --- FIX END --- + digits.clear(); + } + break; // Process next chunk read after comment + } else if byte.is_ascii_whitespace() { + if !digits.is_empty() { + // Found whitespace after digits, we have our number + let s = String::from_utf8(digits).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + return s.trim().parse::().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)); + } + // Skip leading/multiple whitespace by not adding it to `digits` + } else if byte.is_ascii_digit() { + digits.push(byte); + } else { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "Non-digit, non-whitespace, non-comment character found in numeric header field", + )); + } + } + + // If we broke loop due to '#', continue reading after comment + if comment_found { + continue; + } + + // If we reached EOF after reading the buffer + if buf.is_empty() { // EOF confirmed by read_until returning 0 earlier + if digits.is_empty() { // EOF before finding any digits + return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "EOF while reading number")); + } else { // Reached EOF after finding digits + let s = String::from_utf8(digits).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + return s.trim().parse::().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)); + } + } + // else: finished processing buffer without finding whitespace after digits, continue loop + } + + // Handle case where file ends immediately after digits without trailing whitespace/comment + if !digits.is_empty() { + let s = String::from_utf8(digits).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + s.trim().parse::().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + } else { + // This state should ideally be unreachable due to EOF checks above, but acts as a safeguard + Err(io::Error::new(io::ErrorKind::UnexpectedEof, "EOF or invalid state reading number")) + } +} + + +fn read_ppm(filename: &str) -> io::Result { + let file = File::open(filename)?; + let mut reader = BufReader::new(file); + + let mut magic = [0u8; 2]; + reader.read_exact(&mut magic)?; + if &magic != b"P6" { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "Not a P6 PPM file", + )); + } + + // Consume the first whitespace/comment after P6, needed before reading width. + // read_ascii_int handles subsequent whitespace/comments. + let mut header_byte = [0u8; 1]; + loop { + reader.read_exact(&mut header_byte)?; + if header_byte[0] == b'#' { + reader.read_until(b'\n', &mut Vec::new())?; // Skip comment line + } else if header_byte[0].is_ascii_whitespace() { + break; // Found the required whitespace separator + } else { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "Expected whitespace or comment after P6 magic number", + )); + } + } + + + let width = read_ascii_int(&mut reader)?; + let height = read_ascii_int(&mut reader)?; + let maxval = read_ascii_int(&mut reader)?; + + if width == 0 || height == 0 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "Invalid image dimensions (width or height is zero)", + )); + } + if maxval != 255 { + // Technically PGM/PPM allow other maxvals, but this code assumes 255. + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "Max color value must be 255 for this implementation", + )); + } + + // Read the single whitespace character separating header from data + let mut header_end = [0u8; 1]; + // Consume any remaining whitespace/comments after maxval before the final newline/space + loop { + reader.read_exact(&mut header_end)?; + if header_end[0] == b'#' { + reader.read_until(b'\n', &mut Vec::new())?; + } else if header_end[0].is_ascii_whitespace() { + // Check if it's the required single whitespace char + if header_end[0] == b'\n' || header_end[0] == b' ' || header_end[0] == b'\t' || header_end[0] == b'\r' { + break; // Found it + } // else keep reading whitespace if needed (though standard expects one) + } else { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "Expected single whitespace after maxval before pixel data", + )); + } + } + + + let mut image = Image::new(width, height); + let pixel_count = width * height; + let byte_count = pixel_count * 3; + + // Read pixel data directly into a Vec first + let mut byte_buffer = vec![0u8; byte_count]; + reader.read_exact(&mut byte_buffer)?; + + + // Convert bytes to Rgb structs - Optimized + // Safety: We know byte_buffer.len() == image.pixels.len() * 3 + // Using chunks_exact is efficient and safe. + let mut pixel_iter = image.pixels.iter_mut(); + for chunk in byte_buffer.chunks_exact(3) { + if let Some(pixel) = pixel_iter.next() { + pixel.r = chunk[0]; + pixel.g = chunk[1]; + pixel.b = chunk[2]; + } else { + // Should not happen if counts are correct + return Err(io::Error::new(io::ErrorKind::InvalidData, "Pixel data size mismatch (internal error)")); + } + } + + // Check for extra data after pixel data (optional, can indicate malformed file) + // let mut extra = [0u8; 1]; + // if reader.read(&mut extra)? > 0 { + // eprintln!("Warning: Extra data found after pixel data in PPM file."); + // } + + Ok(image) +} + +fn write_ppm(image: &Image, filename: &str) -> io::Result<()> { + let file = File::create(filename)?; + let mut writer = BufWriter::new(file); + + write!(writer, "P6\n{} {}\n255\n", image.width, image.height)?; + + // Write pixel data - Optimized + // Create a byte buffer directly from the pixel data + let byte_buffer: Vec = image.pixels + .iter() + .flat_map(|p| [p.r, p.g, p.b]) + .collect(); + + writer.write_all(&byte_buffer)?; + writer.flush()?; // Ensure all data is written + + Ok(()) +} + +// --- Median Filter Logic --- + +// Add pixels in a vertical column segment to the histogram +fn add_pixels( + im: &Image, + row: isize, // Use isize for calculations involving size subtraction + col: usize, + size: isize, + h: &mut ColorHisto, +) { + if col >= im.width { + return; + } + // Calculate row bounds carefully using isize before converting to usize + let start_row = (row - size).max(0) as usize; + // Ensure end_row doesn't wrap around if row+size is huge + let end_row_isize = (row + size).min(im.height as isize - 1); + if end_row_isize < start_row as isize { // Should not happen if size >= 0 + return; + } + let end_row = end_row_isize as usize; + + + for i in start_row..=end_row { + // We already checked col < im.width and i is within [0, im.height) + if let Some(pixel) = im.get_pixel(i, col) { // Use get_pixel for safety just in case + h.add_pixel(*pixel); + } + } +} + +// Delete pixels in a vertical column segment from the histogram +fn del_pixels( + im: &Image, + row: isize, + col: usize, // Column index must be valid if called + size: isize, + h: &mut ColorHisto, +) { + // Assume col is valid (checked by caller usually, like `if remove_col_idx >= 0`) + if col >= im.width { // Still good practice to check upper bound + return; + } + + let start_row = (row - size).max(0) as usize; + let end_row_isize = (row + size).min(im.height as isize - 1); + if end_row_isize < start_row as isize { + return; + } + let end_row = end_row_isize as usize; + + for i in start_row..=end_row { + if let Some(pixel) = im.get_pixel(i, col) { + h.del_pixel(*pixel); + } + } +} + +// Initialize histogram for the start of a row +fn init_histo(im: &Image, row: isize, size: isize, h: &mut ColorHisto) { + *h = ColorHisto::new(); // Reset histogram + + // Calculate the initial window columns (0 to size) + // Ensure end_col doesn't exceed width-1 + let end_col = (size as usize).min(im.width.saturating_sub(1)); + + for j in 0..=end_col { + add_pixels(im, row, j, size, h); + } +} + +// Find the median value in a single channel histogram array +fn median(x: &[i32; 256], n: i32) -> u8 { + if n <= 0 { + return 0; // Handle empty or invalid histogram state + } + let mut count = 0; + // Target count to find the median element + // For even n, this finds the lower median (e.g., for [1,2,3,4], n=4, n/2=2, stops at 2) + // For odd n, this finds the exact median (e.g., for [1,2,3], n=3, n/2=1, stops at 2) + let threshold = n / 2; + for i in 0..256 { + count += x[i]; + // Use > threshold because we want the first bin where cumulative count EXCEEDS n/2 + if count > threshold { + return i as u8; + } + } + // If n > 0, should have returned. If loop finishes, it implies n was 0 + // or data is skewed (e.g., all counts were 0, which shouldn't happen if n > 0). + // Return 255 as a fallback, though 0 might also be reasonable if n was 0. + 255 +} + +// Calculate the median color using the histogram +fn median_color(h: &ColorHisto) -> Rgb { + Rgb { + r: median(&h.r, h.n), + g: median(&h.g, h.n), + b: median(&h.b, h.n), + } +} + +// Apply median filter +fn median_filter(input: &Image, size: usize) -> Image { + let mut output = Image::new(input.width, input.height); + let mut h = ColorHisto::new(); + let size_isize = size as isize; // Use isize for calculations + + if input.width == 0 || input.height == 0 { + return output; // Return empty image if input is empty + } + + for row in 0..input.height { + let row_isize = row as isize; + // Reset histogram at the start of each row + h = ColorHisto::new(); + + for col in 0..input.width { + if col == 0 { + // Initialize histogram for the first pixel window of the row + init_histo(input, row_isize, size_isize, &mut h); + } else { + // Slide the window: remove leftmost column, add rightmost column + + // Column index to remove (can be negative if window is near left edge) + let remove_col_idx = col as isize - size_isize - 1; + // Column index to add (can be >= width if window is near right edge) + let add_col_idx = col as isize + size_isize; + + // del_pixels handles bounds check for remove_col_idx < 0 internally (no-op) + // We only need to check if it's a valid index >= 0 before calling + if remove_col_idx >= 0 { + del_pixels(input, row_isize, remove_col_idx as usize, size_isize, &mut h); + } + // add_pixels handles bounds check for add_col_idx >= width internally (no-op) + // No need for explicit check here, add_pixels takes usize and handles it. + add_pixels(input, row_isize, add_col_idx as usize, size_isize, &mut h); + } + + // Calculate median for the center pixel (current row, col) and write to output + // Ensure the histogram is not empty before calculating median + if h.n > 0 { + if let Some(out_pixel) = output.get_pixel_mut(row, col) { + *out_pixel = median_color(&h); + } + } else { + // This might happen if the window size is very large relative to image dimensions + // or near edges with empty columns added/removed. Output black or default pixel. + if let Some(out_pixel) = output.get_pixel_mut(row, col) { + *out_pixel = Rgb::default(); + } + // Can add a warning here if needed: eprintln!("Warning: Empty histogram at ({}, {})", row, col); + } + } + } + + output +} + +// --- Main Function --- + +fn main() -> io::Result<()> { + let args: Vec = env::args().collect(); + + if args.len() <= 3 { + eprintln!("Usage: {} ", args[0]); + process::exit(1); + } + + let size: usize = match args[1].parse() { + Ok(s) if s > 0 => s, // Median filter radius usually non-zero + Ok(_) => { // Allow size 0 (no filtering), though typically size >= 1 + eprintln!("Warning: Filter size is 0. Output will be same as input."); + 0 + } + Err(_) => { + eprintln!("Error: Filter size must be a non-negative integer."); + process::exit(1); + } + }; + + let input_filename = &args[2]; + let output_filename = &args[3]; + + println!( + "Reading input file: {} with filter size {}", + input_filename, size + ); + let input_image = read_ppm(input_filename).map_err(|e| { + eprintln!("Error reading input file '{}': {}", input_filename, e); + process::exit(1); // Exit on read error + })?; + + println!( + "Applying median filter (window radius {}, diameter {})...", + size, 2 * size + 1 + ); + let output_image = median_filter(&input_image, size); + + println!("Writing output file: {}", output_filename); + write_ppm(&output_image, output_filename).map_err(|e| { + eprintln!("Error writing output file '{}': {}", output_filename, e); + process::exit(1); // Exit on write error + })?; + + println!("Done."); + Ok(()) +} diff --git a/Task/Meissel-Mertens-constant/EasyLang/meissel-mertens-constant.easy b/Task/Meissel-Mertens-constant/EasyLang/meissel-mertens-constant.easy index 8fdd64cc93..54d3856e03 100644 --- a/Task/Meissel-Mertens-constant/EasyLang/meissel-mertens-constant.easy +++ b/Task/Meissel-Mertens-constant/EasyLang/meissel-mertens-constant.easy @@ -1,15 +1,8 @@ fastfunc isprim num . - if num mod 2 = 0 - if num = 2 - return 1 - . - return 0 - . + if num mod 2 = 0 and num <> 2 : return 0 i = 3 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 . return 1 @@ -23,5 +16,5 @@ for x = 2 to 1e6 m += log (1 - (1 / x)) + (1 / x) . . -numfmt 11 0 +numfmt 0 11 print "mm = " & euler + m diff --git a/Task/Meissel-Mertens-constant/REXX/meissel-mertens-constant.rexx b/Task/Meissel-Mertens-constant/REXX/meissel-mertens-constant.rexx index 55681c59ee..1c5d19a827 100644 --- a/Task/Meissel-Mertens-constant/REXX/meissel-mertens-constant.rexx +++ b/Task/Meissel-Mertens-constant/REXX/meissel-mertens-constant.rexx @@ -1,6 +1,9 @@ +-- 8 May 2025 include Settings -say version; say 'Meissel-Mertens constant'; say +say 'MEISSEL-MERTENS CONSTANT' +say version +say arg n if n = '' then n = 16 @@ -30,11 +33,11 @@ numeric digits Digits()-2 return y+0 UsingSieve: -procedure expose glob. prim. +procedure expose glob. prim. flag. numeric digits Digits()+2 n = Primes(1000000); y = 0 do i = 1 to n - q = 1/prim.prime.i; t = Ln(1-q)+q; y = y+t + q = 1/prim.i; t = Ln(1-q)+q; y = y+t end y = Euler()+y numeric digits Digits()-2 @@ -63,4 +66,7 @@ return 0.26149721284764278375542683860869585905156664826119920619206421392492451 include Constants include Functions +include Special include Numbers +include Sequences +include Abend diff --git a/Task/Merge-and-aggregate-datasets/EasyLang/merge-and-aggregate-datasets.easy b/Task/Merge-and-aggregate-datasets/EasyLang/merge-and-aggregate-datasets.easy index 51a02cfa7a..451dbc3f9b 100644 --- a/Task/Merge-and-aggregate-datasets/EasyLang/merge-and-aggregate-datasets.easy +++ b/Task/Merge-and-aggregate-datasets/EasyLang/merge-and-aggregate-datasets.easy @@ -5,12 +5,10 @@ repeat pat$[][] &= strsplit s$ "," pat$[$][] &= "" . -proc sort . d$[][] . - for i = len d$[][] - 1 downto 1 - for j = 1 to i - if strcmp d$[j][1] d$[j + 1][1] > 0 - swap d$[j][] d$[j + 1][] - . +proc sort &d$[][] . + for i = len d$[][] - 1 downto 1 : for j = 1 to i + if strcmp d$[j][1] d$[j + 1][1] > 0 + swap d$[j][] d$[j + 1][] . . . @@ -36,9 +34,7 @@ repeat . func$ f s$ n . s$ = " " & s$ - while len s$ < n - s$ &= " " - . + while len s$ < n : s$ &= " " return s$ . print "PATIENT_ID | LASTNAME | LAST_VISIT | SCORE_SUM | SCORE_AVG" diff --git a/Task/Merge-and-aggregate-datasets/FreeBASIC/merge-and-aggregate-datasets.basic b/Task/Merge-and-aggregate-datasets/FreeBASIC/merge-and-aggregate-datasets-1.basic similarity index 100% rename from Task/Merge-and-aggregate-datasets/FreeBASIC/merge-and-aggregate-datasets.basic rename to Task/Merge-and-aggregate-datasets/FreeBASIC/merge-and-aggregate-datasets-1.basic diff --git a/Task/Merge-and-aggregate-datasets/FreeBASIC/merge-and-aggregate-datasets-2.basic b/Task/Merge-and-aggregate-datasets/FreeBASIC/merge-and-aggregate-datasets-2.basic new file mode 100644 index 0000000000..6b0293f6d1 --- /dev/null +++ b/Task/Merge-and-aggregate-datasets/FreeBASIC/merge-and-aggregate-datasets-2.basic @@ -0,0 +1,248 @@ +#include once "sqlite3.bi" +#include once "string.bi" +#include once "crt.bi" + +' Callback para SQLite +Function callback Cdecl (Byval NotUsed As Any Ptr, Byval argc As Integer, _ + Byval argv As ZString Ptr Ptr, Byval colName As ZString Ptr Ptr) As Integer + + For i As Integer = 0 To argc - 1 + If argv[i] <> NULL Then + Print *colName[i] & ": " & *argv[i] & " "; + Else + Print *colName[i] & ": NULL "; + End If + Next + Print + + Return 0 +End Function + +Sub createCSVfiles() + Dim As Integer ff + + If Dir("patients.csv") = "" Then + ff = Freefile + Open "patients.csv" For Output As #ff + Print #ff, "PATIENT_ID,LASTNAME" + Print #ff, "1001,Hopper" + Print #ff, "4004,Wirth" + Print #ff, "3003,Kemeny" + Print #ff, "2002,Gosling" + Print #ff, "5005,Kurtz" + Close #ff + End If + + If Dir("visits.csv") = "" Then + ff = Freefile + Open "visits.csv" For Output As #ff + Print #ff, "PATIENT_ID,VISIT_DATE,SCORE" + Print #ff, "2002,2020-09-10,6.8" + Print #ff, "1001,2020-09-17,5.5" + Print #ff, "4004,2020-09-24,8.4" + Print #ff, "2002,2020-10-08," + Print #ff, "1001,,6.6" + Print #ff, "3003,2020-11-12," + Print #ff, "4004,2020-11-05,7.0" + Print #ff, "1001,2020-11-19,5.3" + Close #ff + End If +End Sub + +Sub createTableHeaders(db As sqlite3 Ptr) + Dim As ZString Ptr errMsg = NULL + + ' Create the patient and visit table + sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS patients (PATIENT_ID INT, LASTNAME TEXT);", Cast(Any Ptr, @callback), NULL, @errMsg) + If errMsg <> NULL Then + Print "Error creating patients table: " & *errMsg + sqlite3_free(errMsg) + End If + + sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS visits (PATIENT_ID INT, VISIT_DATE TEXT, SCORE NUMERIC(4,1));", Cast(Any Ptr, @callback), NULL, @errMsg) + If errMsg <> NULL Then + Print "Error creating visits table: " & *errMsg + sqlite3_free(errMsg) + End If +End Sub + +Sub fillTablesFromCSV(db As sqlite3 Ptr) + Dim As Integer ff, i + Dim As String lineaCSV, query + Dim As ZString Ptr errMsg = NULL + + ff = Freefile + Open "patients.csv" For Input As #ff + Line Input #ff, lineaCSV ' Saltar la cabecera + + While Not Eof(ff) + Line Input #ff, lineaCSV + Dim As String id = "", lastname = "" + + i = 1 + While i <= Len(lineaCSV) And Mid(lineaCSV, i, 1) <> "," + id += Mid(lineaCSV, i, 1) + i += 1 + Wend + i += 1 ' Skip the comma + + While i <= Len(lineaCSV) + lastname += Mid(lineaCSV, i, 1) + i += 1 + Wend + + query = "INSERT INTO patients VALUES (" & id & ", '" & lastname & "');" + + sqlite3_exec(db, query, NULL, NULL, @errMsg) + If errMsg <> NULL Then + Print "Error inserting patient: " & *errMsg + sqlite3_free(errMsg) + End If + Wend + Close #ff + + ff = Freefile + Open "visits.csv" For Input As #ff + Line Input #ff, lineaCSV ' Skip header + + While Not Eof(ff) + Line Input #ff, lineaCSV + Dim As String id = "", dateStr = "", score = "" + Dim As Integer fieldNum = 0 + + For i = 1 To Len(lineaCSV) + If Mid(lineaCSV, i, 1) = "," Then + fieldNum += 1 + Else + Select Case fieldNum + Case 0: id += Mid(lineaCSV, i, 1) + Case 1: dateStr += Mid(lineaCSV, i, 1) + Case 2: score += Mid(lineaCSV, i, 1) + End Select + End If + Next i + + query = "INSERT INTO visits VALUES (" & id & ", " + + If dateStr = "" Then + query &= "NULL, " + Else + query &= "'" & dateStr & "', " + End If + + If score = "" Then + query &= "NULL);" + Else + query &= score & ");" + End If + + sqlite3_exec(db, query, NULL, NULL, @errMsg) + If errMsg <> NULL Then + Print "Error inserting visit: " & *errMsg + sqlite3_free(errMsg) + End If + Wend + Close #ff +End Sub + +Function joinTablesAndGroup(db As sqlite3 Ptr) As String + Dim As sqlite3_stmt Ptr stmt + Dim As String result = "" + Dim As ZString Ptr errMsg = NULL + + Dim As String query = _ + "SELECT " & _ + " p.PATIENT_ID, " & _ + " p.LASTNAME, " & _ + " MAX(v.VISIT_DATE) AS LAST_VISIT, " & _ + " SUM(v.SCORE) AS SCORE_SUM, " & _ + " ROUND(AVG(v.SCORE), 1) AS SCORE_AVG " & _ + "FROM " & _ + " patients p " & _ + "LEFT JOIN " & _ + " visits v ON p.PATIENT_ID = v.PATIENT_ID " & _ + "GROUP BY " & _ + " p.PATIENT_ID, p.LASTNAME " & _ + "ORDER BY " & _ + " p.PATIENT_ID;" + + If sqlite3_prepare_v2(db, query, -1, @stmt, NULL) <> SQLITE_OK Then + Print "Error preparing statement: " & *sqlite3_errmsg(db) + Return "Error" + End If + + result = "| PATIENT_ID | LASTNAME | LAST_VISIT | SCORE_SUM | SCORE_AVG |" & Chr(10) + result &= "|------------|----------|------------|-----------|-----------|" & Chr(10) + + While sqlite3_step(stmt) = SQLITE_ROW + Dim As String row = "| " + + ' PATIENT_ID + If sqlite3_column_type(stmt, 0) <> SQLITE_NULL Then + row &= " " & Trim(Str(sqlite3_column_int(stmt, 0))) & " | " + Else + row &= Space(10) & "| " + End If + + ' LASTNAME + If sqlite3_column_type(stmt, 1) <> SQLITE_NULL Then + Dim As String lastname = *Cast(ZString Ptr, sqlite3_column_text(stmt, 1)) + row &= lastname & Space(9 - Len(lastname)) & "| " + Else + row &= " | " + End If + + ' LAST_VISIT + If sqlite3_column_type(stmt, 2) <> SQLITE_NULL Then + Dim As String visit_date = *Cast(ZString Ptr, sqlite3_column_text(stmt, 2)) + row &= visit_date & Space(11 - Len(visit_date)) & "| " + Else + row &= " None | " + End If + + ' SCORE_SUM + If sqlite3_column_type(stmt, 3) <> SQLITE_NULL Then + Dim As Double score_sum = sqlite3_column_double(stmt, 3) + row &= " " & Format(score_sum, "#00.#") & " | " + Else + row &= " None | " + End If + + ' SCORE_AVG + If sqlite3_column_type(stmt, 4) <> SQLITE_NULL Then + Dim As Double score_avg = sqlite3_column_double(stmt, 4) + row &= " " & Format(score_avg, "##.#") & " |" + Else + row &= " None |" + End If + + result &= row & Chr(10) + Wend + + sqlite3_finalize(stmt) + Return result +End Function + +' Main program +Dim As sqlite3 Ptr db +Dim As Integer rc + +createCSVfiles() + +rc = sqlite3_open(":memory:", @db) +If rc <> SQLITE_OK Then + Print "Error opening database: " & *sqlite3_errmsg(db) + sqlite3_close(db) + Sleep: End 1 +End If + +createTableHeaders(db) + +fillTablesFromCSV(db) + +Dim As String result = joinTablesAndGroup(db) +Print result + +sqlite3_close(db) + +Sleep diff --git a/Task/Merge-and-aggregate-datasets/Logo/merge-and-aggregate-datasets-1.logo b/Task/Merge-and-aggregate-datasets/Logo/merge-and-aggregate-datasets-1.logo new file mode 100644 index 0000000000..576dddf06b --- /dev/null +++ b/Task/Merge-and-aggregate-datasets/Logo/merge-and-aggregate-datasets-1.logo @@ -0,0 +1,87 @@ +to read.simple.csv :in + local [line list] + make "list [] + openread :in + setread :in + while [not eofp] [ + make "line subst.comma readword + make "line parse map [ifelse equalp ? ", ["\ ] [?]] :line + make "list fput :line :list + ] + close :in + setread [] + output reverse :list +end + +to subst.comma :string + local [out k] + make "k 1 + make "out " + foreach :string [ + ifelse equalp ? ", ~ + [ifelse equalp :k 1 ~ + [make "out word :out ? make "k sum :k 1] ~ + [make "out word :out "|missing,| make "k 1]] ~ + [make "out word :out ? make "k 1] + ] + output ifelse equalp last :out ", [word :out "missing] [:out] +end + +to aggregate :patients :visits + if emptyp :patients [output []] + output fput aggregate.helper first :patients :visits aggregate bf :patients :visits +end + + +to aggregate.helper :patient :visits [s 0] [c 0] [m "] +;m for max date. s for sum of scores. c number of scores + if emptyp :visits [ + output (se :patient ifelse equalp :m " ["missing] [:m] ~ + ifelse equalp :s 0 ["missing] [:s] ~ + ifelse equalp :s 0 ["missing] [quotient :s :c]) + ] + output ifelse equalp first :patient first first :visits [ + (aggregate.helper :patient bf :visits ~ + ifelse equalp last first :visits "missing [:s][sum :s last first :visits] ~ + ifelse equalp last first :visits "missing [:c][sum :c 1] ~ + ifelse equalp first bf first :visits "missing [:m] ~ + [ifelse beforep :m first bf first :visits [first bf first :visits] [:m]])] ~ + [(aggregate.helper :patient bf :visits :s :c :m)] +end + +to mergesort :list + localmake "half split (count :list) / 2 [] :list + if empty? first :half [output :list] + output merge mergesort first :half mergesort last :half +end + +to split :size :front :list + if :size < 1 [output list :front :list] + output split :size-1 (lput first :list :front) (butfirst :list) +end + +to merge :small :large + if empty? :small [output :large] + ifelse lessequal? first first :small first first :large ~ + [output fput first :small merge butfirst :small :large] ~ + [output fput first :large merge butfirst :large :small] +end + +to csv.write :list :out + openwrite :out + setwrite :out + csv.write.lines :list + close :out + setwrite [] +end + +to csv.write.lines :list + if emptyp :list [stop] + print csv.write.fields first :list + csv.write.lines bf :list +end + +to csv.write.fields :line + if equalp count :line 1 [output first :line] + output (word first :line ", csv.write.fields bf :line) +end diff --git a/Task/Merge-and-aggregate-datasets/Logo/merge-and-aggregate-datasets-2.logo b/Task/Merge-and-aggregate-datasets/Logo/merge-and-aggregate-datasets-2.logo new file mode 100644 index 0000000000..e7cfd319ec --- /dev/null +++ b/Task/Merge-and-aggregate-datasets/Logo/merge-and-aggregate-datasets-2.logo @@ -0,0 +1,5 @@ +make "patients bf read.simple.csv "patients.csv +make "visits bf read.simple.csv "visits.csv +make "out mergesort aggregate :patients :visits +make "out fput [patient_id lastname max_date score_sum score_mean] :out +csv.write :out "out.csv diff --git a/Task/Mertens-function/EasyLang/mertens-function.easy b/Task/Mertens-function/EasyLang/mertens-function.easy index bacf516727..5ba339e368 100644 --- a/Task/Mertens-function/EasyLang/mertens-function.easy +++ b/Task/Mertens-function/EasyLang/mertens-function.easy @@ -8,19 +8,15 @@ for n = 2 to 1000 . print "First 99 Mertens numbers:" write " " -numfmt 0 2 +numfmt 2 0 for n = 1 to 99 write mertens[n] & " " - if n mod 10 = 9 - print "" - . + if n mod 10 = 9 : print "" . for n = 1 to 1000 if mertens[n] = 0 zeros += 1 - if mertens[n - 1] <> 0 - crosses += 1 - . + if mertens[n - 1] <> 0 : crosses += 1 . . print "" diff --git a/Task/Mertens-function/REXX/mertens-function.rexx b/Task/Mertens-function/REXX/mertens-function.rexx index ee48fca3f7..86a3268b56 100644 --- a/Task/Mertens-function/REXX/mertens-function.rexx +++ b/Task/Mertens-function/REXX/mertens-function.rexx @@ -1,61 +1,118 @@ -/*REXX pgm computes & shows a value grid of the Mertens function for a range of integers*/ -parse arg LO HI grp eqZ xZ . /*obtain optional arguments from the CL*/ -if LO=='' | LO=="," then LO= 0 /*Not specified? Then use the default.*/ -if HI=='' | HI=="," then HI= 199 /* " " " " " " */ -if grp=='' | grp=="," then grp= 20 /* " " " " " " */ -if eqZ=='' | eqZ=="," then eqZ= 1000 /* " " " " " " */ -if xZ=='' | xZ=="," then xZ= 1000 /* " " " " " " */ -call genP /*generate primes up to max √ HIHI */ - call Franz LO, HI -if eqZ>0 then call Franz 1, -eqZ -if xZ>0 then call Franz -1, xZ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Franz: parse arg a 1 oa,b 1 ob; @Mertens= ' The Mertens sequence from ' -a= abs(a); b= abs(b); grid= oa>=0 & ob>=0 /*semaphore used to show a grid title. */ -if grid then say center(@Mertens LO " ──► " HI" ", max(50, grp*3), '═') /*show title*/ - else say -zeros= 0 /*# of 0's found for Mertens function.*/ -Xzero= 0 /*number of times that zero was crossed*/ -$=; prev= /*$ holds output grid of GRP numbers. */ - do j=a to b; _= Mertens(j) /*process some numbers from LO ──► HI.*/ - if _==0 then zeros= zeros + 1 /*Is Zero? Then bump the zeros counter*/ - if _==0 then if prev\==0 then Xzero= Xzero+1 /*prev ¬=0? " " " Xzero " */ - prev= _ - if grid then $= $ right(_, 2) /*build grid if A & B are non─negative.*/ - if words($)==grp then do; say substr($, 2); $= /*show grid if fully populated, */ - end /* and nullify it for more #s. */ - end /*j*/ /*for small grids, using wordCnt is OK.*/ +-- 25 Apr 2025 +include Settings +arg xx +if xx = '' then + xx = 99 -if $\=='' then say substr($, 2) /*handle any residual numbers not shown*/ -if oa<0 then say @Mertens a " to " b ' has crossed zero ' Xzero " times." -if ob<0 then say @Mertens a " to " b ' has ' zeros " zeros." +say 'MERTENS FUNCTION' +say version +say +call Tasks1 xx +call Tasks2 xx +call Tasks3 xx +exit + +Tasks1: +procedure expose squa. +arg xx +call Time('r') +say 'Tasks using Sieve...' +call Squarefrees 2*xx +if xx < 100 then + say 'M1 thru M'xx +e = 0; o = 0; a = 0; b = 0 +n = 1; s = squa.1; p = s +do i = 1 to xx + if s <= i then do + if s = 1 then + f = 0 + else + f = Factors(s) + e = e+Even(f); o = o+Odd(f); m = e-o + n = n+1; s = squa.n + end + if xx < 100 & i < 100 then do + call Charout ,Right(m,3) + if i//10 = 0 then + say + end + if m = 0 then do + a = a+1 + if p <> 0 then + b = b + 1 + end + p = m +end +say +say 'M1 thru M'xx 'equals zero' a 'times' +say 'M1 thru M'xx 'crosses zero' b 'times' +say Format(Time('e'),,3) 'seconds'; say return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Mertens: procedure expose @. !!. M.; parse arg n; if M.n\==. then return M.n - if n<1 then return '∙'; m= 0 /*handle special cases of non─positive#*/ - do k=1 for n; m= m + mobius(k) /*sum the MU's up to N. */ - end /*k*/ /* [↑] mobius function uses memoization*/ - M.n= m; return m /*return the sum of all the MU's. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -mobius: procedure expose @. !!.; parse arg x 1 ox /*get integer to be tested for mu */ - if !!.x\==. then return !!.x /*X computed before? Return that value*/ - if x<1 then return '∙'; mu= 0 /*handle special case of non-positive #*/ - do k=1; p= @.k; if p>x then leave /* (P) > X? Then we're done.*/ - if p*p>x then do; mu= mu+1; leave; end /* (P**2) > X? Bump # and leave*/ - if x//p==0 then do; mu= mu+1 /*X divisible by P? Bump mu number.*/ - x= x % p /* Divide by prime. */ - if x//p==0 then return 0 /*X÷by P? Then return zero*/ - end - end /*k*/ /*MU (below) is almost always small, <9*/ - !!.ox= -1 ** mu; return !!.ox /*raise -1 to the mu power, memoize it.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13 /*initialize some low primes; # primes.*/ - !!.=.; M.=!!.; #= 6; sq.#= @.6**2 /* " 2 arrays for memoization. */ - do j=@.#+4 by 2 to max(HI, eqZ, xZ); parse var j '' -1 _ /*odd Ps from now on*/ - if _==5 then iterate; if j//3==0 then iterate; if j//7==0 then iterate /*÷ 5 3 7*/ - do k=7 while sq.k<=j /*divide by some generated odd primes. */ - if j//@.k==0 then iterate j /*Is J divisible by P? Then not prime*/ - end /*k*/ /* [↓] a prime (J) has been found. */ - #= #+1; @.#=j; sq.j= j*j /*bump P count; P──►@.; compute J**2*/ - end /*j*/; return /*calculate the squares of some primes.*/ + +Tasks2: +procedure expose squa. +arg xx +call Time('r') +say 'Tasks using Moebius function...' +if xx < 100 then + say 'M1 thru M'xx +e = 0; o = 0; a = 0; b = 0 +s = 0 +do i = 1 to xx + s = s+Moebius(i) + if xx < 100 & i < 100 then do + call Charout ,Right(s,3) + if i//10 = 0 then + say + end + if s = 0 then do + a = a+1 + if p <> 0 then + b = b + 1 + end + p = s +end +say +say 'M1 thru M'xx 'equals zero' a 'times' +say 'M1 thru M'xx 'crosses zero' b 'times' +say Format(Time('e'),,3) 'seconds'; say +return + +Tasks3: +procedure expose squa. +arg xx +call Time('r') +say 'Tasks using Squarefree function...' +if xx < 100 then + say 'M1 thru M'xx +e = 0; o = 0; a = 0; b = 0 +do s = 1 to xx + if Squarefree(s) then do + if s = 1 then + f = 0 + else + f = Factors(s) + e = e+Even(f); o = o+Odd(f); m = e-o + end + if xx < 100 & s < 100 then do + call Charout ,Right(m,3) + if s//10 = 0 then + say + end + if m = 0 then do + a = a+1 + if p <> 0 then + b = b + 1 + end + p = m +end +say +say 'M1 thru M'xx 'equals zero' a 'times' +say 'M1 thru M'xx 'crosses zero' b 'times' +say Format(Time('e'),,3) 'seconds'; say +return + +include Numbers +include Sequences +include Functions +include Abend diff --git a/Task/Miller-Rabin-primality-test/REXX/miller-rabin-primality-test.rexx b/Task/Miller-Rabin-primality-test/REXX/miller-rabin-primality-test.rexx index 30799c4f3d..42cfe64c8b 100644 --- a/Task/Miller-Rabin-primality-test/REXX/miller-rabin-primality-test.rexx +++ b/Task/Miller-Rabin-primality-test/REXX/miller-rabin-primality-test.rexx @@ -1,6 +1,8 @@ include Settings -say version; say 'Miller-Rabin primality test'; say +say 'MILLER-RABIN PRIMALITY TEST - 4 Mar 2025' +say version +say numeric digits 1000 say '25 numbers of the form 2^n-1, mostly Mersenne primes' say 'Up to about 25 digits deterministic, above probabilistic' diff --git a/Task/Mind-boggling-card-trick/EasyLang/mind-boggling-card-trick.easy b/Task/Mind-boggling-card-trick/EasyLang/mind-boggling-card-trick.easy index 9189088f07..1bfe4ab7ba 100644 --- a/Task/Mind-boggling-card-trick/EasyLang/mind-boggling-card-trick.easy +++ b/Task/Mind-boggling-card-trick/EasyLang/mind-boggling-card-trick.easy @@ -1,13 +1,11 @@ -proc shuffle . a[] . +proc shuffle &a[] . for i = len a[] downto 2 r = random i swap a[r] a[i] . . func$ a2str a[] . - for v in a[] - r$ &= strchar v & " " - . + for v in a[] : r$ &= strchar v & " " return r$ . R = strcode "R" @@ -30,12 +28,8 @@ print "After dealing the cards the state of the stacks is:" print " Red : " & a2str red[] print " Black : " & a2str black[] print " Discard: " & a2str discard[] -for i to len red[] - rp[] &= i -. -for i to len black[] - bp[] &= i -. +for i to len red[] : rp[] &= i +for i to len black[] : bp[] &= i shuffle rp[] shuffle bp[] n = random lower len red[] len black[] @@ -52,15 +46,9 @@ print "After swapping " & n & " cards the state of the stacks is:" print " Red : " & a2str red[] print " Black : " & a2str black[] # -for c in red[] - red += if c = R -. -for c in black[] - black += if c = B -. +for c in red[] : red += if c = R +for c in black[] : black += if c = B print "" print "The number of red cards in the red stack = " & red print "The number of black cards in the black stack = " & black -if red = black - print "So the asssertion is correct!" -. +if red = black : print "So the asssertion is correct!" diff --git a/Task/Minesweeper-game/EasyLang/minesweeper-game.easy b/Task/Minesweeper-game/EasyLang/minesweeper-game.easy index 96d2a19eb8..933c63c42a 100644 --- a/Task/Minesweeper-game/EasyLang/minesweeper-game.easy +++ b/Task/Minesweeper-game/EasyLang/minesweeper-game.easy @@ -15,46 +15,39 @@ func getind r c . . return ind . -proc draw_cell ind h . . +proc draw_cell ind h . ind -= 1 r = ind div 8 c = ind mod 8 x = c * 12 + 2.5 y = r * 12 + 2.5 - move x y - rect 11 11 + grect x y 11 11 if h > 0 # count - move x + 3 y + 3 - color 000 - text h + gcolor 000 + gtext x + 3 y + 3 h elif h = -3 # flag x += 4 - color 000 - linewidth 0.8 - move x y + 3 - line x y + 8 - color 600 - linewidth 2 - move x + 0.5 y + 7 - line x + 2 y + 7 + gcolor 000 + glinewidth 0.8 + gline x y + 3 x y + 8 + gcolor 600 + glinewidth 2 + gline x + 0.5 y + 7 x + 2 y + 7 elif h <> 0 # mine - color 333 - if h = -2 - color 800 - . - move x + 5 y + 5 - circle 3 - line x + 8 y + 9 + gcolor 333 + if h = -2 : gcolor 800 + gcircle x + 5 y + 5 3 + gline x + 5 y + 5 x + 8 y + 9 . . -proc open ind . . +proc open ind . if ind <> -1 and cell[ind] = 0 cell[ind] = 2 flag[ind] = 0 - color 686 + gcolor 686 draw_cell ind cnt[ind] if cnt[ind] = 0 ind -= 1 @@ -70,31 +63,25 @@ proc open ind . . . . . -proc show_mines m . . +proc show_mines m . for ind to 56 if cell[ind] = 1 - color 686 - if m = -1 - color 353 - . + gcolor 686 + if m = -1 : gcolor 353 draw_cell ind m . . . -proc outp col s$ . . - move 2.5 87 - color col - rect 59 11 - color 000 - move 5 90 - text s$ +proc outp col s$ . + gcolor col + grect 2.5 87 59 11 + gcolor 000 + gtext 5 90 s$ . -proc upd_info . . +proc upd_info . for i to 56 nm += flag[i] - if cell[i] < 2 - nc += 1 - . + if cell[i] < 2 : nc += 1 . if nc = 8 outp 484 "Well done" @@ -104,11 +91,11 @@ proc upd_info . . outp 464 8 - nm & " mines left" . . -proc test ind . . +proc test ind . if cell[ind] < 2 and flag[ind] = 0 if cell[ind] = 1 show_mines -1 - color 686 + gcolor 686 draw_cell ind -2 outp 844 "B O O M !" state = 1 @@ -119,9 +106,9 @@ proc test ind . . . . background 676 -proc start . . - clear - color 353 +proc start . + gclear + gcolor 353 for ind to 56 cnt[ind] = 0 cell[ind] = 0 @@ -148,21 +135,18 @@ proc start . . . initvars outp 464 "" - textsize 4 - move 5 93 - text "Minesweeper - 8 mines" - move 5 88.2 - text "Long-press for flagging" - textsize 6 + gtextsize 4 + gtext 5 93 "Minesweeper - 8 mines" + gtext 5 88.2 "Long-press for flagging" + gtextsize 6 timer 0 . on mouse_down if state = 0 if mouse_y > 86 and mouse_x > 60 no_time = 1 - move 64.5 87 - color 464 - rect 33 11 + gcolor 464 + grect 64.5 87 33 11 . indx = getind ((mouse_y - 2) div 12) ((mouse_x - 2) div 12) ticks0 = ticks @@ -171,9 +155,7 @@ on mouse_down . . on mouse_up - if state = 0 and indx <> -1 - test indx - . + if state = 0 and indx <> -1 : test indx indx = -1 . on timer @@ -190,7 +172,7 @@ on timer else if indx > 0 and ticks = ticks0 + 2 if cell[indx] < 2 - color 353 + gcolor 353 flag[indx] = 1 - flag[indx] opt = 0 if flag[indx] = 1 @@ -202,15 +184,13 @@ on timer indx = -1 . if no_time = 0 and ticks mod 10 = 0 - move 64.5 87 - color 464 + gcolor 464 if ticks >= 2500 - color 844 + gcolor 844 . - rect 33 11 - color 000 - move 66 90 - text "Time:" & 300 - ticks / 10 + grect 64.5 87 33 11 + gcolor 000 + gtext 66 90 "Time:" & 300 - ticks / 10 . ticks += 1 timer 0.1 diff --git a/Task/Modified-random-distribution/EasyLang/modified-random-distribution.easy b/Task/Modified-random-distribution/EasyLang/modified-random-distribution.easy index 1e16044bef..a1142f0cc2 100644 --- a/Task/Modified-random-distribution/EasyLang/modified-random-distribution.easy +++ b/Task/Modified-random-distribution/EasyLang/modified-random-distribution.easy @@ -26,7 +26,7 @@ for i to n bn = floor (rn / binsz) bins[bn] += 1 . -numfmt 0 4 +numfmt 4 0 for i range0 nbins print bins[i] & " " & rep "*" (bins[i] / histsz) . diff --git a/Task/Monads-Maybe-monad/J/monads-maybe-monad-1.j b/Task/Monads-Maybe-monad/J/monads-maybe-monad-1.j index 6c5b86d50c..4b0d153718 100644 --- a/Task/Monads-Maybe-monad/J/monads-maybe-monad-1.j +++ b/Task/Monads-Maybe-monad/J/monads-maybe-monad-1.j @@ -1,3 +1,3 @@ -'J N'=. s:'Just';'Nothing' +'J N'=. s:' Just Nothing' unit =. J,&<] bind =. {{u@(1{::])^:(N-.@-:])}} diff --git a/Task/Monte-Carlo-methods/EasyLang/monte-carlo-methods.easy b/Task/Monte-Carlo-methods/EasyLang/monte-carlo-methods.easy index da447ba3db..9fac9bcd64 100644 --- a/Task/Monte-Carlo-methods/EasyLang/monte-carlo-methods.easy +++ b/Task/Monte-Carlo-methods/EasyLang/monte-carlo-methods.easy @@ -2,13 +2,11 @@ func mc n . for i = 1 to n x = randomf y = randomf - if x * x + y * y < 1 - hit += 1 - . + if x * x + y * y < 1 : hit += 1 . return 4 * hit / n . -numfmt 4 0 +numfmt 0 4 print mc 10000 print mc 100000 print mc 1000000 diff --git a/Task/Morse-code/EasyLang/morse-code.easy b/Task/Morse-code/EasyLang/morse-code.easy index bbbc87fac2..bf8b794642 100644 --- a/Task/Morse-code/EasyLang/morse-code.easy +++ b/Task/Morse-code/EasyLang/morse-code.easy @@ -3,7 +3,7 @@ txt$ = "sos sos" chars$ = "abcdefghijklmnopqrstuvwxyz " code$[] = [ ".-" "-..." "-.-." "-.." "." "..-." "--." "...." ".." ".---" "-.-" ".-.." "--" "-." "---" ".--." "--.-" ".-." "..." "-" "..-" "...-" ".--" "-..-" "-.--" "--.." " " ] # -proc morse ch$ . . +proc morse ch$ . ind = strpos chars$ ch$ if ind > 0 write ch$ & " " diff --git a/Task/Morse-code/Java/morse-code.java b/Task/Morse-code/Java/morse-code-1.java similarity index 100% rename from Task/Morse-code/Java/morse-code.java rename to Task/Morse-code/Java/morse-code-1.java diff --git a/Task/Morse-code/Java/morse-code-2.java b/Task/Morse-code/Java/morse-code-2.java new file mode 100644 index 0000000000..32c825d049 --- /dev/null +++ b/Task/Morse-code/Java/morse-code-2.java @@ -0,0 +1,99 @@ +import java.util.Map; +import java.util.stream.IntStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; + +public final class MorseCode { + + public static void main(String[] args) { + Map morseCode = Map.ofEntries( + // International Morse Code, ITU standard + Map.entry("A", ".-"), Map.entry("B", "-..."), Map.entry("C", "-.-."), Map.entry("D", "-.."), + Map.entry("E", "."), Map.entry("F", "..-."), Map.entry("G", "--."), Map.entry("H", "...."), + Map.entry("I", ".."), Map.entry("J", ".---"), Map.entry("K", "-.-"), Map.entry("L", ".-.."), + Map.entry("M", "--"), Map.entry("N", "-."), Map.entry("O", "---"), Map.entry("P", ".--."), + Map.entry("Q", "--.-"), Map.entry("R", ".-."), Map.entry("S", "..."), Map.entry("T", "-"), + Map.entry("U", "..-"), Map.entry("V", "...-"), Map.entry("W", ".--"), Map.entry("X", "-..-"), + Map.entry("Y", "-.--"), Map.entry("Z", "--.."), + + Map.entry("1", ".----"), Map.entry("2", "..---"), Map.entry("3", "...--"), Map.entry("4", "....-"), + Map.entry("5", "....."), Map.entry("6", "-...."), Map.entry("7", "--..."), Map.entry("8", "---.."), + Map.entry("9", "----."), Map.entry("0", "-----"), + + // Generally accepted additions + Map.entry("'", ".----."), Map.entry(":", "---..."), Map.entry(",", "--..--"), Map.entry("-", "-....-"), + Map.entry("(", "-.--.-"), Map.entry(".", ".-.-.-"), Map.entry("?", "..--.."), Map.entry(";", "-.-.-."), + Map.entry("/", "-..-."), Map.entry(")", "---.."), Map.entry("=", "-...-"), Map.entry("@", ".--.-."), + Map.entry("\"", ".-..-."), Map.entry("+", ".-.-.") + ); + + prepareSourceDataLine(); + + final int frequency = 1280; // Frequency of the sound tone in Hertz + final int time = 250; // Time unit in milliseconds + + // Correct pacing of the sound transmission is essential for practical use + final int dot = 1; // Time units taken for one dot + final int dash = 3; // Time units taken for one dash + final int interval = 1; // Time units interval between dots and dashes + final int letterInterval = 1; // Time units interval between letters of a word + final int wordInterval = 7; // Time units interval between words + + String message = "Hello World"; + + for ( String letter : message.toUpperCase().split("") ) { + switch ( letter ) { + case " " -> tone(0, time * wordInterval, 0); + default -> { + String code = morseCode.get(letter); + for ( String dotDash : code.split("") ) { + switch ( dotDash ) { + case "." -> { tone(frequency, time * dot, 1); tone(0, time * interval, 0); } + case "-" -> { tone(frequency, time * dash, 1); tone(0, time * interval, 0); } + } + } + } + } + tone(0, time * letterInterval, 0); + } + } + + private static void tone(double frequency, int duration, int volume) { + sourceDataLine.start(); + + IntStream.range(0, 8 * duration).forEach( i -> { + final double angle = i / ( SAMPLE_RATE / frequency ) * 2 * Math.PI; + byte[] buffer = new byte[] { (byte) ( Math.sin(angle) * 127 * volume ) }; + sourceDataLine.write(buffer, BYTE_OFFSET, buffer.length); + } ); + + sourceDataLine.drain(); + sourceDataLine.stop(); + } + + private static void prepareSourceDataLine() { + final int sampleSizeInBits = 8; + final int numberChannels = 1; + final boolean signedData = true; + final boolean isBigEndian = false; + + AudioFormat audioFormat = new AudioFormat( + SAMPLE_RATE, sampleSizeInBits, numberChannels, signedData, isBigEndian); + + try { + sourceDataLine = AudioSystem.getSourceDataLine(audioFormat); + sourceDataLine.open(audioFormat); + } catch (LineUnavailableException lue) { + lue.printStackTrace(); + } + } + + private static SourceDataLine sourceDataLine; + + private static float SAMPLE_RATE = 8_000.0F; + private static final int BYTE_OFFSET = 0; + +} diff --git a/Task/Motzkin-numbers/REXX/motzkin-numbers.rexx b/Task/Motzkin-numbers/REXX/motzkin-numbers.rexx index 742b20cb56..d601b7d240 100644 --- a/Task/Motzkin-numbers/REXX/motzkin-numbers.rexx +++ b/Task/Motzkin-numbers/REXX/motzkin-numbers.rexx @@ -1,43 +1,32 @@ -/*REXX program to display the first N Motzkin numbers, and if that number is prime. */ -numeric digits 92 /*max number of decimal digits for task*/ -parse arg n . /*obtain optional argument from the CL.*/ -if n=='' | n=="," then n= 42 /*Not specified? Then use the default.*/ -w= length(n) + 1; wm= digits()%4 /*define maximum widths for two columns*/ -say center('n', w ) center("Motzkin[n]", wm) center(' primality', 11) -say center('' , w, "─") center('' , wm, "─") center('', 11, "─") -@.= 1 /*define default vale for the @. array.*/ - do m=0 for n /*step through indices for Motzkin #'s.*/ - if m>1 then @.m= (@(m-1)*(m+m+1) + @(m-2)*(m*3-3))%(m+2) /*calculate a Motzkin #*/ - call show /*display a Motzkin number ──► terminal*/ - end /*m*/ +-- 22 Mar 2025 +include Settings +numeric digits 30 -say center('' , w, "─") center('' , wm, "─") center('', 11, "─") -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -@: parse arg i; return @.i /*return function expression based on I*/ -commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? -prime: if isPrime(@.m) then return " prime"; return '' -show: y= commas(@.m); say right(m, w) right(y, max(wm, length(y))) prime(); return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure expose p?. p#. p_.; parse arg x /*persistent P·· REXX variables.*/ - if symbol('P?.#')\=='VAR' then /*1st time here? Then define primes. */ - do /*L is a list of some low primes < 100.*/ - L= 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 - p?.=0 /* [↓] define P_index, P, P squared.*/ - do i=1 for words(L); _= word(L,i); p?._= 1; p#.i= _; p_.i= _*_ - end /*i*/; p?.0= x2d(3632c8eb5af3b) /*bypass big ÷*/ - p?.n= _ + 4 /*define next prime after last prime. */ - p?.#= i - 1 /*define the number of primes found. */ - end /* p?. p#. p_ must be unique. */ - if xhigh multiple Ps*/ - do k=p?.n by 6 while k*k<=x; if x//k ==0 then return 0 - if x//(k+2)==0 then return 0 - end /*k*/; return 1 /*Passed all divisions? It's a prime.*/ +say 'MOTZKIN NUMBERS' +say version +say +call Motzkins 1e20 +call Range 0 41 +say Time('e')/1 'seconds' +exit + +Range: +procedure expose motz. glob. +arg xx yy +if yy = '' then + yy = xx +say 'The Motzkin numbers from no' xx 'up to' yy 'are' +do i = xx to yy + m = motz.i + if prime(m) then + p = 'is prime' + else + p = '' + say 'M['right(i,2)']' right(m,18) p +end +return + +include Sequences +include Numbers +include Functions +include Abend diff --git a/Task/Mouse-position/EasyLang/mouse-position.easy b/Task/Mouse-position/EasyLang/mouse-position.easy index 42fc50d7a9..207262adb6 100644 --- a/Task/Mouse-position/EasyLang/mouse-position.easy +++ b/Task/Mouse-position/EasyLang/mouse-position.easy @@ -1,6 +1,5 @@ -move 10 80 on mouse_move - clear + gclear drawgrid - text mouse_x & " " & mouse_y + gtext 12 82 mouse_x & " " & mouse_y . diff --git a/Task/Mouse-position/Uxntal/mouse-position.uxnatl b/Task/Mouse-position/Uxntal/mouse-position.uxnatl index 5e484335dd..a925b61005 100644 --- a/Task/Mouse-position/Uxntal/mouse-position.uxnatl +++ b/Task/Mouse-position/Uxntal/mouse-position.uxnatl @@ -1,27 +1,24 @@ -|00 @System &vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1 -|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 -|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 -|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2 +% { [ LIT2 20 -Console/write ] DEO } +% { [ LIT2 0a -Console/write ] DEO } + +|10 @Console/vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 +|90 @Mouse/vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2 |0100 ;on-mouse .Mouse/vector DEO2 -BRK + BRK @on-mouse - .Mouse/x DEI2 print-hex2 - #20 .Console/write DEO - .Mouse/y DEI2 print-hex2 - #0a .Console/write DEO -BRK + .Mouse/x DEI2 + + .Mouse/y DEI2 + + BRK -@print-hex - DUP #04 SFT print-digit #0f AND print-digit -JMP2r - -@print-hex2 - SWP print-hex print-hex -JMP2r - -@print-digit - DUP #09 GTH #27 MUL ADD #30 ADD .Console/write DEO -JMP2r +@ ( short* -: ) + SWP /b + &b ( byte -: ) + DUP #04 SFT /c + &c ( byte -: ) + #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO + JMP2r diff --git a/Task/Move-to-front-algorithm/EasyLang/move-to-front-algorithm.easy b/Task/Move-to-front-algorithm/EasyLang/move-to-front-algorithm.easy index 9ec20dfb56..ee166d3ff8 100644 --- a/Task/Move-to-front-algorithm/EasyLang/move-to-front-algorithm.easy +++ b/Task/Move-to-front-algorithm/EasyLang/move-to-front-algorithm.easy @@ -1,7 +1,7 @@ subr init symt$[] = strchars "abcdefghijklmnopqrstuvwxyz" . -proc rot k . . +proc rot k . c$ = symt$[k] for j = k downto 2 symt$[j] = symt$[j - 1] diff --git a/Task/Move-to-front-algorithm/Zig/move-to-front-algorithm.zig b/Task/Move-to-front-algorithm/Zig/move-to-front-algorithm.zig new file mode 100644 index 0000000000..8c42575a8a --- /dev/null +++ b/Task/Move-to-front-algorithm/Zig/move-to-front-algorithm.zig @@ -0,0 +1,78 @@ +const std = @import("std"); + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer _ = gpa.deinit(); + + const examples = [_][]const u8{ "broood", "bananaaa", "hiphophiphop" }; + + for (examples) |example| { + const encoded = try encode(allocator, example); + defer allocator.free(encoded); + + const decoded = try decode(allocator, encoded); + defer allocator.free(decoded); + + std.debug.print("{s} encodes to {any} decodes to {s}\n", .{ example, encoded, decoded }); + } +} + +fn getSymbols(allocator: std.mem.Allocator) ![]u8 { + var symbols = std.ArrayList(u8).init(allocator); + errdefer symbols.deinit(); + + var c: u8 = 'a'; + while (c <= 'z') : (c += 1) { + try symbols.append(c); + } + + return symbols.toOwnedSlice(); +} + +fn encode(allocator: std.mem.Allocator, input: []const u8) ![]usize { + var output = std.ArrayList(usize).init(allocator); + errdefer output.deinit(); + + var symbols = try getSymbols(allocator); + defer allocator.free(symbols); + + for (input) |byte| { + // Find position of the byte in symbols + var position: usize = 0; + for (symbols, 0..) |symbol, i| { + if (symbol == byte) { + position = i; + break; + } + } + + // Remove the byte at the position + const char = symbols[position]; + std.mem.copyForwards(u8, symbols[1..position + 1], symbols[0..position]); + symbols[0] = char; + + try output.append(position); + } + + return output.toOwnedSlice(); +} + +fn decode(allocator: std.mem.Allocator, input: []const usize) ![]u8 { + var output = std.ArrayList(u8).init(allocator); + errdefer output.deinit(); + + var symbols = try getSymbols(allocator); + defer allocator.free(symbols); + + for (input) |position| { + try output.append(symbols[position]); + + // Remove the byte at the position + const char = symbols[position]; + std.mem.copyForwards(u8, symbols[1..position + 1], symbols[0..position]); + symbols[0] = char; + } + + return output.toOwnedSlice(); +} diff --git a/Task/Multi-base-primes/REXX/multi-base-primes.rexx b/Task/Multi-base-primes/REXX/multi-base-primes.rexx index 1e787f514f..cc1c8d4378 100644 --- a/Task/Multi-base-primes/REXX/multi-base-primes.rexx +++ b/Task/Multi-base-primes/REXX/multi-base-primes.rexx @@ -1,44 +1,66 @@ -/*REXX pgm finds primes whose values in other bases (2──►36) have the most diff. bases. */ -parse arg widths . /*obtain optional argument from the CL.*/ -if widths=='' | widths=="," then widths= 5 /*Not specified? Then use the default.*/ -call genP /*build array of semaphores for primes.*/ -names= 'one two three four five six seven eight' /*names for some low decimal numbers. */ -$.= - do j=1 for # /*only use primes that are within range*/ - do b=36 by -1 for 35; n= base(@.j, b) /*use different bases for each prime. */ - L= length(n); if L>widths then iterate /*obtain length; Length too big? Skip.*/ - if L==1 then $.L.n= b $.L.n /*Length = unity? Prepend the base.*/ - else $.L.n= $.L.n b /* " ¬= " Append " " */ - end /*b*/ - end /*j*/ - /*display info for each of the widths. */ - do w=1 for widths; cnt= 0 /*show for each width: cnt,number,bases*/ - bot= left(1, w, 0); top= left(9, w, 9) /*calculate range for DO. */ - do n=bot to top; y= words($.w.n) /*find the sets of numbers for a width.*/ - if y>cnt then do; mxn=n; cnt= max(cnt, y); end /*found a max? Remember it*/ - end /*n*/ - say - say; say center(' 'word(names, w)"─character numbers that are" , - 'prime in the most bases: ('cnt "bases) ", 101, '─') - do n=bot to top; y= words($.w.n) /*search again for maximums.*/ - if y==cnt then say n '──►' strip($.w.n) /*display ───a─── maximum. */ - end /*n*/ - end /*w*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -base: procedure; parse arg x,r,,z; @= '0123456789abcdefghijklmnopqrsruvwxyz' - do j=1; _= r**j; if _>x then leave - end /*j*/ - do k=j-1 to 1 by -1; _= r**k; z= z || substr(@, (x % _) + 1, 1); x= x // _ - end /*k*/; return z || substr(@, x+1, 1) -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11 /*define some low primes. */ - #= 5; sq.#= @.# ** 2 /*number primes so far; prime squared.*/ - do j=@.#+2 by 2 to 2 * 36 * 10**widths /*find odd primes from here on. */ - parse var j '' -1 _; if _==5 then iterate /*J is ÷ by 5? (right dig).*/ - if j//3==0 then iterate; if j//7==0 then iterate /*" " " " 3?; ÷ by 7? */ - do k=5 while sq.k<=j /* [↓] divide by the known odd primes.*/ - if j//@.k==0 then iterate j /*Is J ÷ X? Then not prime. ___ */ - end /*k*/ /* [↑] only process numbers ≤ √ J */ - #= # + 1; @.#= j; sq.#= j*j /*bump # Ps; assign next P; P squared.*/ - end /*j*/; return +-- 22 Mar 2025 +include Settings + +say 'MULTI-BASE PRIMES' +say version +say +arg ww +if ww = '' then + ww = 4 +call GetPrimes +call Collect +call Report +exit + +GetPrimes: +call time('r') +a = 2*36*10**ww +say 'Get primes up to' a'...' +call Primes 2*36*10**ww +say Time('e')/1 'seconds'; say +return + +Collect: +call time('r') +say 'Collect bases up to' ww'-character numbers...' +base. = '' +do j = 1 to prim.0 + do b = 36 by -1 to 2 + n = Basenn(prim.j,b); l = Length(n) + if l > ww then + iterate + if l = 1 then + base.l.n = b base.l.n + else + base.l.n = base.l.n b + end +end +say Time('e')/1 'seconds'; say +return + +Report: +call time('r') +say 'Report bases up to' ww'-character numbers...' +do w = 1 to ww + a = Left(1,w,0); b = Left(9,w,9); c = 0 + do n = a to b + y = Words(base.w.n) + if y > c then do + mxn = n; c = Max(c,y) + end + end + say w'-character numbers that are prime in the most bases ('c')' + do n = a to b + y = Words(base.w.n) + if y = c then + say n 'in' Strip(base.w.n) + end + say +end +say Time('e')/1 'seconds'; say +return + +include Sequences +include Numbers +include Functions +include Abend diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-1.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-1.basic new file mode 100644 index 0000000000..3a3478d7ad --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-1.basic @@ -0,0 +1,5 @@ +NEW +DIM A%(1,1) +A%(0,0)=1 +A%(0,1)=2 +CALL-151 : REM enter the machine language monitor to inspect memory diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-2.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-2.basic new file mode 100644 index 0000000000..7196c6c02c --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-2.basic @@ -0,0 +1 @@ +800.817 E000G dump the array memory and cold start BASIC diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-3.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-3.basic new file mode 100644 index 0000000000..24f8b028ad --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-3.basic @@ -0,0 +1 @@ +DIM A(4,3,2,1) diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-4.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-4.basic new file mode 100644 index 0000000000..bd4ca73386 --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-4.basic @@ -0,0 +1,5 @@ + 0 DATA3 + 1 DIM A(4,3,2,1) + 2 GET A(4,3,2,1) + 3 INPUT A(4,3,2,1) + 4 READ A(4,3,2,1) diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-5.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-5.basic new file mode 100644 index 0000000000..f7081fdaea --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-5.basic @@ -0,0 +1 @@ +RUN diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-6.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-6.basic new file mode 100644 index 0000000000..2f742aa6c7 --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-6.basic @@ -0,0 +1 @@ +LET A(4,3,2,1) = 1 : REM the LET keyword is optional diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-7.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-7.basic new file mode 100644 index 0000000000..fef7f0345e --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-7.basic @@ -0,0 +1 @@ +PRINT A(4,3,2,1) : REM arrays can be accessed in expressions diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-8.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-8.basic new file mode 100644 index 0000000000..3a1713158f --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-8.basic @@ -0,0 +1 @@ +A(4,3,2,1) = 2 diff --git a/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-9.basic b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-9.basic new file mode 100644 index 0000000000..e3ee8c3204 --- /dev/null +++ b/Task/Multi-dimensional-array/Applesoft-BASIC/multi-dimensional-array-9.basic @@ -0,0 +1 @@ +PRINT A(4,3,2,1) diff --git a/Task/Multi-dimensional-array/C++/multi-dimensional-array.cpp b/Task/Multi-dimensional-array/C++/multi-dimensional-array-1.cpp similarity index 88% rename from Task/Multi-dimensional-array/C++/multi-dimensional-array.cpp rename to Task/Multi-dimensional-array/C++/multi-dimensional-array-1.cpp index e471fe5954..9aca4766f7 100644 --- a/Task/Multi-dimensional-array/C++/multi-dimensional-array.cpp +++ b/Task/Multi-dimensional-array/C++/multi-dimensional-array-1.cpp @@ -1,7 +1,7 @@ #include #include -// convienince for printing the contents of a collection +// convenience for printing the contents of a collection template std::ostream& operator<<(std::ostream& out, const std::vector& c) { auto it = c.cbegin(); @@ -57,9 +57,9 @@ void fourDim() { } int main() { - /* C++ does not have native support for multi-dimensional arrays, + /* C++ hasn't had native support for multi-dimensional arrays, * but classes could be written to make things easier to work with. - * There are standard library classes which can be used for single dimension arrays. + * std::vector<>, std::array<> and even int[] can be composed to create multidimensional arrays. * Also raw access is supported through pointers as in C. */ diff --git a/Task/Multi-dimensional-array/C++/multi-dimensional-array-2.cpp b/Task/Multi-dimensional-array/C++/multi-dimensional-array-2.cpp new file mode 100644 index 0000000000..a77f26c762 --- /dev/null +++ b/Task/Multi-dimensional-array/C++/multi-dimensional-array-2.cpp @@ -0,0 +1,80 @@ +#include // array +#include // mdspan +#include // ranges::iota +#include // println +#include // views::{cartesian_product, iota, take, transform} +#include // apply + +using namespace std; + +template + requires((Extents != dynamic_extent) && ...) && (sizeof...(Extents) < 10) +static consteval auto generate_array(extents) -> array { + + // Generate a sequence of numbers (0..size) to fit into the array + auto ret = array{}; + ranges::iota(ret, 0); + + return ret; +} + +// Given extents of size i, create right-index arrays of size i +// That is, a combination of indices that increment from the right-side first +template + requires((Extents != dynamic_extent) && ...) +static consteval auto right_indices(extents) { + + // Generate all combinations of (0..2, 0..3, 0..4, 0..5) + constexpr auto index_ranges = views::cartesian_product(views::iota(size_t{}, Extents)...); + + // Convert tuple of numbers (a, b, c, d) to array of numbers [a, b, c, d] + constexpr auto tuple_to_array = [](auto &&tuple) { + return apply([](auto... elems) { return array{elems...}; }, tuple); + }; + + return index_ranges | views::transform(tuple_to_array); +} + +int main() { + // This type models the size of our backing array and the shape of the mdspan + using exts = extents; + + auto backing_array = generate_array(exts{}); + constexpr auto array_indices = right_indices(exts{}); + + // mdspan accesses the underlying array in row-major ordering (std::layout_right) by default + auto row_span = mdspan{backing_array.data(), exts{}}; + auto col_span = mdspan{backing_array.data(), layout_left::mapping{exts{}}}; + + // print out the rank count and size of the underlying data structure + println("row_span.rank() = {}", row_span.rank()); + println("row_span.size() = {}", row_span.size()); + + // Display the size of each dimension + for (auto &&i : views::iota(size_t{}, row_span.rank())) { + println("row_span.extent({}) = {}, ", i, row_span.extent(i)); + } + + /// Add-assign a value using the multidimensional subscript operator + row_span[0, 0, 0, 0] += 999; + + // We can't iterate through our dim_span directly, so we have to index through it instead + // Here we demonstrate the ability to index into an mdspan with an array + // + // indexing out of bounds with [] is still undefined behavior + // There is no .at() equivalent for throwing access + + println("\n======================== Row-major =======================\n"); + + println("First 30 elements:\n{}", + array_indices | views::take(30) | + views::transform( + [&](array &&idc) -> int { return row_span[idc]; })); + + println("\n=========== Column-major (right_array_indices) ===========\n"); + + println("First 30 elements:\n{}", + array_indices | views::take(30) | + views::transform( + [&](array &&idc) -> int { return col_span[idc]; })); +} diff --git a/Task/Multiplication-tables/EasyLang/multiplication-tables.easy b/Task/Multiplication-tables/EasyLang/multiplication-tables.easy index f1cd5095ec..1dc483371a 100644 --- a/Task/Multiplication-tables/EasyLang/multiplication-tables.easy +++ b/Task/Multiplication-tables/EasyLang/multiplication-tables.easy @@ -1,14 +1,10 @@ n = 12 -numfmt 0 4 +numfmt 4 0 write " " -for i = 1 to n - write i -. +for i = 1 to n : write i print "" write " " -for i = 1 to n - write "----" -. +for i = 1 to n : write "----" print "" for i = 1 to n write i diff --git a/Task/Multiplication-tables/Objeck/multiplication-tables.objeck b/Task/Multiplication-tables/Objeck/multiplication-tables.objeck new file mode 100644 index 0000000000..802fe8d28c --- /dev/null +++ b/Task/Multiplication-tables/Objeck/multiplication-tables.objeck @@ -0,0 +1,25 @@ +class MulTbl { + function : Main(args : String[]) ~ Nil { + for(i := 1; i <= 12; i++;) { + "\t{$i}"->Print(); + }; + + ""->PrintLine(); + for(i := 0; i < 100; i++;) { + ("-")->Print(); + }; + + ""->PrintLine(); + for(i := 1; i <= 12; i++;) { + "{$i}|"->Print(); + for(j := 1; j <= 12; j++) { + "\t"->Print(); + if (j >= i) { + s := i * j; + "{$s}"->Print(); + }; + }; + ""->PrintLine(); + }; + } +} diff --git a/Task/Multisplit/EasyLang/multisplit.easy b/Task/Multisplit/EasyLang/multisplit.easy index ac60f0d2ff..9f6e2551db 100644 --- a/Task/Multisplit/EasyLang/multisplit.easy +++ b/Task/Multisplit/EasyLang/multisplit.easy @@ -1,4 +1,4 @@ -proc multisplit str$ sep$[] . . +proc multisplit str$ sep$[] . repeat min = 1 / 0 for sep$ in sep$[] diff --git a/Task/Munchausen-numbers/J/munchausen-numbers-3.j b/Task/Munchausen-numbers/J/munchausen-numbers-3.j new file mode 100644 index 0000000000..3d79f08bd8 --- /dev/null +++ b/Task/Munchausen-numbers/J/munchausen-numbers-3.j @@ -0,0 +1,7 @@ + load 'stats/base/combinatorial' + nDigits =: 4 + p =: 0 1 4 27 256 3125 46656 823543 16777216 387420489 + sp =: [:+/"1 p{~] + dg =: 10&#.inv + (sp@#~[:-:/"2[:/:~"1(],:~dg@sp)"1) nDigits combrep 10 +0 1 3435 diff --git a/Task/Munchausen-numbers/R/munchausen-numbers.r b/Task/Munchausen-numbers/R/munchausen-numbers.r new file mode 100644 index 0000000000..8079ca1175 --- /dev/null +++ b/Task/Munchausen-numbers/R/munchausen-numbers.r @@ -0,0 +1,10 @@ +exp_digsum <- function(n){ + if(n>9){ + return((n%%10)^(n%%10)+exp_digsum(n%/%10)) + } + else return(n^n) +} + +for(i in 1:5000){ + if(exp_digsum(i)==i) print(i) +} diff --git a/Task/Munching-squares/Arturo/munching-squares.arturo b/Task/Munching-squares/Arturo/munching-squares.arturo new file mode 100644 index 0000000000..8e945b6747 --- /dev/null +++ b/Task/Munching-squares/Arturo/munching-squares.arturo @@ -0,0 +1,9 @@ +; outputs a PPM image file +imgSize: 256 +image: ~"P3\n|imgSize| |imgSize|\n255\n" + +loop 0..dec imgSize 'row -> + loop 0..dec imgSize 'col -> + 'image ++ ~"|xor row col| |or row col| |and row col|\n" + +write image ./"munching.ppm" diff --git a/Task/Munching-squares/EasyLang/munching-squares.easy b/Task/Munching-squares/EasyLang/munching-squares.easy index b888d2e392..78ae2c25f5 100644 --- a/Task/Munching-squares/EasyLang/munching-squares.easy +++ b/Task/Munching-squares/EasyLang/munching-squares.easy @@ -1,9 +1,8 @@ sc = 100 / 64 -for x range0 64 - for y range0 64 +for x = 0 to 63 + for y = 0 to 63 h = bitand bitxor x y 63 / 63 - color3 h h h - move x * sc y * sc - rect sc + 0.1 sc + 0.1 + gcolor3 h h h + grect x * sc y * sc sc + 0.1 sc + 0.1 . . diff --git a/Task/Munching-squares/Uiua/munching-squares.uiua b/Task/Munching-squares/Uiua/munching-squares.uiua new file mode 100644 index 0000000000..eb4602c5a0 --- /dev/null +++ b/Task/Munching-squares/Uiua/munching-squares.uiua @@ -0,0 +1 @@ +÷256⊞[0.⍜∩⋯⬚0≠].⇡256 diff --git a/Task/Musical-scale/Java/musical-scale.java b/Task/Musical-scale/Java/musical-scale.java index 41061e9847..8ee6d59a24 100644 --- a/Task/Musical-scale/Java/musical-scale.java +++ b/Task/Musical-scale/Java/musical-scale.java @@ -1,4 +1,6 @@ import java.util.List; +import java.util.stream.IntStream; + import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.LineUnavailableException; @@ -7,48 +9,54 @@ import javax.sound.sampled.SourceDataLine; public final class MusicalScale { public static void main(String[] aArgs) { - List frequencies = List.of( 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25 ); - final int duration = 500; + List frequencies = List.of( 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25 ); + + prepareSourceDataLine(); + + final int duration = 500; // in milliseconds final int volume = 1; - for ( int i = 0; i < 3; i++ ) { + IntStream.range(0, 3).forEach( _ -> { for ( double frequency : frequencies ) { musicalTone(frequency, duration, volume); } - } + } ); + + sourceDataLine.close(); } - private static void musicalTone(double aFrequency, int aDuration, int aVolume) { - byte[] buffer = new byte[1]; - AudioFormat audioFormat = getAudioFormat(); + private static void musicalTone(double frequency, int duration, int volume) { + sourceDataLine.start(); - try ( SourceDataLine sourceDataLine = AudioSystem.getSourceDataLine(audioFormat) ) { - sourceDataLine.open(audioFormat); - sourceDataLine.start(); - - for ( int i = 0; i < aDuration * 8; i++ ) { - double angle = i / ( SAMPLE_RATE / aFrequency ) * 2 * Math.PI; - buffer[0] = (byte) ( Math.sin(angle) * 127 * aVolume ); - sourceDataLine.write(buffer, BYTE_OFFSET, buffer.length); - } - - sourceDataLine.drain(); - sourceDataLine.stop(); - sourceDataLine.close(); - } catch (LineUnavailableException exception) { - exception.printStackTrace(); - } + IntStream.range(0, 8 * duration).forEach( i -> { + final double angle = i / ( SAMPLE_RATE / frequency ) * 2 * Math.PI; + byte[] buffer = new byte[] { (byte) ( Math.sin(angle) * 127 * volume ) }; + sourceDataLine.write(buffer, BYTE_OFFSET, buffer.length); + } ); + + sourceDataLine.drain(); + sourceDataLine.stop(); } - private static AudioFormat getAudioFormat() { + private static void prepareSourceDataLine() { final int sampleSizeInBits = 8; final int numberChannels = 1; final boolean signedData = true; final boolean isBigEndian = false; - return new AudioFormat(SAMPLE_RATE, sampleSizeInBits, numberChannels, signedData, isBigEndian); + AudioFormat audioFormat = new AudioFormat( + SAMPLE_RATE, sampleSizeInBits, numberChannels, signedData, isBigEndian); + + try { + sourceDataLine = AudioSystem.getSourceDataLine(audioFormat); + sourceDataLine.open(audioFormat); + } catch (LineUnavailableException lue) { + lue.printStackTrace(); + } } + private static SourceDataLine sourceDataLine; + private static float SAMPLE_RATE = 8_000.0F; private static final int BYTE_OFFSET = 0; diff --git a/Task/Musical-scale/JavaScript/musical-scale.js b/Task/Musical-scale/JavaScript/musical-scale.js index aae2540dd2..77a3ebe4a3 100644 --- a/Task/Musical-scale/JavaScript/musical-scale.js +++ b/Task/Musical-scale/JavaScript/musical-scale.js @@ -1,36 +1,36 @@ - - - - -Sample Page - - - - - - + +function playNotes(root, notes, { seconds, wave } = {}) { + const ctx = new AudioContext() + const oscillator = ctx.createOscillator() + const freqs = notes.map(incrementSemitones(root)) + + oscillator.connect(ctx.createGain().connect(ctx.destination)) + oscillator.type = wave ?? 'sine' + + const duration = seconds ?? 0.3 + + for (const [i, freq] of freqs.entries()) { + oscillator.frequency.setValueAtTime(freq, ctx.currentTime + i * duration) + } + + oscillator.start() + oscillator.stop(ctx.currentTime + freqs.length * duration) + + return new Promise((res) => oscillator.addEventListener('ended', res)) +} + +const A = 440 +const C = incrementSemitones(A)(-9) // ~= 261.63 + +const major = [0, 2, 4, 5, 7, 9, 11, 12] +const minor = [0, 2, 3, 5, 7, 8, 10, 12] + +void (async function main() { + await playNotes(C, major, { seconds: 0.3, wave: 'sine' }) + await playNotes(A, minor, { seconds: 0.1, wave: 'triangle' }) +})() diff --git a/Task/N-queens-problem/C/n-queens-problem-1.c b/Task/N-queens-problem/C/n-queens-problem-1.c index 8b4dc90905..151b12f9c9 100644 --- a/Task/N-queens-problem/C/n-queens-problem-1.c +++ b/Task/N-queens-problem/C/n-queens-problem-1.c @@ -34,10 +34,10 @@ advance_row: } col = 0; try_column: - if (!a[col] && !b[col+row-1] && !c[col-row+n]) { + if (!a[col] && !b[col+row] && !c[col-row+n-1]) { a[col] = true; - b[col+row-1] = true; - c[col-row+n] = true; + b[col+row] = true; + c[col-row+n-1] = true; x[row] = col; row++; goto advance_row; @@ -51,8 +51,8 @@ backtrack: if (row != 0) { --row; col = x[row]; - c[col-row+n] = false; - b[col+row-1] = false; + c[col-row+n-1] = false; + b[col+row] = false; a[col] = false; goto try_again; } @@ -60,9 +60,8 @@ backtrack: static void *calloc_wrapper(size_t count, size_t bytesize) { void *r; - if ((r = calloc(count, bytesize)) == NULL) { + if ((r = calloc(count, bytesize)) == NULL) exit(EXIT_FAILURE); - } return r; } diff --git a/Task/N-queens-problem/Jq/n-queens-problem-6.jq b/Task/N-queens-problem/Jq/n-queens-problem-6.jq new file mode 100644 index 0000000000..ab836a6131 --- /dev/null +++ b/Task/N-queens-problem/Jq/n-queens-problem-6.jq @@ -0,0 +1,38 @@ +def queens(n): + def q: . as $pl + | $pl[4] as $r + | $pl[3] as $cl | $cl[] | . as $c + | ($r+$c | tostring) as $k0 + | ($r-$c | tostring) as $k1 + | def place: + ($k0 | in($pl[1]) | not) + and ($k1 | in($pl[2]) | not); + select(place) + | [$pl[0]+[$c], $pl[1]+{$k0:null}, + $pl[2]+{$k1:null}, $cl-[$c], $r+1]; + def pipeline(n): + q | if n > 1 then pipeline(n-1) end; + def toletter: + "abcdefghijklmnopqrstuvwxyz"[.:.+1]; + def fund_solut(f): + def inverse: . as $xl + | reduce range(0; n) as $i + ([]; .+[$xl | index($i)]); + def variants: + [., inverse] | map(., reverse) + | map(., map(n-1-.)) + | map(map(toletter) | add); + foreach f as $i + ([null, {}]; .[1] as $ml + | ($i | variants) as $nl + | if all($nl[]; in($ml) | not) then + [$i, ($ml | .[$nl[]]=null)] + else + [null, $ml] end; + .[0]) + | select (. != null); + fund_solut([[], {}, {}, [range(0; n)], 0] + | pipeline(n) | .[0]) + | map(toletter) | to_entries + | map(.value+(.key+1 | tostring)) | sort; +queens(8) diff --git a/Task/N-queens-problem/Jq/n-queens-problem-7.jq b/Task/N-queens-problem/Jq/n-queens-problem-7.jq new file mode 100644 index 0000000000..9c6b1ee068 --- /dev/null +++ b/Task/N-queens-problem/Jq/n-queens-problem-7.jq @@ -0,0 +1,13 @@ +$ jq -nc -f ./queens.jq +["a1","b7","c5","d8","e2","f4","g6","h3"] +["a1","b7","c4","d6","e8","f2","g5","h3"] +["a6","b1","c5","d2","e8","f3","g7","h4"] +["a4","b1","c5","d8","e2","f7","g3","h6"] +["a5","b1","c8","d4","e2","f7","g3","h6"] +["a3","b1","c7","d5","e8","f2","g4","h6"] +["a5","b1","c4","d6","e8","f2","g7","h3"] +["a7","b1","c3","d8","e6","f4","g2","h5"] +["a5","b1","c8","d6","e3","f7","g2","h4"] +["a5","b3","c1","d7","e2","f8","g6","h4"] +["a5","b7","c1","d4","e2","f8","g6","h3"] +["a6","b3","c1","d8","e4","f2","g7","h5"] diff --git a/Task/N-queens-problem/Python/n-queens-problem-10.py b/Task/N-queens-problem/Python/n-queens-problem-10.py new file mode 100644 index 0000000000..8a1791f8f8 --- /dev/null +++ b/Task/N-queens-problem/Python/n-queens-problem-10.py @@ -0,0 +1,13 @@ +$ python3 ./queens.py +['a1', 'b7', 'c5', 'd8', 'e2', 'f4', 'g6', 'h3'] +['a1', 'b7', 'c4', 'd6', 'e8', 'f2', 'g5', 'h3'] +['a6', 'b1', 'c5', 'd2', 'e8', 'f3', 'g7', 'h4'] +['a4', 'b1', 'c5', 'd8', 'e2', 'f7', 'g3', 'h6'] +['a5', 'b1', 'c8', 'd4', 'e2', 'f7', 'g3', 'h6'] +['a3', 'b1', 'c7', 'd5', 'e8', 'f2', 'g4', 'h6'] +['a5', 'b1', 'c4', 'd6', 'e8', 'f2', 'g7', 'h3'] +['a7', 'b1', 'c3', 'd8', 'e6', 'f4', 'g2', 'h5'] +['a5', 'b1', 'c8', 'd6', 'e3', 'f7', 'g2', 'h4'] +['a5', 'b3', 'c1', 'd7', 'e2', 'f8', 'g6', 'h4'] +['a5', 'b7', 'c1', 'd4', 'e2', 'f8', 'g6', 'h3'] +['a6', 'b3', 'c1', 'd8', 'e4', 'f2', 'g7', 'h5'] diff --git a/Task/N-queens-problem/Python/n-queens-problem-5.py b/Task/N-queens-problem/Python/n-queens-problem-5.py index 7cc53040e3..040ec86b2b 100644 --- a/Task/N-queens-problem/Python/n-queens-problem-5.py +++ b/Task/N-queens-problem/Python/n-queens-problem-5.py @@ -6,6 +6,5 @@ def queens(n: int, i: int, a: list, b: list, c: list): else: yield a - for solution in queens(8, 0, [], [], []): print(solution) diff --git a/Task/N-queens-problem/Python/n-queens-problem-6.py b/Task/N-queens-problem/Python/n-queens-problem-6.py index 2f6cb0cbf0..acc9a23854 100644 --- a/Task/N-queens-problem/Python/n-queens-problem-6.py +++ b/Task/N-queens-problem/Python/n-queens-problem-6.py @@ -1,14 +1,23 @@ -def queens(i: int, a: set): - if a: # set a is not empty - for j in a: - if i + j not in b and i - j not in c: - b.add(i + j); c.add(i - j); x.append(j) - yield from queens(i + 1, a - {j}) - b.remove(i + j); c.remove(i - j); x.pop() - else: - yield x +def queens(n: int): + + def sub(i: int): + if i < n: + for k in range(i, n): + j = a[k] + if b[i + j] and c[i - j]: + a[i], a[k] = a[k], a[i] + b[i + j] = c[i - j] = False + yield from sub(i + 1) + b[i + j] = c[i - j] = True + a[i], a[k] = a[k], a[i] + else: + yield a + + a = list(range(n)) + b = [True] * (2 * n - 1) + c = [True] * (2 * n - 1) + yield from sub(0) -b = set(); c = set(); x = [] -for solution in queens(0, set(range(8))): - print(solution) +sum(1 for solution in queens(8)) # count solutions +92 diff --git a/Task/N-queens-problem/Python/n-queens-problem-7.py b/Task/N-queens-problem/Python/n-queens-problem-7.py index f404b4c1dc..3a6b107381 100644 --- a/Task/N-queens-problem/Python/n-queens-problem-7.py +++ b/Task/N-queens-problem/Python/n-queens-problem-7.py @@ -1,15 +1,15 @@ -def queens(n: int): +def queens_lex(n: int): def sub(i: int): if i < n: for k in range(i, n): j = a[k] + a[i], a[k] = a[k], a[i] if b[i + j] and c[i - j]: - a[i], a[k] = a[k], a[i] b[i + j] = c[i - j] = False yield from sub(i + 1) b[i + j] = c[i - j] = True - a[i], a[k] = a[k], a[i] + a[i:(n - 1)], a[n - 1] = a[(i + 1):n], a[i] else: yield a @@ -19,5 +19,11 @@ def queens(n: int): yield from sub(0) -sum(1 for p in queens(8)) # count solutions -92 +next(queens(31)) +[0, 2, 4, 1, 3, 8, 10, 12, 14, 6, 17, 21, 26, 28, 25, 27, 24, 30, 7, 5, 29, 15, 13, 11, 9, 18, 22, 19, 23, 16, 20] + +next(queens_lex(31)) +[0, 2, 4, 1, 3, 8, 10, 12, 14, 5, 17, 22, 25, 27, 30, 24, 26, 29, 6, 16, 28, 13, 9, 7, 19, 11, 15, 18, 21, 23, 20] + +#Compare to A065188 +#1, 3, 5, 2, 4, 9, 11, 13, 15, 6, 8, 19, 7, 22, 10, 25, 27, 29, 31, 12, 14, 35, 37, ... diff --git a/Task/N-queens-problem/Python/n-queens-problem-8.py b/Task/N-queens-problem/Python/n-queens-problem-8.py index 3a6b107381..dd102072e1 100644 --- a/Task/N-queens-problem/Python/n-queens-problem-8.py +++ b/Task/N-queens-problem/Python/n-queens-problem-8.py @@ -1,29 +1,146 @@ -def queens_lex(n: int): +'''N Queens problem''' - def sub(i: int): - if i < n: - for k in range(i, n): - j = a[k] - a[i], a[k] = a[k], a[i] - if b[i + j] and c[i - j]: - b[i + j] = c[i - j] = False - yield from sub(i + 1) - b[i + j] = c[i - j] = True - a[i:(n - 1)], a[n - 1] = a[(i + 1):n], a[i] - else: - yield a - - a = list(range(n)) - b = [True] * (2 * n - 1) - c = [True] * (2 * n - 1) - yield from sub(0) +from functools import reduce +from itertools import chain -next(queens(31)) -[0, 2, 4, 1, 3, 8, 10, 12, 14, 6, 17, 21, 26, 28, 25, 27, 24, 30, 7, 5, 29, 15, 13, 11, 9, 18, 22, 19, 23, 16, 20] +# queenPuzzle :: Int -> Int -> [[Int]] +def queenPuzzle(nCols): + '''All board patterns of this dimension + in which no two Queens share a row, + column, or diagonal. + ''' + def go(nRows): + lessRows = nRows - 1 + return reduce( + lambda a, xys: a + reduce( + lambda b, iCol: b + [xys + [iCol]] if ( + safe(lessRows, iCol, xys) + ) else b, + enumFromTo(1)(nCols), + [] + ), + go(lessRows), + [] + ) if 0 < nRows else [[]] + return go -next(queens_lex(31)) -[0, 2, 4, 1, 3, 8, 10, 12, 14, 5, 17, 22, 25, 27, 30, 24, 26, 29, 6, 16, 28, 13, 9, 7, 19, 11, 15, 18, 21, 23, 20] -#Compare to A065188 -#1, 3, 5, 2, 4, 9, 11, 13, 15, 6, 8, 19, 7, 22, 10, 25, 27, 29, 31, 12, 14, 35, 37, ... +# safe :: Int -> Int -> [Int] -> Bool +def safe(iRow, iCol, pattern): + '''True if no two queens in the pattern + share a row, column or diagonal. + ''' + def p(sc, sr): + return (iCol == sc) or ( + sc + sr == (iCol + iRow) + ) or (sc - sr == (iCol - iRow)) + return not any(map(p, pattern, range(0, iRow))) + + +# ------------------------- TEST ------------------------- +# main :: IO () +def main(): + '''Number of solutions for boards of various sizes''' + + n = 5 + xs = queenPuzzle(n)(n) + + print( + str(len(xs)) + ' solutions for a {n} * {n} board:\n'.format(n=n) + ) + print(showBoards(10)(xs)) + + print( + fTable( + '\n\n' + main.__doc__ + ':\n' + )(str)(lambda n: str(n).rjust(3, ' '))( + lambda n: len(queenPuzzle(n)(n)) + )(enumFromTo(1)(10)) + ) + + +# ---------------------- FORMATTING ---------------------- + +# showBoards :: Int -> [[Int]] -> String +def showBoards(nCols): + '''String representation, with N columns + of a set of board patterns. + ''' + def showBlock(b): + return '\n'.join(map(intercalate(' '), zip(*b))) + + def go(bs): + return '\n\n'.join(map( + showBlock, + chunksOf(nCols)([ + showBoard(b) for b in bs + ]) + )) + return go + + +# showBoard :: [Int] -> String +def showBoard(xs): + '''String representation of a Queens board.''' + lng = len(xs) + + def showLine(n): + return ('.' * (n - 1)) + '♛' + ('.' * (lng - n)) + return map(showLine, xs) + + +# fTable :: String -> (a -> String) -> +# (b -> String) -> (a -> b) -> [a] -> String +def fTable(s): + '''Heading -> x display function -> fx display function -> + f -> xs -> tabular string. + ''' + def go(xShow, fxShow, f, xs): + ys = [xShow(x) for x in xs] + w = max(map(len, ys)) + return s + '\n' + '\n'.join(map( + lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)), + xs, ys + )) + return lambda xShow: lambda fxShow: lambda f: lambda xs: go( + xShow, fxShow, f, xs + ) + + +# ----------------------- GENERIC ------------------------ + +# enumFromTo :: (Int, Int) -> [Int] +def enumFromTo(m): + '''Integer enumeration from m to n.''' + return lambda n: range(m, 1 + n) + + +# chunksOf :: Int -> [a] -> [[a]] +def chunksOf(n): + '''A series of lists of length n, subdividing the + contents of xs. Where the length of xs is not evenly + divible, the final list will be shorter than n. + ''' + return lambda xs: reduce( + lambda a, i: a + [xs[i:n + i]], + range(0, len(xs), n), [] + ) if 0 < n else [] + + +# intercalate :: [a] -> [[a]] -> [a] +# intercalate :: String -> [String] -> String +def intercalate(x): + '''The concatenation of xs + interspersed with copies of x. + ''' + return lambda xs: x.join(xs) if isinstance(x, str) else list( + chain.from_iterable( + reduce(lambda a, v: a + [x, v], xs[1:], [xs[0]]) + ) + ) if xs else [] + + +# MAIN --- +if __name__ == '__main__': + main() diff --git a/Task/N-queens-problem/Python/n-queens-problem-9.py b/Task/N-queens-problem/Python/n-queens-problem-9.py index dd102072e1..9e9a11ad39 100644 --- a/Task/N-queens-problem/Python/n-queens-problem-9.py +++ b/Task/N-queens-problem/Python/n-queens-problem-9.py @@ -1,146 +1,34 @@ -'''N Queens problem''' - -from functools import reduce -from itertools import chain - - -# queenPuzzle :: Int -> Int -> [[Int]] -def queenPuzzle(nCols): - '''All board patterns of this dimension - in which no two Queens share a row, - column, or diagonal. - ''' - def go(nRows): - lessRows = nRows - 1 - return reduce( - lambda a, xys: a + reduce( - lambda b, iCol: b + [xys + [iCol]] if ( - safe(lessRows, iCol, xys) - ) else b, - enumFromTo(1)(nCols), - [] - ), - go(lessRows), - [] - ) if 0 < nRows else [[]] - return go - - -# safe :: Int -> Int -> [Int] -> Bool -def safe(iRow, iCol, pattern): - '''True if no two queens in the pattern - share a row, column or diagonal. - ''' - def p(sc, sr): - return (iCol == sc) or ( - sc + sr == (iCol + iRow) - ) or (sc - sr == (iCol - iRow)) - return not any(map(p, pattern, range(0, iRow))) - - -# ------------------------- TEST ------------------------- -# main :: IO () -def main(): - '''Number of solutions for boards of various sizes''' - - n = 5 - xs = queenPuzzle(n)(n) - - print( - str(len(xs)) + ' solutions for a {n} * {n} board:\n'.format(n=n) - ) - print(showBoards(10)(xs)) - - print( - fTable( - '\n\n' + main.__doc__ + ':\n' - )(str)(lambda n: str(n).rjust(3, ' '))( - lambda n: len(queenPuzzle(n)(n)) - )(enumFromTo(1)(10)) - ) - - -# ---------------------- FORMATTING ---------------------- - -# showBoards :: Int -> [[Int]] -> String -def showBoards(nCols): - '''String representation, with N columns - of a set of board patterns. - ''' - def showBlock(b): - return '\n'.join(map(intercalate(' '), zip(*b))) - - def go(bs): - return '\n\n'.join(map( - showBlock, - chunksOf(nCols)([ - showBoard(b) for b in bs - ]) - )) - return go - - -# showBoard :: [Int] -> String -def showBoard(xs): - '''String representation of a Queens board.''' - lng = len(xs) - - def showLine(n): - return ('.' * (n - 1)) + '♛' + ('.' * (lng - n)) - return map(showLine, xs) - - -# fTable :: String -> (a -> String) -> -# (b -> String) -> (a -> b) -> [a] -> String -def fTable(s): - '''Heading -> x display function -> fx display function -> - f -> xs -> tabular string. - ''' - def go(xShow, fxShow, f, xs): - ys = [xShow(x) for x in xs] - w = max(map(len, ys)) - return s + '\n' + '\n'.join(map( - lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)), - xs, ys - )) - return lambda xShow: lambda fxShow: lambda f: lambda xs: go( - xShow, fxShow, f, xs - ) - - -# ----------------------- GENERIC ------------------------ - -# enumFromTo :: (Int, Int) -> [Int] -def enumFromTo(m): - '''Integer enumeration from m to n.''' - return lambda n: range(m, 1 + n) - - -# chunksOf :: Int -> [a] -> [[a]] -def chunksOf(n): - '''A series of lists of length n, subdividing the - contents of xs. Where the length of xs is not evenly - divible, the final list will be shorter than n. - ''' - return lambda xs: reduce( - lambda a, i: a + [xs[i:n + i]], - range(0, len(xs), n), [] - ) if 0 < n else [] - - -# intercalate :: [a] -> [[a]] -> [a] -# intercalate :: String -> [String] -> String -def intercalate(x): - '''The concatenation of xs - interspersed with copies of x. - ''' - return lambda xs: x.join(xs) if isinstance(x, str) else list( - chain.from_iterable( - reduce(lambda a, v: a + [x, v], xs[1:], [xs[0]]) - ) - ) if xs else [] - - -# MAIN --- -if __name__ == '__main__': - main() +def queens(n): + def q(pl, r): + def place(c): + return r+c not in pl[1] and r-c not in pl[2] + return ((pl[0]+[c], pl[1]|{r+c}, pl[2]|{r-c}, pl[3]-{c}) + for c in pl[3] if place(c)) + def pipeline(pl, i): + for ipl in q(pl, i): + if i+1 < n: + yield from pipeline(ipl, i+1) + else: + yield ipl[0] + def toletter(x): + return 'abcdefghijklmnopqrstuvwxyz'[x] + def fund_solut(fl): + def inversed(xl): + return (xl.index(i) for i in range(0, n)) + def variants(xl): + rl = [xl] + rl += [[*inversed(x)] for x in rl] + rl += [[*reversed(x)] for x in rl] + rl += [[n-1-i for i in x] for x in rl] + return (''.join(toletter(i) for i in x) for x in rl) + rs = set() + for i in fl: + ks = {*variants(i)} + if rs.isdisjoint(ks): + rs |= ks + yield i + for i in fund_solut( + pipeline(([], set(), set(), {*range(0, n)}), 0)): + rl = sorted(toletter(v)+str(k+1) for k, v in enumerate(i)) + print(rl) +queens(8) diff --git a/Task/N-smooth-numbers/REXX/n-smooth-numbers.rexx b/Task/N-smooth-numbers/REXX/n-smooth-numbers.rexx index db0be253b9..54f579eacb 100644 --- a/Task/N-smooth-numbers/REXX/n-smooth-numbers.rexx +++ b/Task/N-smooth-numbers/REXX/n-smooth-numbers.rexx @@ -1,44 +1,54 @@ -/*REXX pgm computes&displays X n-smooth numbers; both X and N can be specified as ranges*/ -numeric digits 200 /*be able to handle some big numbers. */ -parse arg LOx HIx LOn HIn . /*obtain optional arguments from the CL*/ -if LOx=='' | LOx=="," then LOx= 1 /*Not specified? Then use the default.*/ -if HIx=='' | HIx=="," then HIx= LOx + 24 /* " " " " " " */ -if LOn=='' | LOn=="," then LOn= 2 /* " " " " " " */ -if HIn=='' | HIn=="," then HIn= LOn + 27 /* " " " " " " */ -call genP HIn /*generate enough primes to satisfy HIn*/ -@aList= ' a list of the '; @thru= ' through ' /*literals used with a SAY.*/ +-- 25 Apr 2025 +include Settings - do j=LOn to HIn; if !.j==0 then iterate /*if not prime, then skip this number. */ - call smooth HIx,j; $= /*invoke SMOOTH; initialize $ (list). */ - do k=LOx to HIx; $= $ #.k /*append a smooth number to " " " */ - end /*k*/ - say center(@aList th(LOx) @thru th(HIx) ' numbers for' j"-smooth ", 130, "═") - say strip($); say - end /*j*/ /* [↑] the $ list has a leading blank.*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: procedure expose @. !. #; parse arg x /*#≡num of primes; @. ≡array of primes.*/ - @.=; @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13; @.7=17; @.8=19; @.9=23; #=9 - !.=0; !.2=1; !.3=2; !.5=3; !.7=4; !.11=5; !.13=6; !.17=7; !.19=8; !.23=9 - do k=@.#+6 by 2 until #>=x ; if k//3==0 then iterate - parse var k '' -1 _; if _==5 then iterate - do d=4 until @.d**2>k; if k//@.d==0 then iterate k - end /*d*/ - #= # + 1; !.k= #; @.#= k /*found a prime, bump counter; assign @*/ - end /*k*/; return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -smooth: procedure expose @. !. #.; parse arg y,p /*obtain the arguments from the invoker*/ - if p=='' then p= 3 /*Not specified? Then assume Hamming #s*/ - n= !.p /*the number of primes being used. */ - nn= n - 1; #.= 0; #.1= 1 /*an array of n-smooth numbers (so far)*/ - f.= 1 /*the indices of factors of a number. */ - do j=2 for y-1; _= f.1 - z= @.1 * #._ - do k=2 for nn; _= f.k; v= @.k * #._; if v= "0" And Mid(normalized, e, 1) <= "9") + e += 1 + Wend + If e > idx Then + Redim Preserve result(cnt) + result(cnt).tipo = KIND_STRING + result(cnt).txt = Mid(normalized, idx, e - idx) + result(cnt).num = 0 + cnt += 1 + idx = e + End If + + ' Process number + While e <= l And (Mid(normalized, e, 1) >= "0" And Mid(normalized, e, 1) <= "9") + e += 1 + Wend + If e > idx Then + Redim Preserve result(cnt) + result(cnt).tipo = KIND_NUMBER + result(cnt).txt = "" + result(cnt).num = Val(Mid(normalized, idx, e - idx)) + cnt += 1 + idx = e + End If + Wend +End Sub + +Function scmp(s1 As String, s2 As String) As Integer + If s1 < s2 Then Return -1 + If s1 > s2 Then Return 1 + Return 0 +End Function + +Function NaturalCompare(sa As String, sb As String) As Integer + Dim As KeyItem a(), b() + NatOrderKey(sa, a()) + NatOrderKey(sb, b()) + + ' Check for empty arrays + Dim As Integer la = Ubound(a), lb = Ubound(b) + + ' Handle case where one or both arrays might be empty + If la < 0 And lb < 0 Then Return 0 + If la < 0 Then Return -1 + If lb < 0 Then Return 1 + + Dim As Integer n = Iif(la < lb, la, lb) + + For i As Integer = 0 To n + Dim As KeyItem ai = a(i) + Dim As KeyItem bi = b(i) + + If ai.tipo = bi.tipo Then + Dim As Integer result + If ai.tipo = KIND_STRING Then + result = scmp(ai.txt, bi.txt) + Else + result = Sgn(ai.num - bi.num) ' Use Sgn to get -1, 0, or 1 + End If + If result <> 0 Then Return result + Else + Return Iif(ai.tipo = KIND_STRING, 1, -1) + End If + Next + + If la < lb Then Return -1 + If la > lb Then Return 1 + Return 0 +End Function + +Sub test(title As String, arr() As String) + Print title + Dim As Integer i, j, n = Ubound(arr) + + Dim As String sorted(n) + For i = 0 To n + sorted(i) = arr(i) + Next + + ' Bubble sort + For i = 0 To n - 1 + For j = 0 To n - i - 1 + If NaturalCompare(sorted(j), sorted(j + 1)) > 0 Then Swap sorted(j), sorted(j + 1) + Next + Next + + For i = 0 To n + Print "'" & sorted(i) & "'" + Next + Print +End Sub + +' tests +Dim arr1(3) As String = {"ignore leading spaces: 2-2", " ignore leading spaces: 2-1", " ignore leading spaces: 2+0", " ignore leading spaces: 2+1"} +test("Ignoring leading spaces.", arr1()) + +Dim arr2(3) As String = {"ignore MAS spaces: 2-2", "ignore MAS spaces: 2-1", "ignore MAS spaces: 2+0", "ignore MAS spaces: 2+1"} +test("Ignoring multiple adjacent spaces (MAS).", arr2()) + +Dim arr3(5) As String = {"Equiv. spaces: 3-3", "Equiv. " & Chr(13) & "spaces: 3-2", "Equiv. " & Chr(12) & "spaces: 3-1", "Equiv. " & Chr(11) & "spaces: 3+0", "Equiv. " & Chr(10) & "spaces: 3+1", "Equiv. " & Chr(9) & "spaces: 3+2"} +test("Equivalent whitespace characters.", arr3()) + +Dim arr4(3) As String = {"cASE INDEPENDENT: 3-2", "caSE INDEPENDENT: 3-1", "casE INDEPENDENT: 3+0", "case INDEPENDENT: 3+1"} +test("Case Independent sort.", arr4()) + +Dim arr5(3) As String = {"foo100bar99baz0.txt", "foo100bar10baz0.txt", "foo1000bar99baz10.txt", "foo1000bar99baz9.txt"} +test("Numeric fields as numerics.", arr5()) + +Dim arr6(3) As String = {"The Wind in the Willows", "The 40th step more", "The 39 steps", "Wanda"} +test("Title sorts.", arr6()) + +Sleep diff --git a/Task/Natural-sorting/JavaScript/natural-sorting-1.js b/Task/Natural-sorting/JavaScript/natural-sorting-1.js new file mode 100644 index 0000000000..bc0f1d6c39 --- /dev/null +++ b/Task/Natural-sorting/JavaScript/natural-sorting-1.js @@ -0,0 +1,7 @@ +function naturalSort(a, b) => { + return a.trim().localeCompare(b.trim(), 'und', { numeric: true }) +} + +const files = ['file10.txt', '\nfile9.txt', 'File11.TXT', 'file12.txt'] +console.log(files.toSorted(naturalSort)) +// ['\nfile9.txt', 'file10.txt', 'File11.TXT', 'file12.txt'] diff --git a/Task/Natural-sorting/JavaScript/natural-sorting.js b/Task/Natural-sorting/JavaScript/natural-sorting-2.js similarity index 100% rename from Task/Natural-sorting/JavaScript/natural-sorting.js rename to Task/Natural-sorting/JavaScript/natural-sorting-2.js diff --git a/Task/Natural-sorting/Rust/natural-sorting.rs b/Task/Natural-sorting/Rust/natural-sorting.rs new file mode 100644 index 0000000000..e4d588a384 --- /dev/null +++ b/Task/Natural-sorting/Rust/natural-sorting.rs @@ -0,0 +1,260 @@ +use regex::Regex; +use std::cmp::Ordering; + +// Only covers ISO-8859-1 accented characters plus, for consistency, Ÿ +const UC_ACCENTS: [&str; 8] = ["ÀÁÂÃÄÅ", "Ç", "ÈÉÊË", "ÌÍÎÏ", "Ñ", "ÒÓÔÕÖØ", "ÙÚÛÜ", "ÝŸ"]; +const LC_ACCENTS: [&str; 8] = ["àáâãäå", "ç", "èéêë", "ìíîï", "ñ", "òóôõöø", "ùúûü", "ýÿ"]; +const UC_UNACCENTS: [&str; 8] = ["A", "C", "E", "I", "N", "O", "U", "Y"]; +const LC_UNACCENTS: [&str; 8] = ["a", "c", "e", "i", "n", "o", "u", "y"]; + +// Only the more common ligatures +const UC_LIGATURES: [&str; 3] = ["Æ", "IJ", "Œ"]; +const LC_LIGATURES: [&str; 3] = ["æ", "ij", "œ"]; +const UC_SEPARATES: [&str; 3] = ["AE", "IJ", "OE"]; +const LC_SEPARATES: [&str; 3] = ["ae", "ij", "oe"]; + +// Miscellaneous replacements +const MISC_LETTERS: [&str; 3] = ["ß", "ſ", "ʒ"]; +const MISC_REPLACEMENTS: [&str; 3] = ["ss", "s", "s"]; + +// Remove leading spaces +fn left_trim(text: &str) -> String { + text.trim_start().to_string() +} + +// Replace multiple spaces with a single space +fn replace_spaces(text: &str) -> String { + let regex_expr = Regex::new(r" {2,}").unwrap(); + regex_expr.replace_all(text, " ").to_string() +} + +// Replace whitespace with a single space +fn replace_whitespace(text: &str) -> String { + let regex_expr = Regex::new(r"\s+").unwrap(); + regex_expr.replace_all(text, " ").to_string() +} + +// Display strings including whitespace as if the latter were literal characters +fn to_display_string(text: &str) -> String { + let whitespace_1 = ["\t", "\n", "\u{000b}", "\u{000c}", "\r"]; + let whitespace_2 = ["\\t", "\\n", "\\u000b", "\\u000c", "\\r"]; + let mut result = text.to_string(); + + for i in 0..whitespace_1.len() { + result = result.replace(whitespace_1[i], whitespace_2[i]); + } + result +} + +// Transform the string into lower case +fn to_lower_case(text: &str) -> String { + text.to_lowercase() +} + +// Pad each numeric character with leading zeros to a total length of 20 +fn zero_padding(text: &str) -> String { + let digits = Regex::new(r"-?\d+").unwrap(); + let mut result = text.to_string(); + let mut extra_index = 0; + + for cap in digits.captures_iter(text) { + let match_str = &cap[0]; + let start_pos = text.find(match_str).unwrap() + extra_index; + let padding = "0".repeat(20 - match_str.len()); + + result = format!("{}{}{}", + &result[..start_pos], + padding, + &result[start_pos..]); + + extra_index += 20 - match_str.len(); + } + + result +} + +fn remove_title(text: &str) -> String { + let regex = Regex::new(r"^(The|An|A)\s+").unwrap(); + regex.replace(text, "").to_string() +} + +// Replace accented letters with their unaccented equivalent +fn replace_accents(text: &str) -> String { + let mut result = String::new(); + let chars: Vec = text.chars().collect(); + + for i in 0..chars.len() { + if (chars[i] as u32) < 128 { + result.push(chars[i]); + continue; + } + + let length = result.len(); + let letter = chars[i].to_string(); + + for j in 0..UC_ACCENTS.len() { + if UC_ACCENTS[j].contains(&letter) { + result.push_str(UC_UNACCENTS[j]); + break; + } + } + + if length == result.len() { + for j in 0..LC_ACCENTS.len() { + if LC_ACCENTS[j].contains(&letter) { + result.push_str(LC_UNACCENTS[j]); + break; + } + } + } + } + + result +} + +// Replace ligatures with separated letters +fn replace_ligatures(text: &str) -> String { + let mut result = text.to_string(); + + for i in 0..UC_LIGATURES.len() { + result = result.replace(UC_LIGATURES[i], UC_SEPARATES[i]); + } + + for i in 0..LC_LIGATURES.len() { + result = result.replace(LC_LIGATURES[i], LC_SEPARATES[i]); + } + + result +} + +// Replace miscellaneous letters with their equivalent replacements +fn replace_characters(text: &str) -> String { + let mut result = text.to_string(); + + for i in 0..MISC_LETTERS.len() { + result = result.replace(MISC_LETTERS[i], MISC_REPLACEMENTS[i]); + } + + result +} + +fn main() { + println!("The 9 string lists, sorted 'naturally':"); + + let mut s1 = vec![ + "ignore leading spaces: 2-2".to_string(), + " ignore leading spaces: 2-1".to_string(), + " ignore leading spaces: 2+0".to_string(), + " ignore leading spaces: 2+1".to_string() + ]; + + println!(); + s1.sort_by(|lhs, rhs| left_trim(lhs).cmp(&left_trim(rhs))); + for s in &s1 { + println!("{}", s); + } + + let mut s2 = vec![ + "ignore m.a.s spaces: 2-2".to_string(), + "ignore m.a.s spaces: 2-1".to_string(), + "ignore m.a.s spaces: 2+0".to_string(), + "ignore m.a.s spaces: 2+1".to_string() + ]; + + println!(); + s2.sort_by(|lhs, rhs| replace_spaces(lhs).cmp(&replace_spaces(rhs))); + for s in &s2 { + println!("{}", s); + } + + let mut s3 = vec![ + "Equiv. spaces: 3-3".to_string(), + "Equiv.\rspaces: 3-2".to_string(), + "Equiv.\u{000c}spaces: 3-1".to_string(), + "Equiv.\u{000b}spaces: 3+0".to_string(), + "Equiv.\nspaces: 3+1".to_string(), + "Equiv.\tspaces: 3+2".to_string() + ]; + + println!(); + s3.sort_by(|lhs, rhs| replace_whitespace(lhs).cmp(&replace_whitespace(rhs))); + for s in &s3 { + println!("{}", to_display_string(s)); + } + + let mut s4 = vec![ + "cASE INDEPENENT: 3-2".to_string(), + "caSE INDEPENENT: 3-1".to_string(), + "casE INDEPENENT: 3+0".to_string(), + "case INDEPENENT: 3+1".to_string() + ]; + + println!(); + s4.sort_by(|lhs, rhs| to_lower_case(lhs).cmp(&to_lower_case(rhs))); + for s in &s4 { + println!("{}", s); + } + + let mut s5 = vec![ + "foo100bar99baz0.txt".to_string(), + "foo100bar10baz0.txt".to_string(), + "foo1000bar99baz10.txt".to_string(), + "foo1000bar99baz9.txt".to_string() + ]; + + println!(); + s5.sort_by(|lhs, rhs| zero_padding(lhs).cmp(&zero_padding(rhs))); + for s in &s5 { + println!("{}", s); + } + + let mut s6 = vec![ + "The Wind in the Willows".to_string(), + "The 40th step more".to_string(), + "The 39 steps".to_string(), + "Wanda".to_string() + ]; + + println!(); + s6.sort_by(|lhs, rhs| remove_title(lhs).cmp(&remove_title(rhs))); + for s in &s6 { + println!("{}", s); + } + + let mut s7 = vec![ + "Equiv. ý accents: 2-2".to_string(), + "Equiv. Ý accents: 2-1".to_string(), + "Equiv. y accents: 2+0".to_string(), + "Equiv. Y accents: 2+1".to_string() + ]; + + println!(); + s7.sort_by(|lhs, rhs| replace_accents(lhs).cmp(&replace_accents(rhs))); + for s in &s7 { + println!("{}", s); + } + + let mut s8 = vec![ + "IJ ligatured ij".to_string(), + "no ligature".to_string() + ]; + + println!(); + s8.sort_by(|lhs, rhs| replace_ligatures(lhs).cmp(&replace_ligatures(rhs))); + for s in &s8 { + println!("{}", s); + } + + let mut s9 = vec![ + "Start with an ʒ: 2-2".to_string(), + "Start with an ſ: 2-1".to_string(), + "Start with an ß: 2+0".to_string(), + "Start with an s: 2+1".to_string() + ]; + + println!(); + s9.sort_by(|lhs, rhs| replace_characters(lhs).cmp(&replace_characters(rhs))); + for s in &s9 { + println!("{}", s); + } +} diff --git a/Task/Natural-sorting/Zig/natural-sorting.zig b/Task/Natural-sorting/Zig/natural-sorting.zig new file mode 100644 index 0000000000..4157f50f4e --- /dev/null +++ b/Task/Natural-sorting/Zig/natural-sorting.zig @@ -0,0 +1,571 @@ +const std = @import("std"); +const mem = std.mem; +const Allocator = std.mem.Allocator; +const ArrayList = std.ArrayList; + +// Only covers ISO-8859-1 accented characters plus, for consistency, Ÿ +const UC_ACCENTS = [_][]const u8{ "ÀÁÂÃÄÅ", "Ç", "ÈÉÊË", "ÌÍÎÏ", "Ñ", "ÒÓÔÕÖØ", "ÙÚÛÜ", "ÝŸ" }; +const LC_ACCENTS = [_][]const u8{ "àáâãäå", "ç", "èéêë", "ìíîï", "ñ", "òóôõöø", "ùúûü", "ýÿ" }; +const UC_UNACCENTS = [_][]const u8{ "A", "C", "E", "I", "N", "O", "U", "Y" }; +const LC_UNACCENTS = [_][]const u8{ "a", "c", "e", "i", "n", "o", "u", "y" }; + +// Only the more common ligatures +const UC_LIGATURES = [_][]const u8{ "Æ", "IJ", "Œ" }; +const LC_LIGATURES = [_][]const u8{ "æ", "ij", "œ" }; +const UC_SEPARATES = [_][]const u8{ "AE", "IJ", "OE" }; +const LC_SEPARATES = [_][]const u8{ "ae", "ij", "oe" }; + +// Miscellaneous replacements +const MISC_LETTERS = [_][]const u8{ "ß", "ſ", "ʒ" }; +const MISC_REPLACEMENTS = [_][]const u8{ "ss", "s", "s" }; + +// Remove leading spaces +fn leftTrim(allocator: Allocator, text: []const u8) ![]u8 { + var i: usize = 0; + while (i < text.len and text[i] == ' ') : (i += 1) {} + return allocator.dupe(u8, text[i..]); +} + +// Replace multiple spaces with a single space +fn replaceSpaces(allocator: Allocator, text: []const u8) ![]u8 { + var result = ArrayList(u8).init(allocator); + defer result.deinit(); + + var i: usize = 0; + var inSpaces = false; + while (i < text.len) : (i += 1) { + if (text[i] == ' ') { + if (!inSpaces) { + try result.append(' '); + inSpaces = true; + } + } else { + try result.append(text[i]); + inSpaces = false; + } + } + + return result.toOwnedSlice(); +} + +// Replace whitespace with a single space +fn replaceWhitespace(allocator: Allocator, text: []const u8) ![]u8 { + var result = ArrayList(u8).init(allocator); + defer result.deinit(); + + var i: usize = 0; + var inWhitespace = false; + while (i < text.len) : (i += 1) { + if (std.ascii.isWhitespace(text[i])) { + if (!inWhitespace) { + try result.append(' '); + inWhitespace = true; + } + } else { + try result.append(text[i]); + inWhitespace = false; + } + } + + return result.toOwnedSlice(); +} + +// Display strings including whitespace as if the latter were literal characters +fn toDisplayString(allocator: Allocator, text: []const u8) ![]u8 { + const whitespace_1 = [_][]const u8{ "\t", "\n", "\x0B", "\x0C", "\r" }; + const whitespace_2 = [_][]const u8{ "\\t", "\\n", "\\u000b", "\\u000c", "\\r" }; + + var result = ArrayList(u8).init(allocator); + defer result.deinit(); + + var i: usize = 0; + while (i < text.len) : (i += 1) { + var replaced = false; + for (whitespace_1, 0..) |ws, j| { + if (i + ws.len <= text.len and mem.eql(u8, text[i..i+ws.len], ws)) { + try result.appendSlice(whitespace_2[j]); + i += ws.len - 1; + replaced = true; + break; + } + } + + if (!replaced) { + try result.append(text[i]); + } + } + + return result.toOwnedSlice(); +} + +// Transform the string into lower case +fn toLowerCase(allocator: Allocator, text: []const u8) ![]u8 { + var result = try allocator.alloc(u8, text.len); + errdefer allocator.free(result); + + for (text, 0..) |c, i| { + result[i] = std.ascii.toLower(c); + } + + return result; +} + +// Pad each numeric character with leading zeros to a total length of 20 +fn zeroPadding(allocator: Allocator, text: []const u8) ![]u8 { + var result = ArrayList(u8).init(allocator); + defer result.deinit(); + + var i: usize = 0; + while (i < text.len) { + if (std.ascii.isDigit(text[i]) or (text[i] == '-' and i + 1 < text.len and std.ascii.isDigit(text[i+1]))) { + const start = i; + if (text[i] == '-') { + i += 1; + } + while (i < text.len and std.ascii.isDigit(text[i])) : (i += 1) {} + + const numStr = text[start..i]; + const padding = if (numStr.len < 20) 20 - numStr.len else 0; + + for (0..padding) |_| { + try result.append('0'); + } + try result.appendSlice(numStr); + } else { + try result.append(text[i]); + i += 1; + } + } + + return result.toOwnedSlice(); +} + +fn removeTitle(allocator: Allocator, text: []const u8) ![]u8 { + if (text.len >= 4 and mem.eql(u8, text[0..4], "The ")) { + return allocator.dupe(u8, text[4..]); + } else if (text.len >= 3 and mem.eql(u8, text[0..3], "An ")) { + return allocator.dupe(u8, text[3..]); + } else if (text.len >= 2 and mem.eql(u8, text[0..2], "A ")) { + return allocator.dupe(u8, text[2..]); + } else { + return allocator.dupe(u8, text); + } +} + +// Replace accented letters with their unaccented equivalent +fn replaceAccents(allocator: Allocator, text: []const u8) ![]u8 { + var result = ArrayList(u8).init(allocator); + defer result.deinit(); + + var i: usize = 0; + while (i < text.len) { + // Handle UTF-8 characters + var char: [4]u8 = undefined; + var char_len: usize = 0; + + if ((text[i] & 0x80) == 0) { + // ASCII character + try result.append(text[i]); + i += 1; + continue; + } + + // Extract UTF-8 character + if ((text[i] & 0xE0) == 0xC0) { + char_len = 2; + } else if ((text[i] & 0xF0) == 0xE0) { + char_len = 3; + } else if ((text[i] & 0xF8) == 0xF0) { + char_len = 4; + } else { + // Invalid UTF-8, just copy + try result.append(text[i]); + i += 1; + continue; + } + + if (i + char_len > text.len) { + // Incomplete UTF-8 sequence + try result.append(text[i]); + i += 1; + continue; + } + + @memcpy(char[0..char_len], text[i..i+char_len]); + + var replaced = false; + const charSlice = char[0..char_len]; + + for (UC_ACCENTS, 0..) |accents, j| { + if (containsUtf8Char(accents, charSlice)) { + try result.appendSlice(UC_UNACCENTS[j]); + replaced = true; + break; + } + } + + if (!replaced) { + for (LC_ACCENTS, 0..) |accents, j| { + if (containsUtf8Char(accents, charSlice)) { + try result.appendSlice(LC_UNACCENTS[j]); + replaced = true; + break; + } + } + } + + if (!replaced) { + try result.appendSlice(charSlice); + } + + i += char_len; + } + + return result.toOwnedSlice(); +} + +// Helper function to check if a UTF-8 string contains a character +fn containsUtf8Char(haystack: []const u8, needle: []const u8) bool { + var i: usize = 0; + while (i < haystack.len) { + const char_len = utf8CharLen(haystack[i]); + if (i + char_len <= haystack.len and mem.eql(u8, haystack[i..i+char_len], needle)) { + return true; + } + i += char_len; + } + return false; +} + +// Helper function to get UTF-8 character length +fn utf8CharLen(first_byte: u8) usize { + if ((first_byte & 0x80) == 0) return 1; + if ((first_byte & 0xE0) == 0xC0) return 2; + if ((first_byte & 0xF0) == 0xE0) return 3; + if ((first_byte & 0xF8) == 0xF0) return 4; + return 1; // invalid UTF-8, treat as single byte +} + +// Replace ligatures with separated letters +fn replaceLigatures(allocator: Allocator, text: []const u8) ![]u8 { + var result = ArrayList(u8).init(allocator); + defer result.deinit(); + try result.appendSlice(text); + + for (UC_LIGATURES, 0..) |ligature, i| { + var newResult = ArrayList(u8).init(allocator); + defer newResult.deinit(); + + var j: usize = 0; + while (j < result.items.len) { + const char_len = utf8CharLen(result.items[j]); + if (j + char_len <= result.items.len and isUtf8Char(result.items[j..j+char_len], ligature)) { + try newResult.appendSlice(UC_SEPARATES[i]); + j += char_len; + } else { + try newResult.append(result.items[j]); + j += 1; + } + } + + result.clearAndFree(); + try result.appendSlice(newResult.items); + } + + for (LC_LIGATURES, 0..) |ligature, i| { + var newResult = ArrayList(u8).init(allocator); + defer newResult.deinit(); + + var j: usize = 0; + while (j < result.items.len) { + const char_len = utf8CharLen(result.items[j]); + if (j + char_len <= result.items.len and isUtf8Char(result.items[j..j+char_len], ligature)) { + try newResult.appendSlice(LC_SEPARATES[i]); + j += char_len; + } else { + try newResult.append(result.items[j]); + j += 1; + } + } + + result.clearAndFree(); + try result.appendSlice(newResult.items); + } + + return result.toOwnedSlice(); +} + +// Helper function to compare UTF-8 characters +fn isUtf8Char(a: []const u8, b: []const u8) bool { + return mem.eql(u8, a, b); +} + +// Replace miscellaneous letters with their equivalent replacements +fn replaceCharacters(allocator: Allocator, text: []const u8) ![]u8 { + var result = ArrayList(u8).init(allocator); + defer result.deinit(); + try result.appendSlice(text); + + for (MISC_LETTERS, 0..) |letter, i| { + var newResult = ArrayList(u8).init(allocator); + defer newResult.deinit(); + + var j: usize = 0; + while (j < result.items.len) { + const char_len = utf8CharLen(result.items[j]); + if (j + char_len <= result.items.len and isUtf8Char(result.items[j..j+char_len], letter)) { + try newResult.appendSlice(MISC_REPLACEMENTS[i]); + j += char_len; + } else { + try newResult.append(result.items[j]); + j += 1; + } + } + + result.clearAndFree(); + try result.appendSlice(newResult.items); + } + + return result.toOwnedSlice(); +} + +// Custom context for sort comparators +const SortContext = struct { + allocator: Allocator, +}; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + const stdout = std.io.getStdOut().writer(); + try stdout.print("The 9 string lists, sorted 'naturally':\n", .{}); + + var s1 = ArrayList([]const u8).init(allocator); + defer s1.deinit(); + try s1.append("ignore leading spaces: 2-2"); + try s1.append(" ignore leading spaces: 2-1"); + try s1.append(" ignore leading spaces: 2+0"); + try s1.append(" ignore leading spaces: 2+1"); + + try stdout.print("\n", .{}); + + // Sort using leftTrim + const ctx1 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s1.items, ctx1, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = leftTrim(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = leftTrim(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s1.items) |s| { + try stdout.print("{s}\n", .{s}); + } + + var s2 = ArrayList([]const u8).init(allocator); + defer s2.deinit(); + try s2.append("ignore m.a.s spaces: 2-2"); + try s2.append("ignore m.a.s spaces: 2-1"); + try s2.append("ignore m.a.s spaces: 2+0"); + try s2.append("ignore m.a.s spaces: 2+1"); + + try stdout.print("\n", .{}); + + // Sort using replaceSpaces + const ctx2 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s2.items, ctx2, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = replaceSpaces(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = replaceSpaces(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s2.items) |s| { + try stdout.print("{s}\n", .{s}); + } + + var s3 = ArrayList([]const u8).init(allocator); + defer s3.deinit(); + try s3.append("Equiv. spaces: 3-3"); + try s3.append("Equiv.\rspaces: 3-2"); + try s3.append("Equiv.\x0Cspaces: 3-1"); + try s3.append("Equiv.\x0Bspaces: 3+0"); + try s3.append("Equiv.\nspaces: 3+1"); + try s3.append("Equiv.\tspaces: 3+2"); + + try stdout.print("\n", .{}); + + // Sort using replaceWhitespace + const ctx3 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s3.items, ctx3, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = replaceWhitespace(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = replaceWhitespace(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s3.items) |s| { + const displayStr = try toDisplayString(allocator, s); + defer allocator.free(displayStr); + try stdout.print("{s}\n", .{displayStr}); + } + + var s4 = ArrayList([]const u8).init(allocator); + defer s4.deinit(); + try s4.append("cASE INDEPENENT: 3-2"); + try s4.append("caSE INDEPENENT: 3-1"); + try s4.append("casE INDEPENENT: 3+0"); + try s4.append("case INDEPENENT: 3+1"); + + try stdout.print("\n", .{}); + + // Sort using toLowerCase + const ctx4 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s4.items, ctx4, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = toLowerCase(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = toLowerCase(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s4.items) |s| { + try stdout.print("{s}\n", .{s}); + } + + var s5 = ArrayList([]const u8).init(allocator); + defer s5.deinit(); + try s5.append("foo100bar99baz0.txt"); + try s5.append("foo100bar10baz0.txt"); + try s5.append("foo1000bar99baz10.txt"); + try s5.append("foo1000bar99baz9.txt"); + + try stdout.print("\n", .{}); + + // Sort using zeroPadding + const ctx5 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s5.items, ctx5, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = zeroPadding(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = zeroPadding(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s5.items) |s| { + try stdout.print("{s}\n", .{s}); + } + + var s6 = ArrayList([]const u8).init(allocator); + defer s6.deinit(); + try s6.append("The Wind in the Willows"); + try s6.append("The 40th step more"); + try s6.append("The 39 steps"); + try s6.append("Wanda"); + + try stdout.print("\n", .{}); + + // Sort using removeTitle + const ctx6 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s6.items, ctx6, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = removeTitle(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = removeTitle(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s6.items) |s| { + try stdout.print("{s}\n", .{s}); + } + + var s7 = ArrayList([]const u8).init(allocator); + defer s7.deinit(); + try s7.append("Equiv. ý accents: 2-2"); + try s7.append("Equiv. Ý accents: 2-1"); + try s7.append("Equiv. y accents: 2+0"); + try s7.append("Equiv. Y accents: 2+1"); + + try stdout.print("\n", .{}); + + // Sort using replaceAccents + const ctx7 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s7.items, ctx7, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = replaceAccents(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = replaceAccents(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s7.items) |s| { + try stdout.print("{s}\n", .{s}); + } + + var s8 = ArrayList([]const u8).init(allocator); + defer s8.deinit(); + try s8.append("IJ ligatured ij"); + try s8.append("no ligature"); + + try stdout.print("\n", .{}); + + // Sort using replaceLigatures + const ctx8 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s8.items, ctx8, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = replaceLigatures(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = replaceLigatures(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s8.items) |s| { + try stdout.print("{s}\n", .{s}); + } + + var s9 = ArrayList([]const u8).init(allocator); + defer s9.deinit(); + try s9.append("Start with an ʒ: 2-2"); + try s9.append("Start with an ſ: 2-1"); + try s9.append("Start with an ß: 2+0"); + try s9.append("Start with an s: 2+1"); + + try stdout.print("\n", .{}); + + // Sort using replaceCharacters + const ctx9 = SortContext{ .allocator = allocator }; + std.sort.insertion([]const u8, s9.items, ctx9, struct { + fn lessThan(ctx: SortContext, lhs: []const u8, rhs: []const u8) bool { + const l = replaceCharacters(ctx.allocator, lhs) catch return false; + defer ctx.allocator.free(l); + const r = replaceCharacters(ctx.allocator, rhs) catch return false; + defer ctx.allocator.free(r); + return mem.lessThan(u8, l, r); + } + }.lessThan); + + for (s9.items) |s| { + try stdout.print("{s}\n", .{s}); + } +} diff --git a/Task/Negative-base-numbers/EasyLang/negative-base-numbers.easy b/Task/Negative-base-numbers/EasyLang/negative-base-numbers.easy index 84baeb9cc1..6cbd821900 100644 --- a/Task/Negative-base-numbers/EasyLang/negative-base-numbers.easy +++ b/Task/Negative-base-numbers/EasyLang/negative-base-numbers.easy @@ -1,7 +1,5 @@ func$ encode n b . - if n = 0 - return "0" - . + if n = 0 : return "0" while n <> 0 r = n mod b n = n div b @@ -14,16 +12,14 @@ func$ encode n b . return out$ . func decode n$ b . - if n$ = "0" - return 0 - . + if n$ = "0" : return 0 for c$ in strchars n$ c = strcode c$ - 48 tot = tot * b + c . return tot . -proc test n b . . +proc test n b . h$ = encode n b print n & " -> " & h$ & "_" & b & " -> " & decode h$ b . diff --git a/Task/Next-highest-int-from-digits/EasyLang/next-highest-int-from-digits.easy b/Task/Next-highest-int-from-digits/EasyLang/next-highest-int-from-digits.easy index 7044c77896..4f9bb1200a 100644 --- a/Task/Next-highest-int-from-digits/EasyLang/next-highest-int-from-digits.easy +++ b/Task/Next-highest-int-from-digits/EasyLang/next-highest-int-from-digits.easy @@ -1,20 +1,18 @@ -proc reverse i j . dig[] . +proc reverse &dig[] i j . while i < j swap dig[i] dig[j] i += 1 j -= 1 . . -proc next_perm . dig[] . +proc next_perm &dig[] . if len dig[] >= 2 for i = 2 to len dig[] if dig[i] < dig[i - 1] k = 1 - while dig[i] >= dig[k] - k += 1 - . + while dig[i] >= dig[k] : k += 1 swap dig[i] dig[k] - reverse 1 i - 1 dig[] + reverse dig[] 1 i - 1 return . . diff --git a/Task/Non-decimal-radices-Convert/Crystal/non-decimal-radices-convert.cr b/Task/Non-decimal-radices-Convert/Crystal/non-decimal-radices-convert.cr new file mode 100644 index 0000000000..089597edba --- /dev/null +++ b/Task/Non-decimal-radices-Convert/Crystal/non-decimal-radices-convert.cr @@ -0,0 +1,2 @@ +27812426061.to_s(36) # => "crystal" +"code".to_i(28) # => 282618 diff --git a/Task/Non-decimal-radices-Convert/REXX/non-decimal-radices-convert.rexx b/Task/Non-decimal-radices-Convert/REXX/non-decimal-radices-convert.rexx index 47643bb543..fc32acaa42 100644 --- a/Task/Non-decimal-radices-Convert/REXX/non-decimal-radices-convert.rexx +++ b/Task/Non-decimal-radices-Convert/REXX/non-decimal-radices-convert.rexx @@ -1,37 +1,15 @@ -/*REXX program converts integers from one base to another (using bases 2 ──► 90). */ -@abc = 'abcdefghijklmnopqrstuvwxyz' /*lowercase (Latin or English) alphabet*/ -parse upper var @abc @abcU /*uppercase a version of @abc. */ -@@ = 0123456789 || @abc || @abcU /*prefix them with all numeric digits. */ -@@ = @@'<>[]{}()?~!@#$%^&*_=|\/;:¢¬≈' /*add some special characters as well. */ - /* [↑] all characters must be viewable*/ -numeric digits 3000 /*what da hey, support gihugeic numbers*/ -maxB= length(@@) /*max base/radix supported in this code*/ -parse arg x toB inB 1 ox . 1 sigX 2 x2 . /*obtain: three args, origX, sign ··· */ -if pos(sigX, "+-")\==0 then x= x2 /*does X have a leading sign (+ or -) ?*/ - else sigX= /*Nope. No leading sign for the X value*/ -if x=='' then call erm /*if no X number, issue an error msg.*/ -if toB=='' | toB=="," then toB= 10 /*if skipped, assume the default (10). */ -if inB=='' | inB=="," then inB= 10 /* " " " " " " */ -if inB<2 | inB>maxB | \datatype(inB, 'W') then call erb "inBase " inB -if toB<2 | toB>maxB | \datatype(toB, 'W') then call erb "toBase " toB -#=0 /*result of converted X (in base 10).*/ - do j=1 for length(x) /*convert X: base inB ──► base 10. */ - ?= substr(x,j,1) /*pick off a numeral/digit from X. */ - _= pos(?, @@) /*calculate the value of this numeral. */ - if _==0 | _>inB then call erd x /*is _ character an illegal numeral? */ - #= # * inB + _ - 1 /*build a new number, digit by digit. */ - end /*j*/ /* [↑] this also verifies digits. */ -y= /*the value of X in base B. */ - do while # >= toB /*convert #: base 10 ──► base toB.*/ - y= substr(@@, (#//toB) + 1, 1)y /*construct the output number. */ - #= # % toB /* ··· and whittle # down also. */ - end /*while*/ /* [↑] algorithm may leave a residual.*/ - /* [↓] Y is the residual. */ -y= sigX || substr(@@, #+1, 1)y /*prepend the sign if it existed. */ -say ox "(base" inB')' center("is", 20) y '(base' toB")" -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -erb: call ser 'illegal' arg(1)", it must be in the range: 2──►"maxB -erd: call ser 'illegal digit/numeral ['?"] in: " x -erm: call ser 'no argument specified.' -ser: say; say '***error!***'; say arg(1); exit 13 +include Settings + +say 'NON-DECIMAL RADICES - 11 Mar 2025' +say version +say +arg xx +if xx = '' then + xx = 255 +do n = 2 to 36 + say xx 'decimal =' Basenn(xx,n) 'base' n '=' Base10(Basenn(xx,n),n) 'decimal' +end +exit + +include Functions +include Abend diff --git a/Task/Nonoblock/EasyLang/nonoblock.easy b/Task/Nonoblock/EasyLang/nonoblock.easy index 28195b8824..9d0287fcdc 100644 --- a/Task/Nonoblock/EasyLang/nonoblock.easy +++ b/Task/Nonoblock/EasyLang/nonoblock.easy @@ -1,7 +1,5 @@ func$ rep s$ n . - for i to n - r$ &= s$ - . + for i to n : r$ &= s$ return r$ . func$[] genseq ones$[] nzeros . @@ -20,11 +18,9 @@ func$[] genseq ones$[] nzeros . . return r$[] . -proc block data$ le . . +proc block data$ le . a[] = number strchars data$ - for b in a[] - nbytes += b - . + for b in a[] : nbytes += b print "blocks " & a[] & " cells " & le if le - nbytes <= 0 print "No solution" diff --git a/Task/Nonogram-solver/Rust/nonogram-solver.rs b/Task/Nonogram-solver/Rust/nonogram-solver.rs new file mode 100644 index 0000000000..5844bb387f --- /dev/null +++ b/Task/Nonogram-solver/Rust/nonogram-solver.rs @@ -0,0 +1,241 @@ +use std::collections::HashSet; + +// BitSet implementation +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +struct BitSet { + bits: u64, +} + +impl BitSet { + fn empty() -> Self { + BitSet { bits: 0 } + } + + fn value(&self) -> u64 { + self.bits + } + + fn add(&self, item: usize) -> Self { + BitSet { bits: self.bits | (1 << item) } + } + + fn add_range(&self, start: usize, count: usize) -> Self { + let mask = ((1 << (start + count)) - 1) & !((1 << start) - 1); + BitSet { bits: self.bits | mask } + } + + fn contains(&self, item: usize) -> bool { + (self.bits & (1 << item)) != 0 + } + + fn shift_left_at(&self, index: usize) -> Self { + let high_bits = (self.bits >> index) << (index + 1); + let low_bits = self.bits & ((1 << index) - 1); + BitSet { bits: high_bits | low_bits } + } + + fn to_string(&self) -> String { + format!("{:b}", self.bits) + } +} + +impl std::ops::BitAnd for BitSet { + type Output = Self; + + fn bitand(self, rhs: Self) -> Self::Output { + BitSet { bits: self.bits & rhs.bits } + } +} + +impl std::ops::BitOr for BitSet { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + BitSet { bits: self.bits | rhs.bits } + } +} + +fn generate(length: usize, runs: &[usize]) -> Vec { + let mut list = Vec::new(); + let initial = BitSet::empty(); + let mut sums = vec![0; runs.len()]; + + for i in 1..runs.len() { + sums[i] = sums[i - 1] + runs[i - 1] + 1; + } + + let initial = runs.iter().enumerate() + .fold(initial, |acc, (i, &run)| acc.add_range(sums[i], run)); + + let max = BitSet::empty().add(length); + generate_recursive(&mut list, max, runs, &sums, initial, 0, 0); + + list +} + +fn generate_recursive( + result: &mut Vec, + max: BitSet, + runs: &[usize], + sums: &[usize], + mut current: BitSet, + index: usize, + mut shift: usize, +) { + if index == runs.len() { + result.push(current); + return; + } + + while current.value() < max.value() { + generate_recursive(result, max, runs, sums, current, index + 1, shift); + current = current.shift_left_at(sums[index] + shift); + shift += 1; + } +} + +fn reduce(rows: &mut Vec>, columns: &mut Vec>) { + let mut count = 1; + + while count > 0 { + count = 0; + + // Check rows against columns + for row_idx in 0..rows.len() { + let all_on = rows[row_idx].iter().fold(rows[row_idx][0], |acc, &b| acc & b); + let all_off = rows[row_idx].iter().fold(rows[row_idx][0], |acc, &b| acc | b); + + for col_idx in 0..columns.len() { + // Remove column patterns where a cell should be on but isn't + let before_len = columns[col_idx].len(); + columns[col_idx].retain(|c| !(all_on.contains(col_idx) && !c.contains(row_idx))); + count += before_len - columns[col_idx].len(); + + // Remove column patterns where a cell should be off but isn't + let before_len = columns[col_idx].len(); + columns[col_idx].retain(|c| !(!all_off.contains(col_idx) && c.contains(row_idx))); + count += before_len - columns[col_idx].len(); + } + } + + // Check columns against rows + for col_idx in 0..columns.len() { + let all_on = columns[col_idx].iter().fold(columns[col_idx][0], |acc, &b| acc & b); + let all_off = columns[col_idx].iter().fold(columns[col_idx][0], |acc, &b| acc | b); + + for row_idx in 0..rows.len() { + // Remove row patterns where a cell should be on but isn't + let before_len = rows[row_idx].len(); + rows[row_idx].retain(|r| !(all_on.contains(row_idx) && !r.contains(col_idx))); + count += before_len - rows[row_idx].len(); + + // Remove row patterns where a cell should be off but isn't + let before_len = rows[row_idx].len(); + rows[row_idx].retain(|r| !(!all_off.contains(row_idx) && r.contains(col_idx))); + count += before_len - rows[row_idx].len(); + } + } + } +} + +fn solve(row_runs: &[Vec], column_runs: &[Vec]) { + let column_len = column_runs.len(); + let row_len = row_runs.len(); + + let mut rows: Vec> = row_runs.iter() + .map(|row| generate(column_len, row)) + .collect(); + + let mut columns: Vec> = column_runs.iter() + .map(|column| generate(row_len, column)) + .collect(); + + reduce(&mut rows, &mut columns); + + for row in rows { + if row.len() != 1 { + println!("{}", vec!['?'; column_len].into_iter().collect::().chars().intersperse(' ').collect::()); + } else { + let mut s = format!("{:0width$b}", row[0].value(), width = column_len) + .replace('1', "#") + .replace('0', "."); + + // Reverse the string + let s: String = s.chars().rev().collect(); + println!("{}", s.chars().intersperse(' ').collect::()); + } + } +} + +fn parse_runs(input: &str) -> Vec> { + input.split_whitespace() + .map(|s| s.chars().map(|c| (c as u8 - b'A' + 1) as usize).collect()) + .collect() +} + +fn main() { + let test_cases = [ + ("C BA CB BB F AE F A B", "AB CA AE GA E C D C"), + ("F CAC ACAC CN AAA AABB EBB EAA ECCC HCCC", + "D D AE CD AE A DA BBB CC AAB BAA AAB DA AAB AAA BAB AAA CD BBA DA"), + ("CA BDA ACC BD CCAC CBBAC BBBBB BAABAA ABAD AABB BBH BBBD ABBAAA CCEA AACAAB BCACC ACBH DCH ADBE ADBB DBE ECE DAA DB CC", + "BC CAC CBAB BDD CDBDE BEBDF ADCDFA DCCFB DBCFC ABDBA BBF AAF BADB DBF AAAAD BDG CEF CBDB BBB FC"), + ("E BCB BEA BH BEK AABAF ABAC BAA BFB OD JH BADCF Q Q R AN AAN EI H G", + "E CB BAB AAA AAA AC BB ACC ACCA AGB AIA AJ AJ ACE AH BAF CAG DAG FAH FJ GJ ADK ABK BL CM") + ]; + + for (row_letters, column_letters) in test_cases.iter() { + let row_runs = parse_runs(row_letters); + let column_runs = parse_runs(column_letters); + solve(&row_runs, &column_runs); + println!(); + } +} + +// Extension trait to add intersperse functionality +trait Intersperse { + fn intersperse(self, separator: char) -> InterspersedIter + where + Self: Sized + Iterator; +} + +impl Intersperse for I +where + I: Iterator + Sized, +{ + fn intersperse(self, separator: char) -> InterspersedIter { + InterspersedIter { + iter: self, + separator, + need_separator: false, + } + } +} + +struct InterspersedIter { + iter: I, + separator: char, + need_separator: bool, +} + +impl Iterator for InterspersedIter +where + I: Iterator, +{ + type Item = char; + + fn next(&mut self) -> Option { + if self.need_separator { + self.need_separator = false; + return Some(self.separator); + } + + match self.iter.next() { + Some(val) => { + self.need_separator = true; + Some(val) + } + None => None, + } + } +} diff --git a/Task/Nth-root/AppleScript/nth-root.applescript b/Task/Nth-root/AppleScript/nth-root.applescript new file mode 100644 index 0000000000..428a7d2965 --- /dev/null +++ b/Task/Nth-root/AppleScript/nth-root.applescript @@ -0,0 +1,23 @@ +set outPutString to "" +set outPutString to outPutString & nthRoot2(34, 5) & linefeed +set outPutString to outPutString & nthRoot2(42, 10) & linefeed +set outPutString to outPutString & nthRoot2(5, 2) & linefeed + +on nthRoot(x, n) + local n1, y, res, abs + set n1 to n - 1 + set res to x / n + set abs to x + repeat until abs < 1.0E-14 + set y to res + set res to ((n1 * y) + (x / (y ^ n1))) / n + if res > y then + set abs to res - y + else + set abs to y - res + end if + end repeat + set y to res div 1 + if res = y then return y + return res +end nthRoot diff --git a/Task/Nth-root/EasyLang/nth-root.easy b/Task/Nth-root/EasyLang/nth-root.easy index 7cc72ab579..a8c059fb6d 100644 --- a/Task/Nth-root/EasyLang/nth-root.easy +++ b/Task/Nth-root/EasyLang/nth-root.easy @@ -1,8 +1,6 @@ func power x n . r = 1 - for i = 1 to n - r *= x - . + for i = 1 to n : r *= x return r . func nth_root x n . @@ -15,6 +13,8 @@ func nth_root x n . . return r . -numfmt 4 0 +numfmt 0 4 x = power 3.1416 10 print nth_root x 10 +print nth_root 2 2 +print nth_root 81 4 diff --git a/Task/Nth-root/REXX/nth-root.rexx b/Task/Nth-root/REXX/nth-root.rexx index d319e533a9..b1b9cff741 100644 --- a/Task/Nth-root/REXX/nth-root.rexx +++ b/Task/Nth-root/REXX/nth-root.rexx @@ -1,17 +1,22 @@ -/*REXX program calculates the Nth root of X, with DIGS (decimal digits) accuracy. */ +-- 8 May 2025 include Settings -say version; say 'Nth root'; say -parse arg x root digs . /*obtain optional arguments from the CL*/ -if x=='' | x=="," then x= 2 /*Not specified? Then use the default.*/ -if root=='' | root=="," then root= 2 /* " " " " " " */ -if digs=='' | digs=="," then digs=65 /* " " " " " " */ -numeric digits digs /*set the decimal digits to DIGS. */ -say ' x = ' x /*echo the value of X. */ -say ' root = ' root /* " " " " ROOT. */ -say ' digits = ' digs /* " " " " DIGS. */ -say ' answer = ' Nroot(x, root) /*show the value of ANSWER. */ -exit /*stick a fork in it, we're all done. */ +say 'NTH ROOT' +say version +say +parse arg x','root','digs +if x = '' then + x = 2 +if root = '' then + root = 5 +if digs = '' then + digs = 65 +numeric digits digs +say ' x = ' x +say ' root = ' root +say 'digits = ' digs +say 'answer = ' Nroot(x,root) +exit include Numbers include Functions diff --git a/Task/Number-reversal-game/EasyLang/number-reversal-game.easy b/Task/Number-reversal-game/EasyLang/number-reversal-game.easy index c455ae1acd..6de6dde1c1 100644 --- a/Task/Number-reversal-game/EasyLang/number-reversal-game.easy +++ b/Task/Number-reversal-game/EasyLang/number-reversal-game.easy @@ -1,24 +1,20 @@ func sorted s[] . for c in s[] - if c < last - return 0 - . + if c < last : return 0 last = c . return 1 . func$ tostr s[] . - for s in s[] - res$ &= s & " " - . + for s in s[] : res$ &= s & " " return res$ . -proc shuffle . s[] . +proc shuffle &s[] . for i = len s[] downto 2 swap s[i] s[random i] . . -proc reverse n . s[] . +proc reverse n &s[] . for i = 1 to n div 2 swap s[i] s[n - i + 1] . diff --git a/Task/Numbers-which-are-not-the-sum-of-distinct-squares/EasyLang/numbers-which-are-not-the-sum-of-distinct-squares.easy b/Task/Numbers-which-are-not-the-sum-of-distinct-squares/EasyLang/numbers-which-are-not-the-sum-of-distinct-squares.easy index 4c7612257a..fc65581a3b 100644 --- a/Task/Numbers-which-are-not-the-sum-of-distinct-squares/EasyLang/numbers-which-are-not-the-sum-of-distinct-squares.easy +++ b/Task/Numbers-which-are-not-the-sum-of-distinct-squares/EasyLang/numbers-which-are-not-the-sum-of-distinct-squares.easy @@ -2,7 +2,7 @@ maxNumber = 324 len isSum[] maxNumber maxSquare = floor sqrt maxNumber # -proc flagSum currSum sqPos . . +proc flagSum currSum sqPos . nextSum = currSum + sqPos * sqPos if nextSum <= maxNumber isSum[nextSum] = 1 diff --git a/Task/Numbers-with-equal-rises-and-falls/EasyLang/numbers-with-equal-rises-and-falls.easy b/Task/Numbers-with-equal-rises-and-falls/EasyLang/numbers-with-equal-rises-and-falls.easy index 9faf463899..ce815f5bb5 100644 --- a/Task/Numbers-with-equal-rises-and-falls/EasyLang/numbers-with-equal-rises-and-falls.easy +++ b/Task/Numbers-with-equal-rises-and-falls/EasyLang/numbers-with-equal-rises-and-falls.easy @@ -1,7 +1,5 @@ fastfunc risefall n . - if n < 10 - return 1 - . + if n < 10 : return 1 prev = -1 while n > 0 d = n mod 10 @@ -15,21 +13,17 @@ fastfunc risefall n . prev = d n = n div 10 . - if rises = falls - return 1 - . + if rises = falls : return 1 return 0 . -numfmt 0 4 +numfmt 4 0 n = 1 repeat if risefall n = 1 cnt += 1 if cnt <= 200 write n - if cnt mod 10 = 0 - print "" - . + if cnt mod 10 = 0 : print "" . . until cnt = 1e7 diff --git a/Task/Numerical-integration-Gauss-Legendre-Quadrature/REXX/numerical-integration-gauss-legendre-quadrature-2.rexx b/Task/Numerical-integration-Gauss-Legendre-Quadrature/REXX/numerical-integration-gauss-legendre-quadrature-2.rexx index 4027fb164e..55b09726ec 100644 --- a/Task/Numerical-integration-Gauss-Legendre-Quadrature/REXX/numerical-integration-gauss-legendre-quadrature-2.rexx +++ b/Task/Numerical-integration-Gauss-Legendre-Quadrature/REXX/numerical-integration-gauss-legendre-quadrature-2.rexx @@ -1,49 +1,95 @@ -/*REXX program does numerical integration using an N─point Gauss─Legendre quadrature rule. */ -pi= pi(); digs= length(pi) - length(.); numeric digits digs; reps= digs % 2 +-- 9 Jun 2025 +include Settings -!.= .; b= 3; a= -b; bma= b - a; bmaH= bma / 2; tiny= '1e-'digs -trueV= exp(b)-exp(a); bpa= b + a; bpaH= bpa / 2 -hdr= 'iterate value (with ' digs " decimal digits being used)" -say ' step ' center(hdr, digs+3) ' difference' /*show hdr*/ -sep='──────' copies("─", digs+3) '─────────────'; say sep /* " sep*/ +arg digs +if digs = '' then + digs=9 +numeric digits digs - do #=1 until dif>0; p0z= 1; p0.1= 1; p1z= 2; p1.1= 1; p1.2= 0; ##= # + .5; r.= 0 - /*█*/ do k=2 to #; km= k - 1 - /*█*/ do y=1 for p1z; T.y= p1.y; end /*y*/ - /*█*/ T.y= 0; TT.= 0; do L=1 for p0z; _= L + 2; TT._= p0.L; end /*L*/ - /*█*/ kkm= k + km; do j=1 for p1z +1; T.j= (kkm*T.j - km*TT.j)/k; end /*j*/ - /*█*/ p0z= p1z; do n=1 for p0z; p0.n= p1.n ; end /*n*/ - /*█*/ p1z= p1z + 1; do p=1 for p1z; p1.p= T.p ; end /*p*/ - /*█*/ end /*k*/ - /*▓*/ do !=1 for #; x= cos( pi * (! - .25) / ## ) - /*▓*/ /*░*/ do reps until abs(dx) <= tiny - /*▓*/ /*░*/ f= p1.1; df= 0; do u=2 to p1z; df= f + x*df - /*▓*/ /*░*/ f= p1.u +x*f - /*▓*/ /*░*/ end /*u*/ - /*▓*/ /*░*/ dx= f / df; x= x - dx - /*▓*/ /*░*/ end /*reps ···*/ - /*▓*/ r.1.!= x - /*▓*/ r.2.!= 2 / ( (1 - x*x) * df*df) - /*▓*/ end /*!*/ - $= 0 - /*▒*/ do m=1 for #; $=$ + r.2.m * exp(bpaH + r.1.m*bmaH); end /*m*/ - z= bmaH * $ /*calculate target value (Z)*/ - dif= z - trueV; z= format(z, 3, digs - 2) /* " difference. */ - Ndif= translate( format(dif, 3, 4, 2, 0), 'e', "E") - if #\==1 then say center(#, 6) z' ' Ndif /*no display if not computed*/ - end /*#*/ +say 'NUMERICAL INTEGRATION: GAUSS-LEGENDRE QUADRATURE' +say version +say +w=Digits()+2 +say Left('Function',10) Left('Range',w+4) ' N', + Left('Result',w) Left('True',w) Left(' Error',w) +say +call Task 'x**3', 0, 1, 1/4 +call Task '1/x', 1, 100, Ln(100)/1 +call Task 'x', 0, 5000, 12500000 +call Task '4/(x**2+1)', 0, 1, Pi()/1 +call Task 'Sin(x)', 0, 1, -Cos(1)+1 +call Task 'Sin(x)', 0, Pi()/1, 2 +call Task 'Cos(x)', 0, 1, Sin(1) +call Task 'Cos(x)', 0, Pi()/1, 0 +call Task 'Tan(x)', 0, 1, -Ln(Abs(Cos(1))) +call Task 'Tan(x)', 0, Pi()/1, 0 +call Task 'Exp(x)', -3, 3, Exp(3)-Exp(-3) +call Task 'Gamma(x)', 1, 8, 2603.238829328642145 +call Timer +exit -say sep; xdif= compare( strip(z), trueV); say right("↑", 6 + 1 + xdif) -say left('', 6 + 1) trueV " {exact value}"; say -say 'Using ' digs " digit precision, the" , - 'N-point Gauss─Legendre quadrature (GLQ) had an accuracy of ' xdif-2 " digits." -exit 0 /*stick a fork in it, we're all done. */ -/*───────────────────────────────────────────────────────────────────────────────────────────*/ -e: return 2.718281828459045235360287471352662497757247093699959574966967627724076630353547595 -pi: return 3.141592653589793238462643383279502884197169399375105820974944592307816406286286209 -/*───────────────────────────────────────────────────────────────────────────────────────────*/ -cos: procedure expose !.; parse arg x; if !.x\==. then return !.x; _= 1; z=1; y= x*x - do k=2 by 2 until p==z; p=z; _= -_*y/(k*(k-1)); z=z+_; end; !.x=z; return z -/*───────────────────────────────────────────────────────────────────────────────────────────*/ -exp: procedure; parse arg x; ix= x % 1; if abs(x-ix)>.5 then ix= ix + sign(x); x= x-ix; z= 1 - _=1; do j=1 until p==z; p=z; _= _*x/j; z= z+_; end; return z * e()**ix +Task: +procedure expose glob. +arg ff,aa,bb,true +w=Digits()+2 +do nn = 1 to 20 + res=GaussQuad(ff,aa,bb,nn); diff=res-true + say Left(ff,10) Left(aa '-' bb,w+4) Right(nn,2), + Left(Std(res),w) Left(true/1,w) Format(diff,2,4,,0) +end +say +return + +GaussQuad: +procedure expose glob. +-- Gaussion-Legendre quadrature on function f in range a...b taking n points +arg ff,aa,bb,nn +-- Legendre polynomials +p0=1; poly1.1=1; p1=2; poly2.1=1; poly2.2=0 +do i = 2 to nn + work1.0=p1+1 + do j = 1 to p1 + work1.j=poly2.j + end + work1.j=0; work2.0=p0+2; work2.1=0; work2.2=0 + do j = 1 to p0 + j2=j+2; work2.j2=poly1.j + end + do j = 1 to work1.0 + work1.j=((2*i-1)*work1.j-(i-1)*work2.j)/i + end + p0=p1 + do j = 1 to p0 + poly1.j=poly2.j + end + p1=work1.0 + do j = 1 to p1 + poly2.j=work1.j + end +end +-- Roots and weights +eps=1/10**Digits() +root.=0 +do i = 1 to nn + x=Cos(Pi()*(i-0.25)/(nn+0.5)) + do 10 until Abs(dx) < eps + f=poly2.1; df=0 + do k = 2 to p1 + df=f+x*df; f=poly2.k+x*f + end + dx=f/df; x=x-dx + end + root.1.i=x; root.2.i=2/((1-x*x)*df*df) +end +-- Quadrature +bp=0.5*(bb+aa); bm=0.5*(bb-aa); zz=0 +do i = 1 to nn + zz=zz+root.2.i*Eval(ff,bp+root.1.i*bm) +end +return bm*zz + +include Functions +include Special +include Constants +include Helper +include Abend diff --git a/Task/Numerical-integration-Gauss-Legendre-Quadrature/REXX/numerical-integration-gauss-legendre-quadrature-3.rexx b/Task/Numerical-integration-Gauss-Legendre-Quadrature/REXX/numerical-integration-gauss-legendre-quadrature-3.rexx deleted file mode 100644 index 2c9b14bc0a..0000000000 --- a/Task/Numerical-integration-Gauss-Legendre-Quadrature/REXX/numerical-integration-gauss-legendre-quadrature-3.rexx +++ /dev/null @@ -1,51 +0,0 @@ -/*REXX program does numerical integration using an N─point Gauss─Legendre quadrature rule. */ -pi= pi(); digs= length(pi) - length(.); numeric digits digs; reps= digs % 2 -!.= .; b= 3; a= -b; bma= b - a; bmaH= bma / 2; tiny= '1e-'digs -trueV= exp(b)-exp(a); bpa= b + a; bpaH= bpa / 2 -hdr= 'iterate value (with ' digs " decimal digits being used)" -say ' step ' center(hdr, digs+3) ' difference' /*show hdr*/ -sep='──────' copies("─", digs+3) '─────────────'; say sep /* " sep*/ - - do #=1 until dif>0; p0z= 1; p0.1= 1; p1z= 2; p1.1= 1; p1.2= 0; ##= # + .5; r.= 0 - /*█*/ do k=2 to #; km= k - 1 - /*█*/ do y=1 for p1z; T.y= p1.y; end /*y*/ - /*█*/ T.y= 0; TT.= 0; do L=1 for p0z; _= L + 2; TT._= p0.L; end /*L*/ - /*█*/ kkm= k + km; do j=1 for p1z +1; T.j= (kkm*T.j - km*TT.j)/k; end /*j*/ - /*█*/ p0z= p1z; do n=1 for p0z; p0.n= p1.n ; end /*n*/ - /*█*/ p1z= p1z + 1; do p=1 for p1z; p1.p= T.p ; end /*p*/ - /*█*/ end /*k*/ - /*▓*/ do !=1 for #; x= cos( pi * (! - .25) / ## ) - /*▓*/ /*░*/ do reps until abs(dx) <= tiny - /*▓*/ /*░*/ f= p1.1; df= 0; do u=2 to p1z; df= f + x*df - /*▓*/ /*░*/ f= p1.u +x*f - /*▓*/ /*░*/ end /*u*/ - /*▓*/ /*░*/ dx= f / df; x= x - dx - /*▓*/ /*░*/ end /*reps ···*/ - /*▓*/ r.1.!= x - /*▓*/ r.2.!= 2 / ( (1 - x*x) * df*df) - /*▓*/ end /*!*/ - $= 0 - /*▒*/ do m=1 for #; $=$ + r.2.m * exp(bpaH + r.1.m*bmaH); end /*m*/ - z= bmaH * $ /*calculate target value (Z)*/ - dif= z - trueV; z= format(z, 3, digs - 2) /* " difference. */ - Ndif= translate( format(dif, 3, 4, 3, 0), 'e', "E") - if #\==1 then say center(#, 6) z' ' Ndif /*no display if not computed*/ - end /*#*/ - -say sep; xdif= compare( strip(z), trueV); say right("↑", 6 + 1 + xdif) -say left('', 6 + 1) trueV " {exact value}"; say -say 'Using ' digs " digit precision, the" , - 'N-point Gauss─Legendre quadrature (GLQ) had an accuracy of ' xdif-2 " digits." -exit 0 /*stick a fork in it, we're all done. */ -/*───────────────────────────────────────────────────────────────────────────────────────────*/ -e: return 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759, - ||457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794 -/*───────────────────────────────────────────────────────────────────────────────────────────*/ -pi: return 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899, - ||862803482534211706798214808651328230664709384460955058223172535940812848111745028410270194 -/*───────────────────────────────────────────────────────────────────────────────────────────*/ -cos: procedure expose !.; parse arg x; if !.x\==. then return !.x; _= 1; z=1; y= x*x - do k=2 by 2 until p==z; p=z; _= -_*y/(k*(k-1)); z=z+_; end; !.x=z; return z -/*───────────────────────────────────────────────────────────────────────────────────────────*/ -exp: procedure; parse arg x; ix= x % 1; if abs(x-ix)>.5 then ix= ix + sign(x); x= x-ix; z= 1 - _=1; do j=1 until p==z; p=z; _= _*x/j; z= z+_; end; return z * e()**ix diff --git a/Task/Numerical-integration/Julia/numerical-integration.jl b/Task/Numerical-integration/Julia/numerical-integration-1.jl similarity index 100% rename from Task/Numerical-integration/Julia/numerical-integration.jl rename to Task/Numerical-integration/Julia/numerical-integration-1.jl diff --git a/Task/Numerical-integration/Julia/numerical-integration-2.jl b/Task/Numerical-integration/Julia/numerical-integration-2.jl new file mode 100644 index 0000000000..5e60450fc9 --- /dev/null +++ b/Task/Numerical-integration/Julia/numerical-integration-2.jl @@ -0,0 +1,24 @@ +leftrect(f, x, _) = f(x) +midrect(f, x, h) = f(x + h / 2) +rightrect(f, x, h) = f(x + h) +trapezium(f, x, h) = (f(x) + f(x + h)) / 2 +simpson(f, x, h) = (f(x) + 4 * f(x + h / 2) + f(x + h)) / 6 +cube(x) = x * x * x +reciprocal(x) = inv(x) + +function integrate(f, a, b, steps, meth) + h = (b - a) / steps + return h * sum(meth(f, a + i * h, h) for i in 0:steps-1) +end + +for (a, b, steps, fun) in [ + (0, 1, 100, cube), + (1, 100, 1000, reciprocal), + (0, 5000, 5_000_000, identity), + (0, 6000, 6_000_000, identity)] + for rule in [leftrect, midrect, rightrect, trapezium, simpson] + println(string(fun) * " integrated using " * string(rule)) + println(" from $a to $b ($steps steps) = ", + round(integrate(fun, a, b, steps, rule), sigdigits=14)) + end +end diff --git a/Task/Numerical-integration/REXX/numerical-integration.rexx b/Task/Numerical-integration/REXX/numerical-integration.rexx index 05cd99baa8..dcaa344a38 100644 --- a/Task/Numerical-integration/REXX/numerical-integration.rexx +++ b/Task/Numerical-integration/REXX/numerical-integration.rexx @@ -1,48 +1,108 @@ -/*REXX pgm performs numerical integration using 5 different algorithms and show results.*/ -numeric digits 20 /*use twenty decimal digits precision. */ +-- 8 Jun 2025 +include Settings +arg digs +if digs = '' then + digs=9 +numeric digits digs - do test=1 for 4; say /*perform the 4 different test suites. */ - if test==1 then do; L= 0; H= 1; i= 100; end - if test==2 then do; L= 1; H= 100; i= 1000; end - if test==3 then do; L= 0; H= 5000; i= 5000000; end - if test==4 then do; L= 0; H= 6000; i= 6000000; end - say center('test' test, 79, "═") /*display a header for the test suite. */ - say ' left rectangular('L", "H', 'i") ──► " left_rect(L, H, i) - say ' midpoint rectangular('L", "H', 'i") ──► " midpoint_rect(L, H, i) - say ' right rectangular('L", "H', 'i") ──► " right_rect(L, H, i) - say ' Simpson('L", "H', 'i") ──► " Simpson(L, H, i) - say ' trapezium('L", "H', 'i") ──► " trapezium(L, H, i) - end /*test*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -f: parse arg y; if test>2 then return y /*choose the "as─is" function. */ - if test==1 then return y**3 /* " " cube function. */ - return 1/y /* " " reciprocal " */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -left_rect: procedure expose test; parse arg a,b,#; $= 0; h= (b-a)/# - do x=a by h for #; $= $ + f(x) - end /*x*/ - return $*h/1 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -midpoint_rect: procedure expose test; parse arg a,b,#; $= 0; h= (b-a)/# - do x=a+h/2 by h for #; $= $ + f(x) - end /*x*/ - return $*h/1 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -right_rect: procedure expose test; parse arg a,b,#; $= 0; h= (b-a)/# - do x=a+h by h for #; $= $ + f(x) - end /*x*/ - return $*h/1 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Simpson: procedure expose test; parse arg a,b,#; h= (b-a)/# - hh= h/2; $= f(a + hh) - @= 0; do x=1 for #-1; hx=h*x + a; @= @ + f(hx) - $= $ + f(hx + hh) - end /*x*/ +say 'NUMERICAL INTEGRATION: COMPARE 5 METHODS' +say version +say +w=Digits()+2 +say Left('Function',11) Left( 'Range',w+4) Left('Method',9) Left( 'Steps',7), + Left('Result',w) Left('True',w) ' Error' +say +call Task 'x**3', 0, 1, 100, 1/4 +call Task '1/x', 1, 100, 1000, Ln(100)/1 +call Task 'x', 0, 5000, 1000000, 12500000 +call Task 'x', 0, 5000, 4, 12500000 +call Task '4/(x**2+1)', 0, 1, 100, Pi()/1 +call Task '4/(x**2+1)', 0, 1, 1000, Pi()/1 +call Task 'Sin(x)', 0, Pi()/1, 100, 2 +call Task 'Sin(x)', 0, Pi()/1, 10000, 2 +call Task 'Cos(x)', 0, Pi()/1, 100, 0 +call Task 'Cos(x)', 0, Pi()/1, 10000, 0 +call Task 'Tan(x)', 0, Pi()/1, 100, 0 +call Task 'Tan(x)', 0, Pi()/1, 10000, 0 +call Task 'Exp(x)', -3, 3, 100, Exp(3)-Exp(-3) +call Task 'Exp(x)', -3, 3, 10000, Exp(3)-Exp(-3) +call Task 'Gamma(x)', 1, 8, 100, 2603.238829328642145 +call Task 'Gamma(x)', 1, 8, 10000, 2603.238829328642145 +call Timer +exit - return h * (f(a) + f(b) + 4*$ + 2*@) / 6 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -trapezium: procedure expose test; parse arg a,b,#; $= 0; h= (b-a)/# - do x=a by h for #; $= $ + (f(x) + f(x+h)) - end /*x*/ - return $*h/2 +Task: +procedure expose glob. +arg ff,aa,bb,steps,true +w=Digits()+2 +res=LeftRect(ff,aa,bb,steps); diff=res-true +say Left(ff,11) Left(aa '-' bb,w+4) Left('LeftRect',9) Left(steps,7), + Left(Std(res),w) Left(true,w) Format(diff,2,4,,0) +res=MidRect(ff,aa,bb,steps); diff=res-true +say Left(ff,11) Left(aa '-' bb,w+4) Left('MidRect',9) Left(steps,7), + Left(Std(res),w) Left(true,w) Format(diff,2,4,,0) +res=RightRect(ff,aa,bb,steps); diff=res-true +say Left(ff,11) Left(aa '-' bb,w+4) Left('RightRect',9) Left(steps,7), + Left(Std(res),w) Left(true,w) Format(diff,2,4,,0) +res=Trapezoid(ff,aa,bb,steps); diff=res-true +say Left(ff,11) Left(aa '-' bb,w+4) Left('Trapezoid',9) Left(steps,7), + Left(Std(res),w) Left(true,w) Format(diff,2,4,,0) +res=Simpson(ff,aa,bb,steps); diff=res-true +say Left(ff,11) Left(aa '-' bb,w+4) Left('Simpson',9) Left(steps,7), + Left(Std(res),w) Left(true,w) Format(diff,2,4,,0) +say +return + +LeftRect: +procedure expose glob. +arg ff,aa,bb,steps +h=(bb-aa)/steps; s=0 +do n = 0 to steps-1 + s=s+Eval(ff,aa+n*h) +end +return s*h + +MidRect: +procedure expose glob. +arg ff,aa,bb,steps +h=(bb-aa)/steps; s=0; aa=aa-h/2 +do n = 1 to steps + s=s+Eval(ff,aa+n*h) +end +return s*h + +RightRect: +procedure expose glob. +arg ff,aa,bb,steps +h=(bb-aa)/steps; s=0 +do n = 1 to steps + s=s+Eval(ff,aa+n*h) +end +return s*h + +Trapezoid: +procedure expose glob. +arg ff,aa,bb,steps +h=(bb-aa)/steps; s=0.5*(Eval(ff,aa)+Eval(ff,bb)) +do n = 1 to steps-1 + s=s+Eval(ff,aa+n*h) +end +return s*h + +Simpson: +procedure expose glob. +arg ff,aa,bb,steps +h=(bb-aa)/steps; s=Eval(ff,aa)+Eval(ff,bb) +do n = 1 by 2 to steps-1 + s=s+4*Eval(ff,aa+n*h) +end +do n = 2 by 2 to steps-1 + s=s+2*Eval(ff,aa+n*h) +end +return s*h/3 + +include Functions +include Special +include Constants +include Helper +include Abend diff --git a/Task/Odd-word-problem/EasyLang/odd-word-problem.easy b/Task/Odd-word-problem/EasyLang/odd-word-problem.easy index 23f334b2fb..0dd0bab09e 100644 --- a/Task/Odd-word-problem/EasyLang/odd-word-problem.easy +++ b/Task/Odd-word-problem/EasyLang/odd-word-problem.easy @@ -4,16 +4,12 @@ func$ read . return substr inp$ inpi 1 . func ispunct c$ . - if c$ = "." or c$ = ":" or c$ = ";" or c$ = "," - return 1 - . + if c$ = "." or c$ = ":" or c$ = ";" or c$ = "," : return 1 return 0 . func$ handle odd . c$ = read - if ispunct c$ = 1 - return c$ - . + if ispunct c$ = 1 : return c$ if odd = 0 write c$ r$ = handle 0 @@ -24,7 +20,7 @@ func$ handle odd . return r$ . . -proc go . . +proc go . repeat c$ = handle odd write c$ diff --git a/Task/Old-Russian-measure-of-length/R/old-russian-measure-of-length.r b/Task/Old-Russian-measure-of-length/R/old-russian-measure-of-length.r new file mode 100644 index 0000000000..d22b8c0b1d --- /dev/null +++ b/Task/Old-Russian-measure-of-length/R/old-russian-measure-of-length.r @@ -0,0 +1,28 @@ +#Create a vector containing the value of each Russian unit in metres +russian_units <- c(1066.8, 2.1336, 0.7112, 0.04445) +names(russian_units) <- c("verst", "sazhen", "arshin", "vershok") + +#Expand this vector to a matrix with one column each for values in km, m, and cm +metric_expand <- function(x){ + return(cbind(x/1000, x, x*100)) +} + +conv_matrix <- metric_expand(russian_units) +colnames(conv_matrix) <- c("km", "m", "cm") + +#This function displays values in all units other than the one that is input +convert_units <- function(value, unit){ + if(unit %in% rownames(conv_matrix)){ + conv_metric <- conv_matrix[unit,] + conv_russian <- conv_matrix[unit,2]/conv_matrix[-which(rownames(conv_matrix)==unit),2] + } + else if(unit %in% colnames(conv_matrix)){ + conv_metric <- conv_matrix[2,-which(colnames(conv_matrix)==unit)]/conv_matrix[2,unit] + conv_russian <- 1/conv_matrix[,unit] + } + return(value*c(conv_metric, conv_russian)) +} + +#Test inputs +convert_units(1, "m") +convert_units(1, "arshin") diff --git a/Task/One-dimensional-cellular-automata/EasyLang/one-dimensional-cellular-automata.easy b/Task/One-dimensional-cellular-automata/EasyLang/one-dimensional-cellular-automata.easy index a5e70f7c97..536f269645 100644 --- a/Task/One-dimensional-cellular-automata/EasyLang/one-dimensional-cellular-automata.easy +++ b/Task/One-dimensional-cellular-automata/EasyLang/one-dimensional-cellular-automata.easy @@ -1,14 +1,14 @@ map[] = [ 0 0 0 1 0 1 1 0 ] cell[] = [ 0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 ] len celln[] len cell[] -proc evolve . . +proc evolve . for i = 2 to len cell[] - 1 ind = cell[i - 1] + 2 * cell[i] + 4 * cell[i + 1] + 1 celln[i] = map[ind] . swap celln[] cell[] . -proc show . . +proc show . for v in cell[] if v = 1 write "#" diff --git a/Task/OpenWebNet-password/EasyLang/openwebnet-password.easy b/Task/OpenWebNet-password/EasyLang/openwebnet-password.easy index 57f6c46a31..8b5f5f0ed5 100644 --- a/Task/OpenWebNet-password/EasyLang/openwebnet-password.easy +++ b/Task/OpenWebNet-password/EasyLang/openwebnet-password.easy @@ -3,9 +3,7 @@ func calcpass passw$ nonce$ . passw = number passw$ for c$ in strchars nonce$ if c$ <> "0" - if start = 1 - num2 = passw - . + if start = 1 : num2 = passw start = 0 . if c$ = "1" @@ -43,11 +41,11 @@ func calcpass passw$ nonce$ . if c$ <> "0" and c$ <> "9" num1 = bitor num1 num2 . - num2 = num1 + num2 = bitand 0xffffffff num1 . - return num1 + return bitand 0xffffffff num1 . -proc test_passwd passwd$ nonce$ expected$ . . +proc test_passwd passwd$ nonce$ expected$ . res = calcpass passwd$ nonce$ m$ = passwd$ & " " & nonce$ & " " & res & " " & expected$ if res = number expected$ diff --git a/Task/OpenWebNet-password/Rust/openwebnet-password.rs b/Task/OpenWebNet-password/Rust/openwebnet-password.rs new file mode 100644 index 0000000000..40e6b5a6e0 --- /dev/null +++ b/Task/OpenWebNet-password/Rust/openwebnet-password.rs @@ -0,0 +1,113 @@ +fn own_password_calculation(password: i64, nonce: &str) -> i64 { + const M1: i64 = 0xFFFF_FFFF; + const M8: i64 = 0xFFFF_FFF8; + const M16: i64 = 0xFFFF_FFF0; + const M128: i64 = 0xFFFF_FF80; + const M16777216: i64 = 0xFF00_0000; + + let mut flag = true; + let mut number1 = 0; + let mut number2 = 0; + + for ch in nonce.chars() { + number2 = number2 & M1; + + match ch { + '1' => { + if flag { number2 = password; } + flag = false; + number1 = number2 & M128; + number1 = number1 >> 7; + number2 = number2 << 25; + number1 = number1 + number2; + }, + + '2' => { + if flag { number2 = password; } + flag = false; + number1 = number2 & M16; + number1 = number1 >> 4; + number2 = number2 << 28; + number1 = number1 + number2; + }, + + '3' => { + if flag { number2 = password; } + flag = false; + number1 = number2 & M8; + number1 = number1 >> 3; + number2 = number2 << 29; + number1 = number1 + number2; + }, + + '4' => { + if flag { number2 = password; } + flag = false; + number1 = number2 << 1; + number2 = number2 >> 31; + number1 = number1 + number2; + }, + + '5' => { + if flag { number2 = password; } + flag = false; + number1 = number2 << 5; + number2 = number2 >> 27; + number1 = number1 + number2; + }, + + '6' => { + if flag { number2 = password; } + flag = false; + number1 = number2 << 12; + number2 = number2 >> 20; + number1 = number1 + number2; + }, + + '7' => { + if flag { number2 = password; } + flag = false; + number1 = number2 & 0xFF00; + number1 = number1 + ((number2 & 0xFF) << 24); + number1 = number1 + ((number2 & 0xFF0000) >> 16); + number2 = (number2 & M16777216) >> 8; + number1 = number1 + number2; + }, + + '8' => { + if flag { number2 = password; } + flag = false; + number1 = number2 & 0xFFFF; + number1 = number1 << 16; + number1 = number1 + (number2 >> 24); + number2 = number2 & 0xFF0000; + number2 = number2 >> 8; + number1 = number1 + number2; + }, + + '9' => { + if flag { number2 = password; } + flag = false; + number1 = !number2; + }, + + _ => { + number1 = number2; + }, + } + number2 = number1; + } + + return number1 & M1; +} + +fn own_password_calculation_test(password: &str, nonce: &str, expected: i64) { + let result = own_password_calculation(password.parse::().unwrap(), nonce); + let message = format!("{} {} {} {}", password, nonce, result, expected); + println!("{} {}", if result == expected { "PASS" } else { "FAIL" }, message); +} + +fn main() { + own_password_calculation_test("12345", "603356072", 25280520); + own_password_calculation_test("12345", "410501656", 119537670); +} diff --git a/Task/Order-by-pair-comparisons/Crystal/order-by-pair-comparisons.cr b/Task/Order-by-pair-comparisons/Crystal/order-by-pair-comparisons.cr new file mode 100644 index 0000000000..b567cbb22d --- /dev/null +++ b/Task/Order-by-pair-comparisons/Crystal/order-by-pair-comparisons.cr @@ -0,0 +1,17 @@ +class Array + def sort_with_prompt + rels = { "<" => -1, "=" => 0, ">" => 1 } + n = 0 + puts "Answer with <, = or >" + sort {|a, b| + n += 1 + loop do + print "#{n}) #{a} < = > #{b} ?: " + ans = gets + break rels[ans] if ans.in?(rels.keys) + end + } + end +end + +p %w(violet red green indigo blue yellow orange).sort_with_prompt diff --git a/Task/Order-by-pair-comparisons/EasyLang/order-by-pair-comparisons.easy b/Task/Order-by-pair-comparisons/EasyLang/order-by-pair-comparisons.easy index aa9e793980..91e9a254d2 100644 --- a/Task/Order-by-pair-comparisons/EasyLang/order-by-pair-comparisons.easy +++ b/Task/Order-by-pair-comparisons/EasyLang/order-by-pair-comparisons.easy @@ -1,4 +1,4 @@ -proc insort item$ . arr$[] . +proc insort item$ &arr$[] . mid = 1 lo = 0 hi = len arr$[] + 1 diff --git a/Task/Order-two-numerical-lists/Crystal/order-two-numerical-lists.cr b/Task/Order-two-numerical-lists/Crystal/order-two-numerical-lists.cr new file mode 100644 index 0000000000..a7d1778620 --- /dev/null +++ b/Task/Order-two-numerical-lists/Crystal/order-two-numerical-lists.cr @@ -0,0 +1,2 @@ +p [1,2,1,3,2] < [1,2,0,4,4,0,0,0] # => false +p [1,2,1,3,2] > [1,2,0,4,4,0,0,0] # => true diff --git a/Task/Ormiston-triples/EasyLang/ormiston-triples.easy b/Task/Ormiston-triples/EasyLang/ormiston-triples.easy index 7860840f0f..6b0da9fba9 100644 --- a/Task/Ormiston-triples/EasyLang/ormiston-triples.easy +++ b/Task/Ormiston-triples/EasyLang/ormiston-triples.easy @@ -1,16 +1,10 @@ fastfunc isprim num . - if num mod 3 = 0 - return 0 - . + if num mod 3 = 0 : return 0 i = 5 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 4 . return 1 @@ -42,9 +36,7 @@ repeat da = digs a if da = db and da = dc cnt += 1 - if cnt <= 25 - write c & " " - . + if cnt <= 25 : write c & " " . . print "" diff --git a/Task/P-Adic-numbers-basic/00-TASK.txt b/Task/P-Adic-numbers-basic/00-TASK.txt index f45bc5d663..25139e9545 100644 --- a/Task/P-Adic-numbers-basic/00-TASK.txt +++ b/Task/P-Adic-numbers-basic/00-TASK.txt @@ -47,4 +47,3 @@ set the shortest prime-exponent combinations that allow valid reconstruction. __TOC__ - diff --git a/Task/P-Adic-numbers-basic/C-sharp/p-adic-numbers-basic.cs b/Task/P-Adic-numbers-basic/C-sharp/p-adic-numbers-basic.cs new file mode 100644 index 0000000000..1909a50638 --- /dev/null +++ b/Task/P-Adic-numbers-basic/C-sharp/p-adic-numbers-basic.cs @@ -0,0 +1,402 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public static class PAdicNumbersBasic +{ + public static void Main(string[] args) + { + Console.WriteLine("3-adic numbers:"); + Padic padicOne = new Padic(3, -5, 9); + Console.WriteLine("-5 / 9 => " + padicOne); + Padic padicTwo = new Padic(3, 47, 12); + Console.WriteLine("47 / 12 => " + padicTwo); + + Padic sum = padicOne.Add(padicTwo); + Console.WriteLine("sum => " + sum); + Console.WriteLine("Rational = " + sum.ConvertToRational()); + Console.WriteLine(); + + Console.WriteLine("7-adic numbers:"); + padicOne = new Padic(7, 5, 8); + Console.WriteLine("5 / 8 => " + padicOne); + padicTwo = new Padic(7, 353, 30809); + Console.WriteLine("353 / 30809 => " + padicTwo); + + sum = padicOne.Add(padicTwo); + Console.WriteLine("sum => " + sum); + Console.WriteLine("Rational = " + sum.ConvertToRational()); + } +} + +public sealed class Padic +{ + /** + * Create a p-adic, with p = aPrime, from the given rational 'aNumerator' / 'aDenominator'. + */ + public Padic(int aPrime, int aNumerator, int aDenominator) + { + if (aDenominator == 0) + { + throw new ArgumentException("Denominator cannot be zero"); + } + + prime = aPrime; + digits = new List(DIGITS_SIZE); + order = 0; + + // Process rational zero + if (aNumerator == 0) + { + order = MAX_ORDER; + return; + } + + // Remove multiples of 'prime' and adjust the order of the p-adic number accordingly + while (FloorMod(aNumerator, prime) == 0) + { + aNumerator /= prime; + order += 1; + } + + while (FloorMod(aDenominator, prime) == 0) + { + aDenominator /= prime; + order -= 1; + } + + // Standard calculation of p-adic digits + long inverse = ModuloInverse(aDenominator); + while (digits.Count < DIGITS_SIZE) + { + int digit = FloorMod((int)(aNumerator * inverse), prime); + digits.Add(digit); + + aNumerator -= digit * aDenominator; + + if (aNumerator != 0) + { + // The denominator is not a power of a prime + int count = 0; + while (FloorMod(aNumerator, prime) == 0) + { + aNumerator /= prime; + count += 1; + } + + for (int i = count; i > 1; i--) + { + digits.Add(0); + } + } + } + } + + /** + * Return the sum of this p-adic number and the given p-adic number. + */ + public Padic Add(Padic aOther) + { + if (prime != aOther.prime) + { + throw new ArgumentException("Cannot add p-adic's with different primes"); + } + + List result = new List(); + + // Adjust the digits so that the p-adic points are aligned + for (int i = 0; i < -order + aOther.order; i++) + { + aOther.digits.Insert(0, 0); + } + + for (int i = 0; i < -aOther.order + order; i++) + { + digits.Insert(0, 0); + } + + // Standard digit by digit addition + int carry = 0; + for (int i = 0; i < Math.Min(digits.Count, aOther.digits.Count); i++) + { + int sum = digits[i] + aOther.digits[i] + carry; + int remainder = FloorMod(sum, prime); + carry = (sum >= prime) ? 1 : 0; + result.Add(remainder); + } + + // Reverse the changes made to the digits + for (int i = 0; i < -order + aOther.order; i++) + { + aOther.digits.RemoveAt(0); + } + + for (int i = 0; i < -aOther.order + order; i++) + { + digits.RemoveAt(0); + } + + return new Padic(prime, result, AllZeroDigits(result) ? MAX_ORDER : Math.Min(order, aOther.order)); + } + + /** + * Return the Rational representation of this p-adic number. + */ + public Rational ConvertToRational() + { + List numbers = new List(digits); + + // Zero + if (numbers.Count == 0 || AllZeroDigits(numbers)) + { + return new Rational(0, 1); + } + + // Positive integer + if (order >= 0 && EndsWith(numbers, 0)) + { + for (int i = 0; i < order; i++) + { + numbers.Insert(0, 0); + } + + return new Rational(ConvertToDecimal(numbers), 1); + } + + // Negative integer + if (order >= 0 && EndsWith(numbers, prime - 1)) + { + NegateList(numbers); + for (int i = 0; i < order; i++) + { + numbers.Insert(0, 0); + } + + return new Rational(-ConvertToDecimal(numbers), 1); + } + + // Rational + Padic sum = new Padic(prime, new List(digits), order); + Padic self = new Padic(prime, new List(digits), order); + int denominator = 1; + do + { + sum = sum.Add(self); + denominator += 1; + } while (!(EndsWith(sum.digits, 0) || EndsWith(sum.digits, prime - 1))); + + bool negative = EndsWith(sum.digits, prime - 1); + if (negative) + { + NegateList(sum.digits); + } + + int numerator = negative ? -ConvertToDecimal(sum.digits) : ConvertToDecimal(sum.digits); + + if (order > 0) + { + numerator *= (int)Math.Pow(prime, order); + } + + if (order < 0) + { + denominator *= (int)Math.Pow(prime, -order); + } + + return new Rational(numerator, denominator); + } + + /** + * Return a string representation of this p-adic. + */ + public override string ToString() + { + List numbers = new List(digits); + PadWithZeros(numbers); + numbers.Reverse(); + string numberString = string.Join("", numbers.Select(n => n.ToString())); + StringBuilder builder = new StringBuilder(numberString); + + if (order >= 0) + { + for (int i = 0; i < order; i++) + { + builder.Append("0"); + } + + builder.Append(".0"); + } + else + { + builder.Insert(builder.Length + order, "."); + + while (builder.ToString().EndsWith("0")) + { + builder.Remove(builder.Length - 1, 1); + } + } + + return " ..." + builder.ToString().Substring(builder.Length - PRECISION - 1); + } + + // PRIVATE // + + /** + * Create a p-adic, with p = 'aPrime', directly from a list of digits. + * + * With 'aOrder' = 0, the list [1, 2, 3, 4, 5] creates the p-adic ...54321.0 + * 'aOrder' > 0 shifts the list 'aOrder' places to the left and + * 'aOrder' < 0 shifts the list 'aOrder' places to the right. + */ + private Padic(int aPrime, List aDigits, int aOrder) + { + prime = aPrime; + digits = new List(aDigits); + order = aOrder; + } + + /** + * Return the multiplicative inverse of the given decimal number modulo 'prime'. + */ + private int ModuloInverse(int aNumber) + { + int inverse = 1; + while (FloorMod(inverse * aNumber, prime) != 1) + { + inverse += 1; + } + + return inverse; + } + + /** + * Transform the given list of digits representing a p-adic number + * into a list which represents the negation of the p-adic number. + */ + private void NegateList(List aDigits) + { + aDigits[0] = FloorMod(prime - aDigits[0], prime); + for (int i = 1; i < aDigits.Count; i++) + { + aDigits[i] = prime - 1 - aDigits[i]; + } + } + + /** + * Return the given list of base 'prime' integers converted to a decimal integer. + */ + private int ConvertToDecimal(List aNumbers) + { + int decimal_value = 0; + int multiple = 1; + foreach (int number in aNumbers) + { + decimal_value += number * multiple; + multiple *= prime; + } + + return decimal_value; + } + + /** + * Return whether the given list consists of all zeros. + */ + private static bool AllZeroDigits(List aList) + { + return aList.All(i => i == 0); + } + + /** + * The given list is padded on the right by zeros up to a maximum length of 'PRECISION'. + */ + private static void PadWithZeros(List aList) + { + while (aList.Count < DIGITS_SIZE) + { + aList.Add(0); + } + } + + /** + * Return whether the given list ends with multiple instances of the given number. + */ + private static bool EndsWith(List aDigits, int aDigit) + { + for (int i = aDigits.Count - 1; i >= aDigits.Count - PRECISION / 2; i--) + { + if (aDigits[i] != aDigit) + { + return false; + } + } + + return true; + } + + /** + * C# implementation of Java's Math.floorMod + */ + private static int FloorMod(int x, int y) + { + int r = x % y; + // If the signs are different and modulo not zero, adjust result + if ((x ^ y) < 0 && r != 0) + { + r += y; + } + return r; + } + + public class Rational + { + private int numerator; + private int denominator; + + public Rational(int aNumerator, int aDenominator) + { + if (aDenominator < 0) + { + numerator = -aNumerator; + denominator = -aDenominator; + } + else + { + numerator = aNumerator; + denominator = aDenominator; + } + + if (aNumerator == 0) + { + denominator = 1; + } + + int gcd = GCD(numerator, denominator); + numerator /= gcd; + denominator /= gcd; + } + + public override string ToString() + { + return numerator + " / " + denominator; + } + + private int GCD(int aOne, int aTwo) + { + if (aTwo == 0) + { + return Math.Abs(aOne); + } + return GCD(aTwo, FloorMod(aOne, aTwo)); + } + } + + private List digits; + private int order; + + private readonly int prime; + + private const int MAX_ORDER = 1000; + private const int PRECISION = 40; + private const int DIGITS_SIZE = PRECISION + 5; +} diff --git a/Task/P-Adic-numbers-basic/JavaScript/p-adic-numbers-basic.js b/Task/P-Adic-numbers-basic/JavaScript/p-adic-numbers-basic.js new file mode 100644 index 0000000000..c1291de454 --- /dev/null +++ b/Task/P-Adic-numbers-basic/JavaScript/p-adic-numbers-basic.js @@ -0,0 +1,310 @@ +// Rational class for rational number representation +class Rational { + constructor(numerator, denominator) { + if (denominator < 0) { + this.numerator = -numerator; + this.denominator = -denominator; + } else { + this.numerator = numerator; + this.denominator = denominator; + } + + if (numerator === 0) { + this.denominator = 1; + } + + const divisor = this.gcd(Math.abs(this.numerator), this.denominator); + this.numerator = Math.floor(this.numerator / divisor); + this.denominator = Math.floor(this.denominator / divisor); + } + + gcd(a, b) { + while (b !== 0) { + const temp = b; + b = a % b; + a = temp; + } + return a; + } + + toString() { + return `${this.numerator} / ${this.denominator}`; + } +} + +// P_adic class for p-adic number representation +class P_adic { + static PRECISION = 40; + static ORDER_MAX = 1000; + static DIGITS_SIZE = P_adic.PRECISION + 5; + + // Create a P_adic number with p = 'prime', from the given rational 'numerator' / 'denominator' + constructor(prime, numerator, denominator, digits = null, order = null) { + this.prime = prime; + + // If digits and order are provided, use them directly (for internal use) + if (digits !== null && order !== null) { + this.digits = digits; + this.order = order; + return; + } + + if (denominator === 0) { + throw new Error("Denominator cannot be zero"); + } + + this.order = 0; + + // Process rational zero + if (numerator === 0) { + this.digits = Array(P_adic.DIGITS_SIZE).fill(0); + this.order = P_adic.ORDER_MAX; + return; + } + + // Remove multiples of 'prime' and adjust the order of the P_adic number accordingly + while (this.moduloPrime(numerator) === 0) { + numerator = Math.floor(numerator / prime); + this.order += 1; + } + + while (this.moduloPrime(denominator) === 0) { + denominator = Math.floor(denominator / prime); + this.order -= 1; + } + + // Standard calculation of P_adic digits + const inverse = this.moduloInverse(denominator); + this.digits = []; + + while (this.digits.length < P_adic.DIGITS_SIZE) { + const digit = this.moduloPrime(numerator * inverse); + this.digits.push(digit); + + numerator -= digit * denominator; + + if (numerator !== 0) { + // The denominator is not a power of a prime + let count = 0; + while (this.moduloPrime(numerator) === 0) { + numerator = Math.floor(numerator / prime); + count += 1; + } + + for (let i = count; i > 1; --i) { + this.digits.push(0); + } + } + } + } + + // Return the sum of this P_adic number with the given P_adic number + add(other) { + if (this.prime !== other.prime) { + throw new Error("Cannot add p-adic's with different primes"); + } + + let this_digits = [...this.digits]; + let other_digits = [...other.digits]; + let result = []; + + // Adjust the digits so that the P_adic points are aligned + for (let i = 0; i < -this.order + other.order; ++i) { + other_digits.unshift(0); + } + + for (let i = 0; i < -other.order + this.order; ++i) { + this_digits.unshift(0); + } + + // Standard digit by digit addition + let carry = 0; + for (let i = 0; i < Math.min(this_digits.length, other_digits.length); ++i) { + const sum = this_digits[i] + other_digits[i] + carry; + const remainder = sum % this.prime; + carry = (sum >= this.prime) ? 1 : 0; + result.push(remainder); + } + + return new P_adic( + this.prime, + null, + null, + result, + this.allZeroDigits(result) ? P_adic.ORDER_MAX : Math.min(this.order, other.order) + ); + } + + // Return the Rational representation of this P_adic number + convertToRational() { + let numbers = [...this.digits]; + + // Zero + if (numbers.length === 0 || this.allZeroDigits(numbers)) { + return new Rational(0, 1); + } + + // Positive integer + if (this.order >= 0 && this.endsWith(numbers, 0)) { + for (let i = 0; i < this.order; ++i) { + numbers.unshift(0); + } + + return new Rational(this.convertToDecimal(numbers), 1); + } + + // Negative integer + if (this.order >= 0 && this.endsWith(numbers, this.prime - 1)) { + this.negateDigits(numbers); + for (let i = 0; i < this.order; ++i) { + numbers.unshift(0); + } + + return new Rational(-this.convertToDecimal(numbers), 1); + } + + // Rational + const copy = new P_adic(this.prime, null, null, [...this.digits], this.order); + let sum = new P_adic(this.prime, null, null, [...this.digits], this.order); + let denominator = 1; + + do { + sum = sum.add(copy); + denominator += 1; + } while (!(this.endsWith(sum.digits, 0) || this.endsWith(sum.digits, this.prime - 1))); + + const negative = this.endsWith(sum.digits, this.prime - 1); + if (negative) { + this.negateDigits(sum.digits); + } + + let numerator = negative ? -this.convertToDecimal(sum.digits) : this.convertToDecimal(sum.digits); + + if (this.order > 0) { + numerator *= Math.pow(this.prime, this.order); + } + + if (this.order < 0) { + denominator *= Math.pow(this.prime, -this.order); + } + + return new Rational(numerator, denominator); + } + + // Return a string representation of this P_adic number + toString() { + let numbers = [...this.digits]; + this.padWithZeros(numbers); + + let result = ""; + for (let i = numbers.length - 1; i >= 0; --i) { + result += this.digits[i].toString(); + } + + if (this.order >= 0) { + for (let i = 0; i < this.order; ++i) { + result += "0"; + } + + result += ".0"; + } else { + result = result.slice(0, result.length + this.order) + "." + result.slice(result.length + this.order); + + while (result[result.length - 1] === '0') { + result = result.substring(0, result.length - 1); + } + } + + return " ..." + result.substring(result.length - P_adic.PRECISION - 1); + } + + // Transform the given array of digits representing a P_adic number + // into an array which represents the negation of the P_adic number + negateDigits(numbers) { + numbers[0] = this.moduloPrime(this.prime - numbers[0]); + for (let i = 1; i < numbers.length; ++i) { + numbers[i] = this.prime - 1 - numbers[i]; + } + } + + // Return the multiplicative inverse of the given number modulo 'prime' + moduloInverse(number) { + let inverse = 1; + while (this.moduloPrime(inverse * number) !== 1) { + inverse += 1; + } + return inverse; + } + + // Return the given number modulo 'prime' in the range 0...'prime' - 1 + moduloPrime(number) { + const div = number % this.prime; + return (div >= 0) ? div : div + this.prime; + } + + // The given array is padded on the right by zeros up to a maximum length of 'DIGITS_SIZE' + padWithZeros(array) { + while (array.length < P_adic.DIGITS_SIZE) { + array.push(0); + } + } + + // Return the given array of base 'prime' integers converted to a decimal integer + convertToDecimal(numbers) { + let decimal = 0; + let multiple = 1; + for (const number of numbers) { + decimal += number * multiple; + multiple *= this.prime; + } + return decimal; + } + + // Return whether the given array consists of all zeros + allZeroDigits(numbers) { + for (const number of numbers) { + if (number !== 0) { + return false; + } + } + return true; + } + + // Return whether the given array ends with multiple instances of the given number + endsWith(numbers, number) { + for (let i = numbers.length - 1; i >= numbers.length - P_adic.PRECISION / 2; --i) { + if (numbers[i] !== number) { + return false; + } + } + return true; + } +} + +// Main function equivalent +function main() { + console.log("3-adic numbers:"); + let padic_one = new P_adic(3, -2, 87); + console.log("-2 / 87 => " + padic_one.toString()); + let padic_two = new P_adic(3, 4, 97); + console.log("4 / 97 => " + padic_two.toString()); + + let sum = padic_one.add(padic_two); + console.log("sum => " + sum.toString()); + console.log("Rational = " + sum.convertToRational().toString()); + console.log(); + + console.log("7-adic numbers:"); + padic_one = new P_adic(7, 5, 8); + console.log("5 / 8 => " + padic_one.toString()); + padic_two = new P_adic(7, 353, 30809); + console.log("353 / 30809 => " + padic_two.toString()); + + sum = padic_one.add(padic_two); + console.log("sum => " + sum.toString()); + console.log("Rational = " + sum.convertToRational().toString()); + console.log(); +} + +// Run the main function +main(); diff --git a/Task/P-Adic-numbers-basic/Rust/p-adic-numbers-basic.rs b/Task/P-Adic-numbers-basic/Rust/p-adic-numbers-basic.rs new file mode 100644 index 0000000000..726a7d21bc --- /dev/null +++ b/Task/P-Adic-numbers-basic/Rust/p-adic-numbers-basic.rs @@ -0,0 +1,391 @@ +use std::cmp; +use std::sync::atomic::{AtomicI32, Ordering}; +use std::cell::UnsafeCell; + +// constants +const EMX: i32 = 64; // exponent maximum (if indexing starts at -EMX) +const DMX: i32 = 100000; // approximation loop maximum +const AMX: i32 = 1048576; // argument maximum +const PMAX: i32 = 32749; // prime maximum + +// Using atomics for the global variables +static P1: AtomicI32 = AtomicI32::new(0); +static P: AtomicI32 = AtomicI32::new(7); // default prime +static K: AtomicI32 = AtomicI32::new(11); // precision + +fn abs(a: i32) -> i32 { + if a >= 0 { + a + } else { + -a + } +} + +fn min(a: i32, b: i32) -> i32 { + if a < b { + a + } else { + b + } +} + +struct Ratio { + a: i32, + b: i32, +} + +struct Padic { + v: i32, + d: [i32; 2 * EMX as usize], // add EMX to index to be consistent with FB +} + +impl Padic { + // Create a new Padic with default values + fn new() -> Self { + Padic { + v: 0, + d: [0; 2 * EMX as usize], + } + } + + // (re)initialize receiver from Ratio, set 'sw' to print + fn r2pa(&mut self, q: Ratio, sw: i32) -> i32 { + let mut a = q.a; + let mut b = q.b; + if b == 0 { + return 1; + } + if b < 0 { + b = -b; + a = -a; + } + if abs(a) > AMX || b > AMX { + return -1; + } + + let p_val = P.load(Ordering::Relaxed); + if p_val < 2 || K.load(Ordering::Relaxed) < 1 { + return 1; + } + + // Set P to minimum of P and PMAX + let p_val = cmp::min(p_val, PMAX); + P.store(p_val, Ordering::Relaxed); + + // Set K to minimum of K and EMX-1 + let k_val = cmp::min(K.load(Ordering::Relaxed), EMX - 1); + K.store(k_val, Ordering::Relaxed); + + if sw != 0 { + println!("{}/{} + ", a, b); // numerator, denominator + println!("0({}^{})", p_val, k_val); // prime, precision + } + + // (re)initialize + self.v = 0; + P1.store(p_val - 1, Ordering::Relaxed); + self.d = [0; 2 * EMX as usize]; + + if a == 0 { + return 0; + } + + let mut i = 0; + let p1_val = P1.load(Ordering::Relaxed); + + // find -exponent of p in b + while b % p_val == 0 { + b = b / p_val; + i -= 1; + } + + let mut s = 0; + let r = b % p_val; + + // modular inverse for small p + let mut b1 = 1; + while b1 <= p1_val { + s += r; + if s > p1_val { + s -= p_val; + } + if s == 1 { + break; + } + b1 += 1; + } + + if b1 == p_val { + println!("r2pa: impossible inverse mod"); + return -1; + } + + self.v = EMX; + + loop { + // find exponent of P in a + while a % p_val == 0 { + a = a / p_val; + i += 1; + } + + // valuation + if self.v == EMX { + self.v = i; + } + + // upper bound + if i >= EMX { + break; + } + + // check precision + if (i - self.v) > k_val { + break; + } + + // next digit + self.d[(i + EMX) as usize] = a * b1 % p_val; + if self.d[(i + EMX) as usize] < 0 { + self.d[(i + EMX) as usize] += p_val; + } + + // remainder - digit * divisor + a -= self.d[(i + EMX) as usize] * b; + if a == 0 { + break; + } + } + + 0 + } + + // Horner's rule + fn dsum(&self) -> i32 { + let t = cmp::min(self.v, 0); + let mut s = 0; + let p_val = P.load(Ordering::Relaxed); + let k_val = K.load(Ordering::Relaxed); + + for i in (t..=k_val - 1 + t).rev() { + let r = s; + s *= p_val; + if r != 0 && (s / r - p_val != 0) { + // overflow + s = -1; + break; + } + s += self.d[(i + EMX) as usize]; + } + s + } + + // add b to receiver + fn add(&self, b: &Padic) -> Padic { + let mut c = 0; + let mut r = Padic::new(); + r.v = cmp::min(self.v, b.v); + let p_val = P.load(Ordering::Relaxed); + let p1_val = P1.load(Ordering::Relaxed); + let k_val = K.load(Ordering::Relaxed); + + for i in r.v..=k_val + r.v { + c += self.d[(i + EMX) as usize] + b.d[(i + EMX) as usize]; + if c > p1_val { + r.d[(i + EMX) as usize] = c - p_val; + c = 1; + } else { + r.d[(i + EMX) as usize] = c; + c = 0; + } + } + + r + } + + // complement of receiver + fn cmpt(&self) -> Padic { + let mut c = 1; + let mut r = Padic::new(); + r.v = self.v; + let p_val = P.load(Ordering::Relaxed); + let p1_val = P1.load(Ordering::Relaxed); + let k_val = K.load(Ordering::Relaxed); + + for i in self.v..=k_val + self.v { + c += p1_val - self.d[(i + EMX) as usize]; + if c > p1_val { + r.d[(i + EMX) as usize] = c - p_val; + c = 1; + } else { + r.d[(i + EMX) as usize] = c; + c = 0; + } + } + + r + } + + // rational reconstruction + fn crat(&self) { + let mut fl = false; + let mut s = self.clone(); + let mut j = 0; + let mut i = 1; + let p_val = P.load(Ordering::Relaxed); + let p1_val = P1.load(Ordering::Relaxed); + let k_val = K.load(Ordering::Relaxed); + + // denominator count + while i <= DMX { + // check for integer + j = k_val - 1 + self.v; + while j >= self.v { + if s.d[(j + EMX) as usize] != 0 { + break; + } + j -= 1; + } + fl = ((j - self.v) * 2) < k_val; + if fl { + fl = false; + break; + } + + // check negative integer + j = k_val - 1 + self.v; + while j >= self.v { + if p1_val - s.d[(j + EMX) as usize] != 0 { + break; + } + j -= 1; + } + fl = ((j - self.v) * 2) < k_val; + if fl { + break; + } + + // repeatedly add self to s + s = s.add(self); + i += 1; + } + + if fl { + s = s.cmpt(); + } + + // numerator: weighted digit sum + let x = s.dsum(); + let mut y = i; + + if x < 0 || y > DMX { + println!("{} {}", x, y); + println!("crat: fail"); + } else { + // negative powers + let mut i = self.v; + while i <= -1 { + y *= p_val; + i += 1; + } + + // negative rational + let final_x = if fl { -x } else { x }; + print!("{}", final_x); + if y > 1 { + print!("/{}", y); + } + println!(); + } + } + + // print expansion + fn printf(&self, sw: i32) { + let t = cmp::min(self.v, 0); + let k_val = K.load(Ordering::Relaxed); + + for i in (t..=k_val - 1 + t).rev() { + print!("{}", self.d[(i + EMX) as usize]); + if i == 0 && self.v < 0 { + print!("."); + } + print!(" "); + } + println!(); + // rational approximation + if sw != 0 { + self.crat(); + } + } +} + +// Implement the Clone trait for Padic +impl Clone for Padic { + fn clone(&self) -> Self { + Padic { + v: self.v, + d: self.d, + } + } +} + +fn main() { + let data = vec![ + /* rational reconstruction depends on the precision + until the dsum-loop overflows */ + vec![2, 1, 2, 4, 1, 1], + vec![4, 1, 2, 4, 3, 1], + vec![4, 1, 2, 5, 3, 1], + vec![4, 9, 5, 4, 8, 9], + vec![26, 25, 5, 4, -109, 125], + vec![49, 2, 7, 6, -4851, 2], + vec![-9, 5, 3, 8, 27, 7], + vec![5, 19, 2, 12, -101, 384], + /* two decadic pairs */ + vec![2, 7, 10, 7, -1, 7], + vec![34, 21, 10, 9, -39034, 791], + /* familiar digits */ + vec![11, 4, 2, 43, 679001, 207], + vec![-8, 9, 23, 9, 302113, 92], + vec![-22, 7, 3, 23, 46071, 379], + vec![-22, 7, 32749, 3, 46071, 379], + vec![35, 61, 5, 20, 9400, 109], + vec![-101, 109, 61, 7, 583376, 6649], + vec![-25, 26, 7, 13, 5571, 137], + vec![1, 4, 7, 11, 9263, 2837], + vec![122, 407, 7, 11, -517, 1477], + /* more subtle */ + vec![5, 8, 7, 11, 353, 30809], + ]; + + let mut sw = 0; + let mut a = Padic::new(); + let mut b = Padic::new(); + + for d in data { + let q = Ratio { a: d[0], b: d[1] }; + + P.store(d[2], Ordering::Relaxed); + K.store(d[3], Ordering::Relaxed); + + sw = a.r2pa(q, 1); + if sw == 1 { + break; + } + a.printf(0); + + let q_b = Ratio { a: d[4], b: d[5] }; + sw = sw | b.r2pa(q_b, 1); + if sw == 1 { + break; + } + + if sw == 0 { + b.printf(0); + let c = a.add(&b); + println!("+ ="); + c.printf(1); + } + println!(); + } +} diff --git a/Task/P-Adic-numbers-basic/Zig/p-adic-numbers-basic.zig b/Task/P-Adic-numbers-basic/Zig/p-adic-numbers-basic.zig new file mode 100644 index 0000000000..d69c31cba2 --- /dev/null +++ b/Task/P-Adic-numbers-basic/Zig/p-adic-numbers-basic.zig @@ -0,0 +1,357 @@ +const std = @import("std"); +const math = std.math; +const stdout = std.io.getStdOut().writer(); +const print = std.debug.print; + +// Constants +const EMX: i32 = 64; // exponent maximum (if indexing starts at -EMX) +const DMX: i32 = 100000; // approximation loop maximum +const AMX: i32 = 1048576; // argument maximum +const PMAX: i32 = 32749; // prime maximum + +// Global variables +var P1: i32 = 0; +var P: i32 = 7; // default prime +var K: i32 = 11; // precision + +// Helper functions +fn abs(a: i32) i32 { + return if (a >= 0) a else -a; +} + +fn min(a: i32, b: i32) i32 { + return if (a < b) a else b; +} + +const Ratio = struct { + a: i32, + b: i32, +}; + +const Padic = struct { + v: i32, + d: [2 * EMX]i32, // add EMX to index to be consistent + + // Create a new Padic with default values + fn new() Padic { + return Padic{ + .v = 0, + .d = [_]i32{0} ** (2 * EMX), + }; + } + + // (re)initialize receiver from Ratio, set 'sw' to print + fn r2pa(self: *Padic, q: Ratio, sw: i32) i32 { + var a = q.a; + var b = q.b; + if (b == 0) { + return 1; + } + if (b < 0) { + b = -b; + a = -a; + } + if (abs(a) > AMX or b > AMX) { + return -1; + } + + if (P < 2 or K < 1) { + return 1; + } + + // Set P to minimum of P and PMAX + P = @min(P, PMAX); + + // Set K to minimum of K and EMX-1 + K = @min(K, EMX - 1); + + if (sw != 0) { + print("{d}/{d} + \n", .{a, b}); // numerator, denominator + print("0({d}^{d})\n", .{P, K}); // prime, precision + } + + // (re)initialize + self.v = 0; + P1 = P - 1; + // std.mem.set(i32, &self.d, 0); + + if (a == 0) { + return 0; + } + + var i: i32 = 0; + + // find -exponent of p in b + while ( @rem(b, P) == 0) { + b = @divTrunc(b, P); + i -= 1; + } + + var s: i32 = 0; + const r = @rem(b, P); + + // modular inverse for small p + var b1: i32 = 1; + while (b1 <= P1) { + s += r; + if (s > P1) { + s -= P; + } + if (s == 1) { + break; + } + b1 += 1; + } + + if (b1 == P) { + print("r2pa: impossible inverse mod\n", .{}); + return -1; + } + + self.v = EMX; + + while (true) { + // find exponent of P in a + while ( @rem(a, P)==0) { + a = @divTrunc(a, P); + i += 1; + } + + // valuation + if (self.v == EMX) { + self.v = i; + } + + // upper bound + if (i >= EMX) { + break; + } + + // check precision + if ((i - self.v) > K) { + break; + } + + // next digit + self.d[@intCast(i + EMX)] = @mod(a * b1, P); + if (self.d[@intCast(i + EMX)] < 0) { + self.d[@intCast(i + EMX)] += P; + } + + // remainder - digit * divisor + a -= self.d[@intCast(i + EMX)] * b; + if (a == 0) { + break; + } + } + + return 0; + } + + // Horner's rule + fn dsum(self: *const Padic) i32 { + const t = @min(self.v, 0); + var s: i32 = 0; + + var i = K - 1 + t; + while (i >= t) : (i -= 1) { + const r = s; + s *= P; + if (r != 0 and (@divTrunc(s, r) - P != 0)) { + // overflow + s = -1; + break; + } + s += self.d[@intCast(i + EMX)]; + } + return s; + } + + // add b to receiver + fn add(self: *const Padic, b: *const Padic) Padic { + var c: i32 = 0; + var r = Padic.new(); + r.v = @min(self.v, b.v); + + var i: i32 = r.v; + while (i <= K + r.v) : (i += 1) { + c += self.d[@intCast(i + EMX)] + b.d[@intCast(i + EMX)]; + if (c > P1) { + r.d[@intCast(i + EMX)] = c - P; + c = 1; + } else { + r.d[@intCast(i + EMX)] = c; + c = 0; + } + } + + return r; + } + + // complement of receiver + fn cmpt(self: *const Padic) Padic { + var c: i32 = 1; + var r = Padic.new(); + r.v = self.v; + + var i: i32 = self.v; + while (i <= K + self.v) : (i += 1) { + c += P1 - self.d[@intCast(i + EMX)]; + if (c > P1) { + r.d[@intCast(i + EMX)] = c - P; + c = 1; + } else { + r.d[@intCast(i + EMX)] = c; + c = 0; + } + } + + return r; + } + + // rational reconstruction + fn crat(self: *const Padic) void { + var fl = false; + var s = self.*; + var j: i32 = 0; + var i: i32 = 1; + + // denominator count + while (i <= DMX) : (i += 1) { + // check for integer + j = K - 1 + self.v; + while (j >= self.v) : (j -= 1) { + if (s.d[@intCast(j + EMX)] != 0) { + break; + } + } + fl = ((j - self.v) * 2) < K; + if (fl) { + fl = false; + break; + } + + // check negative integer + j = K - 1 + self.v; + while (j >= self.v) : (j -= 1) { + if (P1 - s.d[@intCast(j + EMX)] != 0) { + break; + } + } + fl = ((j - self.v) * 2) < K; + if (fl) { + break; + } + + // repeatedly add self to s + s = s.add(self); + } + + if (fl) { + s = s.cmpt(); + } + + // numerator: weighted digit sum + const x = s.dsum(); + var y = i; + + if (x < 0 or y > DMX) { + print("{d} {d}\n", .{x, y}); + print("crat: fail\n", .{}); + } else { + // negative powers + var i_pow = self.v; + while (i_pow <= -1) : (i_pow += 1) { + y *= P; + } + + // negative rational + const final_x = if (fl) -x else x; + print("{d}", .{final_x}); + if (y > 1) { + print("/{d}", .{y}); + } + print("\n", .{}); + } + } + + // print expansion + fn printf(self: *const Padic, sw: i32) void { + const t = @min(self.v, 0); + + var i = K - 1 + t; + while (i >= t) : (i -= 1) { + print("{d}", .{self.d[@intCast(i + EMX)]}); + if (i == 0 and self.v < 0) { + print(".", .{}); + } + print(" ", .{}); + } + print("\n", .{}); + // rational approximation + if (sw != 0) { + self.crat(); + } + } +}; + +pub fn main() !void { + const data = [_][6]i32{ + // rational reconstruction depends on the precision + // until the dsum-loop overflows + [_]i32{ 2, 1, 2, 4, 1, 1 }, + [_]i32{ 4, 1, 2, 4, 3, 1 }, + [_]i32{ 4, 1, 2, 5, 3, 1 }, + [_]i32{ 4, 9, 5, 4, 8, 9 }, + [_]i32{ 26, 25, 5, 4, -109, 125 }, + [_]i32{ 49, 2, 7, 6, -4851, 2 }, + [_]i32{ -9, 5, 3, 8, 27, 7 }, + [_]i32{ 5, 19, 2, 12, -101, 384 }, + // two decadic pairs + [_]i32{ 2, 7, 10, 7, -1, 7 }, + [_]i32{ 34, 21, 10, 9, -39034, 791 }, + // familiar digits + [_]i32{ 11, 4, 2, 43, 679001, 207 }, + [_]i32{ -8, 9, 23, 9, 302113, 92 }, + [_]i32{ -22, 7, 3, 23, 46071, 379 }, + [_]i32{ -22, 7, 32749, 3, 46071, 379 }, + [_]i32{ 35, 61, 5, 20, 9400, 109 }, + [_]i32{ -101, 109, 61, 7, 583376, 6649 }, + [_]i32{ -25, 26, 7, 13, 5571, 137 }, + [_]i32{ 1, 4, 7, 11, 9263, 2837 }, + [_]i32{ 122, 407, 7, 11, -517, 1477 }, + // more subtle + [_]i32{ 5, 8, 7, 11, 353, 30809 }, + }; + + var sw: i32 = 0; + var a = Padic.new(); + var b = Padic.new(); + + for (data) |d| { + const q = Ratio{ .a = d[0], .b = d[1] }; + + P = d[2]; + K = d[3]; + + sw = a.r2pa(q, 1); + if (sw == 1) { + break; + } + a.printf(0); + + const q_b = Ratio{ .a = d[4], .b = d[5] }; + sw = sw | b.r2pa(q_b, 1); + if (sw == 1) { + break; + } + + if (sw == 0) { + b.printf(0); + const c = a.add(&b); + print("+ =\n", .{}); + c.printf(1); + } + print("\n", .{}); + } +} diff --git a/Task/P-Adic-square-roots/Go/p-adic-square-roots.go b/Task/P-Adic-square-roots/Go/p-adic-square-roots.go new file mode 100644 index 0000000000..f567e32ad2 --- /dev/null +++ b/Task/P-Adic-square-roots/Go/p-adic-square-roots.go @@ -0,0 +1,388 @@ +package main + +import ( + "fmt" + "math" + "strconv" + "strings" +) + +// PAdicSquareRoot represents a p-adic square root number +type PAdicSquareRoot struct { + prime int64 + precision int + digits []int64 + order int +} + +const orderMax = 1000 + +// NewPAdicSquareRoot creates a p-adic square root number from a rational number +func NewPAdicSquareRoot(prime int64, precision int, numerator int64, denominator int64) (*PAdicSquareRoot, error) { + if denominator == 0 { + return nil, fmt.Errorf("denominator cannot be zero") + } + + digitsSize := precision + 5 + order := 0 + + // Process rational zero + if numerator == 0 { + return &PAdicSquareRoot{ + prime: prime, + precision: precision, + digits: make([]int64, digitsSize), + order: orderMax, + }, nil + } + + // Remove multiples of 'prime' and adjust the order accordingly + for modulo(numerator, prime) == 0 { + numerator /= prime + order++ + } + + for modulo(denominator, prime) == 0 { + denominator /= prime + order-- + } + + if (order & 1) != 0 { + return nil, fmt.Errorf("number does not have a square root in %d-adic", prime) + } + order >>= 1 + + result := &PAdicSquareRoot{ + prime: prime, + precision: precision, + digits: []int64{}, + order: order, + } + + var err error + if prime == 2 { + err = result.squareRootEvenPrime(numerator, denominator) + } else { + err = result.squareRootOddPrime(numerator, denominator) + } + + if err != nil { + return nil, err + } + + // Ensure we have the right number of digits + for len(result.digits) < digitsSize { + result.digits = append(result.digits, 0) + } + if len(result.digits) > digitsSize { + result.digits = result.digits[:digitsSize] + } + + return result, nil +} + +// Clone returns a copy of the PAdicSquareRoot +func (p *PAdicSquareRoot) Clone() *PAdicSquareRoot { + digitsCopy := make([]int64, len(p.digits)) + copy(digitsCopy, p.digits) + + return &PAdicSquareRoot{ + prime: p.prime, + precision: p.precision, + digits: digitsCopy, + order: p.order, + } +} + +// Negate returns the additive inverse of this p-adic square root number +func (p *PAdicSquareRoot) Negate() *PAdicSquareRoot { + if len(p.digits) == 0 { + return p.Clone() + } + + result := p.Clone() + negateDigits(result.digits, p.prime) + return result +} + +// Multiply returns the product of this p-adic square root number and another +func (p *PAdicSquareRoot) Multiply(other *PAdicSquareRoot) (*PAdicSquareRoot, error) { + if p.prime != other.prime { + return nil, fmt.Errorf("cannot multiply p-adic's with different primes") + } + + if len(p.digits) == 0 || len(other.digits) == 0 { + return NewPAdicSquareRoot(p.prime, p.precision, 0, 1) + } + + digitsSize := p.precision + 5 + product := multiplyDigits(p.digits, other.digits, p.prime, digitsSize) + + return &PAdicSquareRoot{ + prime: p.prime, + precision: p.precision, + digits: product, + order: p.order + other.order, + }, nil +} + +// ConvertToRational returns a string representation of this p-adic square root as a rational number +func (p *PAdicSquareRoot) ConvertToRational() (string, error) { + if len(p.digits) == 0 { + return "0 / 1", nil + } + + // Lagrange lattice basis reduction in two dimensions + seriesSum := p.digits[0] + maximumPrime := int64(1) + + for i := 1; i < p.precision; i++ { + maximumPrime *= p.prime + seriesSum += p.digits[i] * maximumPrime + } + + one := []int64{maximumPrime, seriesSum} + two := []int64{0, 1} + + previousNorm := seriesSum*seriesSum + 1 + currentNorm := previousNorm + 1 + i := 0 + j := 1 + + for previousNorm < currentNorm { + numerator := one[i]*one[j] + two[i]*two[j] + denominator := previousNorm + currentNorm = int64(math.Floor(float64(numerator)/float64(denominator) + 0.5)) + one[i] -= currentNorm * one[j] + two[i] -= currentNorm * two[j] + + currentNorm = previousNorm + previousNorm = one[i]*one[i] + two[i]*two[i] + + if previousNorm < currentNorm { + one[i], one[j] = one[j], one[i] + two[i], two[j] = two[j], two[i] + } + } + + x := one[j] + y := two[j] + if y < 0 { + y = -y + x = -x + } + + if math.Abs(float64(one[i]*y-x*two[i])) != float64(maximumPrime) { + return "", fmt.Errorf("rational reconstruction failed") + } + + for k := p.order; k < 0; k++ { + y *= p.prime + } + + for k := 0; k < p.order; k++ { + x *= p.prime + } + + return fmt.Sprintf("%d / %d", x, y), nil +} + +// String returns a string representation of this p-adic square root +func (p *PAdicSquareRoot) String() string { + digits := make([]int64, len(p.digits)) + copy(digits, p.digits) + + // Pad with zeros if needed + for len(digits) < p.precision+5 { + digits = append(digits, 0) + } + + var result strings.Builder + for i := len(digits) - 1; i >= 0; i-- { + result.WriteString(strconv.FormatInt(digits[i], 10)) + } + + resultStr := result.String() + + if p.order >= 0 { + for i := 0; i < p.order; i++ { + resultStr += "0" + } + resultStr += ".0" + } else { + insertPos := len(resultStr) + p.order + if insertPos >= 0 { + resultStr = resultStr[:insertPos] + "." + resultStr[insertPos:] + } else { + // If we need to insert before the start, pad with zeros + zerosNeeded := -insertPos + resultStr = "0." + strings.Repeat("0", zerosNeeded) + resultStr + } + + // Remove trailing zeros + for strings.HasSuffix(resultStr, "0") { + resultStr = resultStr[:len(resultStr)-1] + } + } + + // Return with ellipsis at the beginning + startPos := 0 + if len(resultStr) > p.precision+1 { + startPos = len(resultStr) - p.precision - 1 + } + return " ..." + resultStr[startPos:] +} + +// squareRootEvenPrime creates a 2-adic number which is the square root of the rational numerator/denominator +func (p *PAdicSquareRoot) squareRootEvenPrime(numerator, denominator int64) error { + if modulo(numerator*denominator, 8) != 1 { + return fmt.Errorf("number does not have a square root in 2-adic") + } + + // First digit + sum := int64(1) + p.digits = append(p.digits, 1) + + // Further digits + digitsSize := p.precision + 5 + for len(p.digits) < digitsSize { + factor := denominator*sum*sum - numerator + valuation := 0 + factorTemp := factor + for modulo(factorTemp, 2) == 0 { + factorTemp /= 2 + valuation++ + } + + sum += int64(math.Pow(2, float64(valuation-1))) + + for len(p.digits) < valuation-1 { + p.digits = append(p.digits, 0) + } + p.digits = append(p.digits, 1) + } + + return nil +} + +// squareRootOddPrime creates a p-adic number, with an odd prime number, which is the p-adic square root +func (p *PAdicSquareRoot) squareRootOddPrime(numerator, denominator int64) error { + // First digit + firstDigit := int64(0) + for i := int64(1); i < p.prime && firstDigit == 0; i++ { + if modulo(denominator*i*i-numerator, p.prime) == 0 { + firstDigit = i + } + } + + if firstDigit == 0 { + return fmt.Errorf("number does not have a square root in %d-adic", p.prime) + } + + p.digits = append(p.digits, firstDigit) + + // Further digits + coefficient := moduloInverse(modulo(2*denominator*firstDigit, p.prime), p.prime) + sum := firstDigit + digitsSize := p.precision + 5 + + for i := 2; i < digitsSize; i++ { + nextSum := sum - int64(coefficient)*(denominator*sum*sum-numerator) + nextSum = modulo(nextSum, int64(math.Pow(float64(p.prime), float64(i)))) + nextSum -= sum + sum += nextSum + + digit := nextSum / int64(math.Pow(float64(p.prime), float64(i-1))) + p.digits = append(p.digits, digit) + } + + return nil +} + +// negateDigits transforms the given vector of digits representing a p-adic number +// into a vector which represents the negation of the p-adic number +func negateDigits(numbers []int64, prime int64) { + if len(numbers) > 0 { + numbers[0] = modulo(prime-numbers[0], prime) + for i := 1; i < len(numbers); i++ { + numbers[i] = prime - 1 - numbers[i] + } + } +} + +// multiplyDigits returns the list obtained by multiplying the digits of the given two lists +func multiplyDigits(one, two []int64, prime int64, maxSize int) []int64 { + product := make([]int64, len(one)+len(two)) + + for b := 0; b < len(two); b++ { + carry := int64(0) + for a := 0; a < len(one); a++ { + product[a+b] += one[a]*two[b] + carry + carry = product[a+b] / prime + product[a+b] %= prime + } + if b+len(one) < len(product) { + product[b+len(one)] = carry + } + } + + // Truncate to maxSize + if len(product) > maxSize { + product = product[:maxSize] + } + return product +} + +// moduloInverse returns the multiplicative inverse of the given number modulo 'prime' +func moduloInverse(number, prime int64) int64 { + inverse := int64(1) + for modulo(inverse*number, prime) != 1 { + inverse++ + } + return inverse +} + +// modulo returns the given number modulo 'prime' in the range 0..'prime' - 1 +func modulo(number, modulus int64) int64 { + div := number % modulus + if div >= 0 { + return div + } + return div + modulus +} + +func main() { + tests := [][]int64{ + {2, 20, 497, 10496}, + {5, 14, 86, 25}, + {7, 10, -19, 1}, + } + + for _, test := range tests { + fmt.Printf("Number: %d / %d in %d-adic\n", test[2], test[3], test[0]) + + squareRoot, err := NewPAdicSquareRoot(test[0], int(test[1]), test[2], test[3]) + if err != nil { + fmt.Printf("Error: %v\n\n", err) + continue + } + + fmt.Println("The two square roots are:") + fmt.Printf(" %s\n", squareRoot.String()) + fmt.Printf(" %s\n", squareRoot.Negate().String()) + + square, err := squareRoot.Multiply(squareRoot) + if err != nil { + fmt.Printf("Error calculating square: %v\n\n", err) + continue + } + + fmt.Printf("The p-adic value is %s\n", square.String()) + rational, err := square.ConvertToRational() + if err != nil { + fmt.Printf("Error converting to rational: %v\n\n", err) + continue + } + fmt.Printf("The rational value is %s\n\n", rational) + } +} diff --git a/Task/P-Adic-square-roots/JavaScript/p-adic-square-roots.js b/Task/P-Adic-square-roots/JavaScript/p-adic-square-roots.js new file mode 100644 index 0000000000..c98cbab03c --- /dev/null +++ b/Task/P-Adic-square-roots/JavaScript/p-adic-square-roots.js @@ -0,0 +1,360 @@ +// PAdicSquareRoot represents a p-adic square root number +class PAdicSquareRoot { + constructor(prime, precision, digits = [], order = 0) { + this.prime = prime; + this.precision = precision; + this.digits = digits; + this.order = order; + } + + // Clone returns a copy of the PAdicSquareRoot + clone() { + return new PAdicSquareRoot( + this.prime, + this.precision, + [...this.digits], + this.order + ); + } + + // Negate returns the additive inverse of this p-adic square root number + negate() { + if (this.digits.length === 0) { + return this.clone(); + } + + const result = this.clone(); + negateDigits(result.digits, this.prime); + return result; + } + + // Multiply returns the product of this p-adic square root number and another + multiply(other) { + if (this.prime !== other.prime) { + throw new Error("Cannot multiply p-adic's with different primes"); + } + + if (this.digits.length === 0 || other.digits.length === 0) { + return createPAdicSquareRoot(this.prime, this.precision, 0, 1); + } + + const digitsSize = this.precision + 5; + const product = multiplyDigits(this.digits, other.digits, this.prime, digitsSize); + + return new PAdicSquareRoot( + this.prime, + this.precision, + product, + this.order + other.order + ); + } + + // ConvertToRational returns a string representation of this p-adic square root as a rational number + convertToRational() { + if (this.digits.length === 0) { + return "0 / 1"; + } + + // Lagrange lattice basis reduction in two dimensions + let seriesSum = this.digits[0]; + let maximumPrime = 1n; + + for (let i = 1; i < this.precision; i++) { + maximumPrime *= BigInt(this.prime); + seriesSum += this.digits[i] * Number(maximumPrime); + } + + const one = [Number(maximumPrime), seriesSum]; + const two = [0, 1]; + + let previousNorm = seriesSum * seriesSum + 1; + let currentNorm = previousNorm + 1; + let i = 0; + let j = 1; + + while (previousNorm < currentNorm) { + const numerator = one[i] * one[j] + two[i] * two[j]; + const denominator = previousNorm; + currentNorm = Math.floor(numerator / denominator + 0.5); + one[i] -= currentNorm * one[j]; + two[i] -= currentNorm * two[j]; + + currentNorm = previousNorm; + previousNorm = one[i] * one[i] + two[i] * two[i]; + + if (previousNorm < currentNorm) { + [one[i], one[j]] = [one[j], one[i]]; + [two[i], two[j]] = [two[j], two[i]]; + } + } + + let x = one[j]; + let y = two[j]; + if (y < 0) { + y = -y; + x = -x; + } + + if (Math.abs(one[i] * y - x * two[i]) !== Number(maximumPrime)) { + throw new Error("Rational reconstruction failed"); + } + + for (let k = this.order; k < 0; k++) { + y *= this.prime; + } + + for (let k = 0; k < this.order; k++) { + x *= this.prime; + } + + return `${x} / ${y}`; + } + + // String returns a string representation of this p-adic square root + toString() { + const digits = [...this.digits]; + + // Pad with zeros if needed + while (digits.length < this.precision + 5) { + digits.push(0); + } + + let result = ""; + for (let i = digits.length - 1; i >= 0; i--) { + result += digits[i].toString(); + } + + let resultStr = result; + + if (this.order >= 0) { + for (let i = 0; i < this.order; i++) { + resultStr += "0"; + } + resultStr += ".0"; + } else { + const insertPos = resultStr.length + this.order; + if (insertPos >= 0) { + resultStr = resultStr.substring(0, insertPos) + "." + resultStr.substring(insertPos); + } else { + // If we need to insert before the start, pad with zeros + const zerosNeeded = -insertPos; + resultStr = "0." + "0".repeat(zerosNeeded) + resultStr; + } + + // Remove trailing zeros + while (resultStr.endsWith("0")) { + resultStr = resultStr.substring(0, resultStr.length - 1); + } + } + + // Return with ellipsis at the beginning + let startPos = 0; + if (resultStr.length > this.precision + 1) { + startPos = resultStr.length - this.precision - 1; + } + return " ..." + resultStr.substring(startPos); + } + + // squareRootEvenPrime creates a 2-adic number which is the square root of the rational numerator/denominator + squareRootEvenPrime(numerator, denominator) { + if (modulo(numerator * denominator, 8) !== 1) { + throw new Error("Number does not have a square root in 2-adic"); + } + + // First digit + let sum = 1; + this.digits.push(1); + + // Further digits + const digitsSize = this.precision + 5; + while (this.digits.length < digitsSize) { + const factor = denominator * sum * sum - numerator; + let valuation = 0; + let factorTemp = factor; + while (modulo(factorTemp, 2) === 0) { + factorTemp = Math.floor(factorTemp / 2); + valuation++; + } + + sum += Math.pow(2, valuation - 1); + + while (this.digits.length < valuation - 1) { + this.digits.push(0); + } + this.digits.push(1); + } + } + + // squareRootOddPrime creates a p-adic number, with an odd prime number, which is the p-adic square root + squareRootOddPrime(numerator, denominator) { + // First digit + let firstDigit = 0; + for (let i = 1; i < this.prime && firstDigit === 0; i++) { + if (modulo(denominator * i * i - numerator, this.prime) === 0) { + firstDigit = i; + } + } + + if (firstDigit === 0) { + throw new Error(`Number does not have a square root in ${this.prime}-adic`); + } + + this.digits.push(firstDigit); + + // Further digits + const coefficient = moduloInverse(modulo(2 * denominator * firstDigit, this.prime), this.prime); + let sum = firstDigit; + const digitsSize = this.precision + 5; + + for (let i = 2; i < digitsSize; i++) { + let nextSum = sum - coefficient * (denominator * sum * sum - numerator); + nextSum = modulo(nextSum, Math.pow(this.prime, i)); + nextSum -= sum; + sum += nextSum; + + const digit = Math.floor(nextSum / Math.pow(this.prime, i - 1)); + this.digits.push(digit); + } + } +} + +// createPAdicSquareRoot creates a p-adic square root number from a rational number +function createPAdicSquareRoot(prime, precision, numerator, denominator) { + if (denominator === 0) { + throw new Error("Denominator cannot be zero"); + } + + const digitsSize = precision + 5; + let order = 0; + + // Process rational zero + if (numerator === 0) { + return new PAdicSquareRoot( + prime, + precision, + Array(digitsSize).fill(0), + 1000 // orderMax + ); + } + + // Remove multiples of 'prime' and adjust the order accordingly + while (modulo(numerator, prime) === 0) { + numerator = Math.floor(numerator / prime); + order++; + } + + while (modulo(denominator, prime) === 0) { + denominator = Math.floor(denominator / prime); + order--; + } + + if ((order & 1) !== 0) { + throw new Error(`Number does not have a square root in ${prime}-adic`); + } + order >>= 1; + + const result = new PAdicSquareRoot( + prime, + precision, + [], + order + ); + + if (prime === 2) { + result.squareRootEvenPrime(numerator, denominator); + } else { + result.squareRootOddPrime(numerator, denominator); + } + + // Ensure we have the right number of digits + while (result.digits.length < digitsSize) { + result.digits.push(0); + } + if (result.digits.length > digitsSize) { + result.digits = result.digits.slice(0, digitsSize); + } + + return result; +} + +// negateDigits transforms the given vector of digits representing a p-adic number +// into a vector which represents the negation of the p-adic number +function negateDigits(numbers, prime) { + if (numbers.length > 0) { + numbers[0] = modulo(prime - numbers[0], prime); + for (let i = 1; i < numbers.length; i++) { + numbers[i] = prime - 1 - numbers[i]; + } + } +} + +// multiplyDigits returns the list obtained by multiplying the digits of the given two lists +function multiplyDigits(one, two, prime, maxSize) { + const product = Array(one.length + two.length).fill(0); + + for (let b = 0; b < two.length; b++) { + let carry = 0; + for (let a = 0; a < one.length; a++) { + product[a + b] += one[a] * two[b] + carry; + carry = Math.floor(product[a + b] / prime); + product[a + b] %= prime; + } + if (b + one.length < product.length) { + product[b + one.length] = carry; + } + } + + // Truncate to maxSize + if (product.length > maxSize) { + return product.slice(0, maxSize); + } + return product; +} + +// moduloInverse returns the multiplicative inverse of the given number modulo 'prime' +function moduloInverse(number, prime) { + let inverse = 1; + while (modulo(inverse * number, prime) !== 1) { + inverse++; + } + return inverse; +} + +// modulo returns the given number modulo 'prime' in the range 0..'prime' - 1 +function modulo(number, modulus) { + const div = number % modulus; + return div >= 0 ? div : div + modulus; +} + +// Main function +function main() { + const tests = [ + [2, 20, 497, 10496], + [5, 14, 86, 25] + // ,[7, 10, -19, 1] + ]; + + for (const test of tests) { + console.log(`Number: ${test[2]} / ${test[3]} in ${test[0]}-adic`); + + try { + const squareRoot = createPAdicSquareRoot(test[0], test[1], test[2], test[3]); + + console.log("The two square roots are:"); + console.log(` ${squareRoot.toString()}`); + console.log(` ${squareRoot.negate().toString()}`); + + const square = squareRoot.multiply(squareRoot); + console.log(`The p-adic value is ${square.toString()}`); + + const rational = square.convertToRational(); + console.log(`The rational value is ${rational}`); + } catch (error) { + console.log(`Error: ${error.message}`); + } + console.log(); + } +} + +// Run the main function +main(); diff --git a/Task/P-Adic-square-roots/Rust/p-adic-square-roots.rs b/Task/P-Adic-square-roots/Rust/p-adic-square-roots.rs new file mode 100644 index 0000000000..1c80c04b89 --- /dev/null +++ b/Task/P-Adic-square-roots/Rust/p-adic-square-roots.rs @@ -0,0 +1,381 @@ +use std::cmp::Ordering; +use std::fmt; + +#[derive(Clone)] +struct PAdicSquareRoot { + prime: u32, + precision: u32, + digits: Vec, + order: i32, +} + +impl PAdicSquareRoot { + // Create a PAdicSquareRoot number, with p = 'prime', from the given rational 'numerator' / 'denominator'. + fn new(prime: u32, precision: u32, mut numerator: i32, mut denominator: i32) -> Result { + if denominator == 0 { + return Err("Denominator cannot be zero".to_string()); + } + + let digits_size = precision + 5; + let mut order = 0; + let mut digits = vec![0; digits_size as usize]; + + // Process rational zero + if numerator == 0 { + return Ok(Self { + prime, + precision, + digits, + order: 1000, // ORDER_MAX from original code + }); + } + + // Remove multiples of 'prime' and adjust the order of the PAdicSquareRoot number accordingly + while Self::modulo(numerator as i64, prime as i64) == 0 { + numerator /= prime as i32; + order += 1; + } + + while Self::modulo(denominator as i64, prime as i64) == 0 { + denominator /= prime as i32; + order -= 1; + } + + if (order & 1) != 0 { + return Err(format!("Number does not have a square root in {}-adic", prime)); + } + order >>= 1; + + let mut result = Self { + prime, + precision, + digits: Vec::with_capacity(digits_size as usize), + order, + }; + + if prime == 2 { + result.square_root_even_prime(numerator, denominator)?; + } else { + result.square_root_odd_prime(numerator, denominator)?; + } + + // Ensure we have the right number of digits + while result.digits.len() < digits_size as usize { + result.digits.push(0); + } + result.digits.truncate(digits_size as usize); + + Ok(result) + } + + // Create a PAdicSquareRoot directly from a vector of digits + fn from_digits(prime: u32, precision: u32, digits: Vec, order: i32) -> Self { + Self { + prime, + precision, + digits, + order, + } + } + + // Return the additive inverse of this PAdicSquareRoot number + fn negate(&self) -> Self { + if self.digits.is_empty() { + return self.clone(); + } + + let mut negated = self.digits.clone(); + Self::negate_digits(&mut negated, self.prime); + + Self::from_digits(self.prime, self.precision, negated, self.order) + } + + // Return the product of this PAdicSquareRoot number and another PAdicSquareRoot number + fn multiply(&self, other: &Self) -> Result { + if self.prime != other.prime { + return Err("Cannot multiply p-adic's with different primes".to_string()); + } + + if self.digits.is_empty() || other.digits.is_empty() { + return Self::new(self.prime, self.precision, 0, 1); + } + + let product_digits = Self::multiply_digits(&self.digits, &other.digits, self.prime, (self.precision + 5) as usize); + Ok(Self::from_digits( + self.prime, + self.precision, + product_digits, + self.order + other.order, + )) + } + + // Return a string representation of this PAdicSquareRoot as a rational number + fn convert_to_rational(&self) -> Result { + if self.digits.is_empty() { + return Ok("0 / 1".to_string()); + } + + // Lagrange lattice basis reduction in two dimensions + let mut series_sum: i64 = self.digits[0] as i64; + let mut maximum_prime: i64 = 1; + + for i in 1..self.precision { + maximum_prime *= self.prime as i64; + series_sum += (self.digits[i as usize] as i64) * maximum_prime; + } + + let mut one = vec![maximum_prime, series_sum]; + let mut two = vec![0, 1]; + + let mut previous_norm = series_sum * series_sum + 1; + let mut current_norm = previous_norm + 1; + let mut i = 0; + let mut j = 1; + + while previous_norm < current_norm { + let numerator = one[i] * one[j] + two[i] * two[j]; + let denominator = previous_norm; + current_norm = ((numerator as f64) / (denominator as f64) + 0.5).floor() as i64; + one[i] -= current_norm * one[j]; + two[i] -= current_norm * two[j]; + + current_norm = previous_norm; + previous_norm = one[i] * one[i] + two[i] * two[i]; + + if previous_norm < current_norm { + std::mem::swap(&mut i, &mut j); + } + } + + let mut x = one[j]; + let mut y = two[j]; + if y < 0 { + y = -y; + x = -x; + } + + if (one[i] * y - x * two[i]).abs() != maximum_prime { + return Err("Rational reconstruction failed.".to_string()); + } + + for _ in self.order..0 { + y *= self.prime as i64; + } + + for _ in 0..self.order { + x *= self.prime as i64; + } + + Ok(format!("{} / {}", x, y)) + } + + // Create a 2-adic number which is the square root of the rational 'numerator' / 'denominator' + fn square_root_even_prime(&mut self, numerator: i32, denominator: i32) -> Result<(), String> { + if Self::modulo((numerator as i64) * (denominator as i64), 8) != 1 { + return Err("Number does not have a square root in 2-adic".to_string()); + } + + // First digit + let mut sum: i64 = 1; + self.digits.push(1); + + // Further digits + let digits_size = self.precision + 5; + while self.digits.len() < digits_size as usize { + let factor = (denominator as i64) * sum * sum - (numerator as i64); + let mut valuation = 0; + let mut factor_temp = factor; + while Self::modulo(factor_temp, 2) == 0 { + factor_temp /= 2; + valuation += 1; + } + + sum += 2i64.pow(valuation - 1); + + while self.digits.len() < (valuation - 1) as usize { + self.digits.push(0); + } + self.digits.push(1); + } + + Ok(()) + } + + // Create a p-adic number, with an odd prime number, p = 'prime', + // which is the p-adic square root of the given rational 'numerator' / 'denominator' + fn square_root_odd_prime(&mut self, numerator: i32, denominator: i32) -> Result<(), String> { + // First digit + let mut first_digit = 0; + for i in 1..self.prime { + if Self::modulo( + (denominator as i64) * (i as i64) * (i as i64) - (numerator as i64), + self.prime as i64, + ) == 0 + { + first_digit = i; + break; + } + } + + if first_digit == 0 { + return Err(format!( + "Number does not have a square root in {}-adic", + self.prime + )); + } + + self.digits.push(first_digit); + + // Further digits + let coefficient = Self::modulo_inverse( + Self::modulo(2 * (denominator as i64) * (first_digit as i64), self.prime as i64) as u32, + self.prime, + ); + + let mut sum: i64 = first_digit as i64; + let digits_size = self.precision + 5; + + for i in 2..digits_size { + let mut next_sum = sum - ((coefficient as i64) * ((denominator as i64) * sum * sum - (numerator as i64))); + next_sum = Self::modulo(next_sum, (self.prime as i64).pow(i)); + next_sum -= sum; + sum += next_sum; + + let digit = (next_sum / (self.prime as i64).pow(i - 1)) as u32; + self.digits.push(digit); + } + + Ok(()) + } + + // Transform the given vector of digits representing a p-adic number + // into a vector which represents the negation of the p-adic number + fn negate_digits(numbers: &mut Vec, prime: u32) { + if !numbers.is_empty() { + numbers[0] = Self::modulo(prime as i64 - numbers[0] as i64, prime as i64) as u32; + for i in 1..numbers.len() { + numbers[i] = prime - 1 - numbers[i]; + } + } + } + + // Return the list obtained by multiplying the digits of the given two lists + fn multiply_digits(one: &[u32], two: &[u32], prime: u32, max_size: usize) -> Vec { + let mut product = vec![0; one.len() + two.len()]; + + for b in 0..two.len() { + let mut carry = 0; + for a in 0..one.len() { + product[a + b] += one[a] * two[b] + carry; + carry = product[a + b] / prime; + product[a + b] %= prime; + } + if b + one.len() < product.len() { + product[b + one.len()] = carry; + } + } + + // Truncate to max_size + product.truncate(max_size); + product + } + + // Return the multiplicative inverse of the given number modulo 'prime' + fn modulo_inverse(number: u32, prime: u32) -> u32 { + let mut inverse: u32 = 1; + while Self::modulo((inverse as i64) * (number as i64), prime as i64) != 1 { + inverse += 1; + } + inverse + } + + // Return the given number modulo 'prime' in the range 0..'prime' - 1 + fn modulo(number: i64, modulus: i64) -> i64 { + let div = number % modulus; + if div >= 0 { + div + } else { + div + modulus + } + } + + // Generate string representation of this PAdicSquareRoot + fn to_string(&self) -> String { + let mut numbers = self.digits.clone(); + + // Ensure we have the right number of digits + while numbers.len() < (self.precision + 5) as usize { + numbers.push(0); + } + + let mut result = String::new(); + for i in (0..numbers.len()).rev() { + result.push_str(&numbers[i].to_string()); + } + + if self.order >= 0 { + for _ in 0..self.order { + result.push('0'); + } + result.push_str(".0"); + } else { + let insert_pos = result.len() as i32 + self.order; + if insert_pos >= 0 { + result.insert(insert_pos as usize, '.'); + } else { + // If we need to insert before the start, pad with zeros + let zeros_needed = -insert_pos; + result = "0.".to_string() + &"0".repeat(zeros_needed as usize) + &result; + } + + // Remove trailing zeros + while result.ends_with('0') { + result.pop(); + } + } + + // Return with ellipsis at the beginning + let start_pos = if result.len() > self.precision as usize + 1 { + result.len() - self.precision as usize - 1 + } else { + 0 + }; + format!(" ...{}", &result[start_pos..]) + } +} + +fn main() { + let tests = vec![ + vec![2, 20, 497, 10496], + vec![5, 14, 86, 25], + vec![7, 10, -19, 1], + ]; + + for test in tests { + println!( + "Number: {} / {} in {}-adic", + test[2], test[3], test[0] + ); + + match PAdicSquareRoot::new(test[0] as u32, test[1] as u32, test[2], test[3]) { + Ok(square_root) => { + println!("The two square roots are:"); + println!(" {}", square_root.to_string()); + println!(" {}", square_root.negate().to_string()); + + match square_root.multiply(&square_root) { + Ok(square) => { + println!("The p-adic value is {}", square.to_string()); + match square.convert_to_rational() { + Ok(rational) => println!("The rational value is {}", rational), + Err(e) => println!("Error converting to rational: {}", e), + } + }, + Err(e) => println!("Error calculating square: {}", e), + } + }, + Err(e) => println!("Error: {}", e), + } + println!(); + } +} diff --git a/Task/P-Adic-square-roots/Zig/p-adic-square-roots.zig b/Task/P-Adic-square-roots/Zig/p-adic-square-roots.zig new file mode 100644 index 0000000000..0b7343aba7 --- /dev/null +++ b/Task/P-Adic-square-roots/Zig/p-adic-square-roots.zig @@ -0,0 +1,495 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const ArrayList = std.ArrayList; + +const PAdicSquareRoot = struct { + prime: u32, + precision: u32, + digits: ArrayList(u32), + order: i32, + allocator: Allocator, + + // Create a PAdicSquareRoot number + pub fn new(allocator: Allocator, prime: u32, precision: u32, numerator: i32, denominator: i32) !*PAdicSquareRoot { + if (denominator == 0) { + return error.DenominatorCannotBeZero; + } + + const digits_size = precision + 5; + var self = try allocator.create(PAdicSquareRoot); + self.* = PAdicSquareRoot{ + .prime = prime, + .precision = precision, + .digits = ArrayList(u32).init(allocator), + .order = 0, + .allocator = allocator, + }; + + // Process rational zero + if (numerator == 0) { + self.order = 1000; // ORDER_MAX from original code + return self; + } + + // Handle numerator and denominator + var num = numerator; + var denom = denominator; + + // Remove multiples of 'prime' and adjust the order accordingly + while (modulo(@as(i64, num), @as(i64, prime)) == 0) { + num = @divTrunc(num, @as(i32, @intCast(prime))); + self.order += 1; + } + + while (modulo(@as(i64, denom), @as(i64, prime)) == 0) { + denom = @divTrunc(denom, @as(i32, @intCast(prime))); + self.order -= 1; + } + + if ((self.order & 1) != 0) { + self.deinit(); + allocator.destroy(self); + return error.NoSquareRoot; + } + self.order >>= 1; + + // Calculate square root based on prime + if (prime == 2) { + try self.squareRootEvenPrime(num, denom); + } else { + try self.squareRootOddPrime(num, denom); + } + + // Ensure we have the right number of digits + while (self.digits.items.len < digits_size) { + try self.digits.append(0); + } + self.digits.shrinkRetainingCapacity(digits_size); + + return self; + } + + // Create a PAdicSquareRoot directly from a vector of digits + pub fn fromDigits(allocator: Allocator, prime: u32, precision: u32, digits: []const u32, order: i32) !*PAdicSquareRoot { + var self = try allocator.create(PAdicSquareRoot); + self.* = PAdicSquareRoot{ + .prime = prime, + .precision = precision, + .digits = ArrayList(u32).init(allocator), + .order = order, + .allocator = allocator, + }; + + try self.digits.appendSlice(digits); + return self; + } + + // Clean up allocated memory + pub fn deinit(self: *PAdicSquareRoot) void { + self.digits.deinit(); + } + + // Return the additive inverse of this PAdicSquareRoot number + pub fn negate(self: *const PAdicSquareRoot) !*PAdicSquareRoot { + if (self.digits.items.len == 0) { + return self.clone(); + } + + var negated = try ArrayList(u32).initCapacity(self.allocator, self.digits.items.len); + try negated.appendSlice(self.digits.items); + negateDigits(negated.items, self.prime); + + return fromDigits(self.allocator, self.prime, self.precision, negated.items, self.order); + } + + // Return a clone of this PAdicSquareRoot + pub fn clone(self: *const PAdicSquareRoot) !*PAdicSquareRoot { + var new_digits = try ArrayList(u32).initCapacity(self.allocator, self.digits.items.len); + try new_digits.appendSlice(self.digits.items); + + const result = try self.allocator.create(PAdicSquareRoot); + result.* = PAdicSquareRoot{ + .prime = self.prime, + .precision = self.precision, + .digits = new_digits, + .order = self.order, + .allocator = self.allocator, + }; + return result; + } + + // Return the product of this PAdicSquareRoot number and another PAdicSquareRoot number + pub fn multiply(self: *const PAdicSquareRoot, other: *const PAdicSquareRoot) !*PAdicSquareRoot { + if (self.prime != other.prime) { + return error.DifferentPrimes; + } + + if (self.digits.items.len == 0 or other.digits.items.len == 0) { + return new(self.allocator, self.prime, self.precision, 0, 1); + } + + const max_size = @as(usize, @intCast(self.precision + 5)); + const product_digits = try multiplyDigits( + self.allocator, + self.digits.items, + other.digits.items, + self.prime, + max_size + ); + + return fromDigits( + self.allocator, + self.prime, + self.precision, + product_digits.items, + self.order + other.order, + ); + } + + // Return a string representation of this PAdicSquareRoot as a rational number + pub fn convertToRational(self: *const PAdicSquareRoot, allocator: Allocator) ![]u8 { + if (self.digits.items.len == 0) { + return try std.fmt.allocPrint(allocator, "0 / 1", .{}); + } + + // Lagrange lattice basis reduction in two dimensions + var series_sum: i64 = @as(i64, self.digits.items[0]); + var maximum_prime: i64 = 1; + + var i: u32 = 1; + while (i < self.precision) : (i += 1) { + maximum_prime *= @as(i64, self.prime); + series_sum += @as(i64, self.digits.items[i]) * maximum_prime; + } + + var one = [_]i64{ maximum_prime, series_sum }; + var two = [_]i64{ 0, 1 }; + + var previous_norm = series_sum * series_sum + 1; + var current_norm = previous_norm + 1; + var idx_i: usize = 0; + var idx_j: usize = 1; + + while (previous_norm < current_norm) { + const numerator = one[idx_i] * one[idx_j] + two[idx_i] * two[idx_j]; + const denominator = previous_norm; + current_norm = @as(i64, @intFromFloat(@floor(@as(f64, @floatFromInt(numerator)) / @as(f64, @floatFromInt(denominator)) + 0.5))); + one[idx_i] -= current_norm * one[idx_j]; + two[idx_i] -= current_norm * two[idx_j]; + + current_norm = previous_norm; + previous_norm = one[idx_i] * one[idx_i] + two[idx_i] * two[idx_i]; + + if (previous_norm < current_norm) { + const temp = idx_i; + idx_i = idx_j; + idx_j = temp; + } + } + + var x = one[idx_j]; + var y = two[idx_j]; + if (y < 0) { + y = -y; + x = -x; + } + + if ( @abs(one[idx_i] * y - x * two[idx_i]) != maximum_prime) { + return error.RationalReconstructionFailed; + } + + var i_order = self.order; + while (i_order < 0) : (i_order += 1) { + y *= @as(i64, self.prime); + } + + i_order = 0; + while (i_order < self.order) : (i_order += 1) { + x *= @as(i64, self.prime); + } + + return try std.fmt.allocPrint(allocator, "{} / {}", .{ x, y }); + } + + // Create a 2-adic number which is the square root of the rational 'numerator' / 'denominator' + fn squareRootEvenPrime(self: *PAdicSquareRoot, numerator: i32, denominator: i32) !void { + if (modulo(@as(i64, numerator) * @as(i64, denominator), 8) != 1) { + return error.NoSquareRootInTwoAdic; + } + + // First digit + var sum: i64 = 1; + try self.digits.append(1); + + // Further digits + const digits_size = self.precision + 5; + while (self.digits.items.len < digits_size) { + const factor = @as(i64, denominator) * sum * sum - @as(i64, numerator); + var valuation: u32 = 0; + var factor_temp = factor; + while (modulo(factor_temp, 2) == 0) { + factor_temp = @divTrunc(factor_temp, 2); + valuation += 1; + } + + sum += std.math.pow(i64, 2, valuation - 1); + + while (self.digits.items.len < valuation - 1) { + try self.digits.append(0); + } + try self.digits.append(1); + } + } + + // Create a p-adic number, with an odd prime number, p = 'prime', + // which is the p-adic square root of the given rational 'numerator' / 'denominator' + fn squareRootOddPrime(self: *PAdicSquareRoot, numerator: i32, denominator: i32) !void { + // First digit + var first_digit: u32 = 0; + var i: u32 = 1; + while (i < self.prime) : (i += 1) { + if (modulo( + @as(i64, denominator) * @as(i64, i) * @as(i64, i) - @as(i64, numerator), + @as(i64, self.prime) + ) == 0) { + first_digit = i; + break; + } + } + + if (first_digit == 0) { + return error.NoSquareRoot; + } + + try self.digits.append(first_digit); + + // Further digits + const coefficient = moduloInverse( + @intCast(modulo(2 * @as(i64, denominator) * @as(i64, first_digit), @as(i64, self.prime))), + self.prime + ); + + var sum: i64 = @as(i64, first_digit); + const digits_size = self.precision + 5; + + var i_digit: u32 = 2; + while (i_digit < digits_size) : (i_digit += 1) { + // FIXED: Break down calculation into smaller operations to avoid overflow + const denom_sum = @as(i128, @as(i128, denominator)) * @as(i128, sum); + const denom_sum_squared = denom_sum * @as(i128, sum); + const subtraction = denom_sum_squared - @as(i128, numerator); + const coef_mul = @as(i128, coefficient) * subtraction; + + var next_sum = @as(i128, sum) - coef_mul; + + // Use modulo with appropriate type + const pow_prime = std.math.pow(i128, @as(i128, self.prime), @as(i128, i_digit)); + next_sum = @intCast(modulo128(next_sum, pow_prime)); + next_sum -= @as(i128, sum); + sum = @intCast(next_sum + @as(i128, sum)); + + // Calculate power for digit extraction + const pow_prime_prev = std.math.pow(i128, @as(i128, self.prime), @as(i128, i_digit - 1)); + const digit = @as(u32, @intCast(@divTrunc(next_sum, pow_prime_prev))); + try self.digits.append(digit); + } + } + + // Generate string representation of this PAdicSquareRoot + pub fn toString(self: *const PAdicSquareRoot, allocator: Allocator) ![]u8 { + var numbers = try ArrayList(u32).initCapacity(allocator, self.digits.items.len); + try numbers.appendSlice(self.digits.items); + + // Ensure we have the right number of digits + while (numbers.items.len < self.precision + 5) { + try numbers.append(0); + } + + var result = ArrayList(u8).init(allocator); + errdefer result.deinit(); + + var i: isize = @as(isize, @intCast(numbers.items.len)) - 1; + while (i >= 0) : (i -= 1) { + const digit_str = try std.fmt.allocPrint(allocator, "{}", .{numbers.items[@intCast(i)]}); + defer allocator.free(digit_str); + try result.appendSlice(digit_str); + } + + if (self.order >= 0) { + var j: i32 = 0; + while (j < self.order) : (j += 1) { + try result.append('0'); + } + try result.appendSlice(".0"); + } else { + const insert_pos = @as(i32, @intCast(result.items.len)) + self.order; + if (insert_pos >= 0) { + try result.insertSlice(@intCast(insert_pos), "."); + } else { + // If we need to insert before the start, pad with zeros + const zeros_needed = -insert_pos; + var new_result = try ArrayList(u8).initCapacity(allocator, result.items.len + @as(usize, @intCast(zeros_needed) ) + 2); + try new_result.appendSlice("0."); + var j: i32 = 0; + while (j < zeros_needed) : (j += 1) { + try new_result.append('0'); + } + try new_result.appendSlice(result.items); + result.deinit(); + result = new_result; + } + + // Remove trailing zeros + while (result.items.len > 0 and result.items[result.items.len - 1] == '0') { + _ = result.pop(); + } + } + + // Return with ellipsis at the beginning + const start_pos = if (result.items.len > self.precision + 1) + result.items.len - self.precision - 1 + else + 0; + + const final_result = try std.fmt.allocPrint(allocator, " ...{s}", .{result.items[start_pos..]}); + result.deinit(); + return final_result; + } +}; + +// Transform the given vector of digits representing a p-adic number +// into a vector which represents the negation of the p-adic number +fn negateDigits(numbers: []u32, prime: u32) void { + if (numbers.len == 0) return; + + numbers[0] = @intCast(modulo(@as(i64, prime) - @as(i64, numbers[0]), @as(i64, prime))); + var i: usize = 1; + while (i < numbers.len) : (i += 1) { + numbers[i] = prime - 1 - numbers[i]; + } +} + +// Return the list obtained by multiplying the digits of the given two lists +fn multiplyDigits( + allocator: Allocator, + one: []const u32, + two: []const u32, + prime: u32, + max_size: usize +) !ArrayList(u32) { + var product = try ArrayList(u32).initCapacity(allocator, one.len + two.len); + var i: usize = 0; + while (i < one.len + two.len) : (i += 1) { + try product.append(0); + } + + var b: usize = 0; + while (b < two.len) : (b += 1) { + var carry: u32 = 0; + var a: usize = 0; + while (a < one.len) : (a += 1) { + product.items[a + b] += one[a] * two[b] + carry; + carry = product.items[a + b] / prime; + product.items[a + b] %= prime; + } + if (b + one.len < product.items.len) { + product.items[b + one.len] = carry; + } + } + + // Truncate to max_size + if (product.items.len > max_size) { + product.shrinkRetainingCapacity(max_size); + } + + return product; +} + +// Return the multiplicative inverse of the given number modulo 'prime' +fn moduloInverse(number: u32, prime: u32) u32 { + var inverse: u32 = 1; + while (modulo(@as(i64, inverse) * @as(i64, number), @as(i64, prime)) != 1) { + inverse += 1; + } + return inverse; +} + +// Return the given number modulo 'prime' in the range 0..'prime' - 1 +fn modulo(number: i64, modulus: i64) i64 { + const div = @mod(number, modulus); + return if (div >= 0) div else div + modulus; +} + +// Added for i128 support +fn modulo128(number: i128, modulus: i128) i128 { + const div = @mod(number, modulus); + return if (div >= 0) div else div + modulus; +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer _ = gpa.deinit(); + + const tests = [_][4]i32{ + [_]i32{ 2, 20, 497, 10496 }, + [_]i32{ 5, 14, 86, 25 }, + [_]i32{ 7, 10, -19, 1 }, + }; + + for (tests) |my_test| { + const stdout = std.io.getStdOut().writer(); + try stdout.print("Number: {} / {} in {}-adic\n", .{ my_test[2], my_test[3], my_test[0] }); + + var square_root = PAdicSquareRoot.new( + allocator, + @intCast(my_test[0]), + @intCast(my_test[1]), + my_test[2], + my_test[3] + ) catch |err| { + try stdout.print("Error: {}\n\n", .{err}); + continue; + }; + defer { + square_root.deinit(); + allocator.destroy(square_root); + } + + try stdout.print("The two square roots are:\n", .{}); + + const sr_string = try square_root.toString(allocator); + defer allocator.free(sr_string); + try stdout.print(" {s}\n", .{sr_string}); + + var negated = try square_root.negate(); + defer { + negated.deinit(); + allocator.destroy(negated); + } + + const neg_string = try negated.toString(allocator); + defer allocator.free(neg_string); + try stdout.print(" {s}\n", .{neg_string}); + + var square = square_root.multiply(square_root) catch |err| { + try stdout.print("Error calculating square: {}\n\n", .{err}); + continue; + }; + defer { + square.deinit(); + allocator.destroy(square); + } + + const square_string = try square.toString(allocator); + defer allocator.free(square_string); + try stdout.print("The p-adic value is {s}\n", .{square_string}); + + const rational = square.convertToRational(allocator) catch |err| { + try stdout.print("Error converting to rational: {}\n\n", .{err}); + continue; + }; + defer allocator.free(rational); + try stdout.print("The rational value is {s}\n\n", .{rational}); + } +} diff --git a/Task/Padovan-n-step-number-sequences/EasyLang/padovan-n-step-number-sequences.easy b/Task/Padovan-n-step-number-sequences/EasyLang/padovan-n-step-number-sequences.easy index 81f4aba3ea..91ab1d2b01 100644 --- a/Task/Padovan-n-step-number-sequences/EasyLang/padovan-n-step-number-sequences.easy +++ b/Task/Padovan-n-step-number-sequences/EasyLang/padovan-n-step-number-sequences.easy @@ -1,11 +1,9 @@ t = 15 len p[] t # -proc padovan n . . +proc padovan n . if n < 2 or t < 3 - for i = 1 to t - p[i] = 1 - . + for i = 1 to t : p[i] = 1 return . padovan n - 1 @@ -19,8 +17,6 @@ proc padovan n . . for n = 2 to 8 padovan n write n & ": " - for i = 1 to t - write p[i] & " " - . + for i = 1 to t : write p[i] & " " print "" . diff --git a/Task/Pancake-numbers/PascalABC.NET/pancake-numbers.pas b/Task/Pancake-numbers/PascalABC.NET/pancake-numbers.pas new file mode 100644 index 0000000000..46d45d200b --- /dev/null +++ b/Task/Pancake-numbers/PascalABC.NET/pancake-numbers.pas @@ -0,0 +1,37 @@ +function pancake(n: integer): (integer, string); +begin + var goalstack := '123456789abcd'[:n + 1]; + var stacks := Dict((goalstack, 0)); + var newstacks := Dict((goalstack, 0)); + var numstacks := 1; + foreach var flip in 1..100 do + begin + var nextstacks := new Dictionary; + foreach var nstack in newstacks do + foreach var pos in 2..n do + begin + var newstack := nstack.key[pos::-1] + nstack.key?[pos + 1:]; + if newstack not in stacks then + nextstacks[newstack] := flip; + end; + newstacks := nextstacks; + foreach var nstack in newstacks do stacks[nstack.key] := nstack.value; + var perms := stacks.Count; + if perms = numstacks then + begin + result := stacks.Where(x -> x.value = flip - 1) + .Select(k -> (k.value, k.key)) + .First; + exit + end; + numstacks := perms + end; +end; + +begin + foreach var n in 1..11 do + begin + var (steps, example) := pancake(n); + writeln('pancake(', n:2, ') = ', steps:2, ' example: ', example); + end; +end. diff --git a/Task/Pangram-checker/PascalABC.NET/pangram-checker.pas b/Task/Pangram-checker/PascalABC.NET/pangram-checker.pas new file mode 100644 index 0000000000..5c62d5f862 --- /dev/null +++ b/Task/Pangram-checker/PascalABC.NET/pangram-checker.pas @@ -0,0 +1,8 @@ +const + alphabet = 'abcdefghijklmnopqrstuvwxyz'; + +function ispangram(text: string) := alphabet.All(c -> text.Contains(c)); + +begin + ispangram('The quick brown fox jumps over the lazy dog').Println; +end. diff --git a/Task/Pangram-checker/Uiua/pangram-checker.uiua b/Task/Pangram-checker/Uiua/pangram-checker.uiua new file mode 100644 index 0000000000..9c9d2ae82d --- /dev/null +++ b/Task/Pangram-checker/Uiua/pangram-checker.uiua @@ -0,0 +1,8 @@ +IsPangram ← /ט∊+@A⇡26⌵ + +┌─╴test + ⍤⤙≍ 1 IsPangram "The quick brown fox jumps over the lazy dog." + ⍤⤙≍ 1 IsPangram "QwErTyUiOp-AsDfGhJkL-zXcVbNm" + ⍤⤙≍ 0 IsPangram "The quick brown fox jumped over the lazy dog." + ⍤⤙≍ 0 IsPangram "This is a sentence." +└─╴ diff --git a/Task/Paraffins/PascalABC.NET/paraffins.pas b/Task/Paraffins/PascalABC.NET/paraffins.pas new file mode 100644 index 0000000000..7661591095 --- /dev/null +++ b/Task/Paraffins/PascalABC.NET/paraffins.pas @@ -0,0 +1,50 @@ +const + nMax = 250; + nBranches = 4; + +var + rooted := (0..nMax).Select(n -> 0bi).ToArray; + unrooted := (0..nMax).Select(n -> 0bi).ToArray; + +function choose(m: biginteger; k: integer): biginteger; +begin + result := m; + if k = 1 then exit + else + for var i := 1 to k - 1 do + result := result * (m + i) div (i + 1) +end; + +procedure tree(br, n, l, sum: integer; cnt: biginteger); +begin + var s := 0; + foreach var b in (br + 1.. nBranches) do + begin + s := sum + (b - br) * n; + if s > nMax then exit; + + var c := choose(rooted[n], b - br) * cnt; + + if l * 2 < s then unrooted[s] += c; + if b = nBranches then exit; + rooted[s] += c; + for var m := n - 1 downto 1 do + tree(b, m, l, s, c); + end; +end; + +procedure bicenter(s: integer); +begin + if (s and 1) = 0 then + unrooted[s] += rooted[s div 2] * (rooted[s div 2] + 1) div 2; +end; + +begin + (rooted[0], rooted[1], unrooted[0], unrooted[1]) := (1bi, 1bi, 1bi, 1bi); + for var n := 1 to nMax do + begin + tree(0, n, n, 1, 1bi); + bicenter(n); + writeln(n, ': ', unrooted[n]); + end; +end. diff --git a/Task/Parallel-calculations/PascalABC.NET/parallel-calculations.pas b/Task/Parallel-calculations/PascalABC.NET/parallel-calculations.pas new file mode 100644 index 0000000000..c43295f6ae --- /dev/null +++ b/Task/Parallel-calculations/PascalABC.NET/parallel-calculations.pas @@ -0,0 +1,24 @@ +uses school; + +const + n = |12757923, 12878611, 12757923, 15808973, 15780709, 197622519|; + +begin + var j := 0; + var m := 0; + var l := new list[n.Length]; + {$omp parallel for} + for var i := 0 to n.Length - 1 do + l[i] := primefactors(n[i]); + + for var i := 0 to n.Length - 1 do + if l[i].Min > m then + begin + m := l[i].Min; + j := i; + end; + + WriteLn('Number ', n[j], ' has largest minimal factor:'); + foreach var list in l[j] do + Write(' ' + list); +end. diff --git a/Task/Parametric-polymorphism/00-TASK.txt b/Task/Parametric-polymorphism/00-TASK.txt index 9924d41a1d..c12cb103a1 100644 --- a/Task/Parametric-polymorphism/00-TASK.txt +++ b/Task/Parametric-polymorphism/00-TASK.txt @@ -1,4 +1,4 @@ -[[wp:Parametric Polymorphism|Parametric Polymorphism]] is a way to define types or functions that are generic over other types. The genericity can be expressed by using ''type variables'' for the parameter type, and by a mechanism to explicitly or implicitly replace the type variables with concrete types when necessary. +[[wp:Parametric polymorphism|Parametric polymorphism]] is a way to define types or functions that are generic over other types. The genericity can be expressed by using ''type variables'' for the parameter type, and by a mechanism to explicitly or implicitly replace the type variables with concrete types when necessary. ;Task: diff --git a/Task/Parametric-polymorphism/C3/parametric-polymorphism-1.c3 b/Task/Parametric-polymorphism/C3/parametric-polymorphism-1.c3 index 73092184fd..86363c0951 100644 --- a/Task/Parametric-polymorphism/C3/parametric-polymorphism-1.c3 +++ b/Task/Parametric-polymorphism/C3/parametric-polymorphism-1.c3 @@ -1,4 +1,4 @@ -module tree(); +module tree {Type}; struct Tree { diff --git a/Task/Parametric-polymorphism/C3/parametric-polymorphism-2.c3 b/Task/Parametric-polymorphism/C3/parametric-polymorphism-2.c3 index bf7a6c9501..f9dac4f3bd 100644 --- a/Task/Parametric-polymorphism/C3/parametric-polymorphism-2.c3 +++ b/Task/Parametric-polymorphism/C3/parametric-polymorphism-2.c3 @@ -2,6 +2,6 @@ import tree; fn void test() { - Tree() inttree; + Tree {int} inttree; inttree.replace_all(3); } diff --git a/Task/Parse-an-IP-Address/Erlang/parse-an-ip-address.erl b/Task/Parse-an-IP-Address/Erlang/parse-an-ip-address.erl new file mode 100644 index 0000000000..454b25b2d1 --- /dev/null +++ b/Task/Parse-an-IP-Address/Erlang/parse-an-ip-address.erl @@ -0,0 +1,53 @@ +#!/usr/bin/env escript +-module(ipparse). + +-export([main/1]). + +main([]) -> + [print(A, parse(A)) || A <- data()], + erlang:halt(0); +main(Args) -> + [print(A, parse(A)) || A <- Args], + erlang:halt(0). + +-spec parse(Input :: string()) -> + {Family :: 'IPv6' | 'IPv4', Hex :: binary(), Port :: string()} | + {Family :: 'IPv6' | 'IPv4', Hex :: binary()}. +parse([$[ | Addr0]) -> + case string:split(Addr0, "]", trailing) of + [Addr] -> + {"IPv6", to_hex(inet:parse_address(Addr))}; + [Addr, [$: | Port]] -> + {"IPv6", to_hex(inet:parse_address(Addr)), Port} + end; +parse(Addr0) -> + case inet:parse_address(Addr0) of + {error, einval} -> + [Addr, Port] = string:split(Addr0, ":", trailing), + {"IPv4", to_hex(inet:parse_address(Addr)), Port}; + {ok, V6Addr} -> + {"IPv6", to_hex({ok, V6Addr})} + end. + +-spec to_hex({ok, inet:ip_address()}) -> Hex :: binary(). +to_hex({ok, {A,B,C,D}}) -> + binary:encode_hex(<>); +to_hex({ok, {A,B,C,D,E,F,G,H}}) -> + binary:encode_hex(<>). + +print(Input, {Family, Hex, Port}) -> + io:format("Input: ~s~nFamily: ~s~nHex: ~s~nPort: ~s~n~n", + [Input, Family, Hex, Port]); +print(Input, {Family, Hex}) -> + io:format("Input: ~s~nFamily: ~s~nHex: ~s~n~n", + [Input, Family, Hex]). + +data() -> + ["127.0.0.1", + "127.0.0.1:80", + "::ffff:127.0.0.1", + "::1", + "[::1]:80", + "1::80", + "2605:2700:0:3::4713:93e3", + "[2605:2700:0:3::4713:93e3]:80"]. diff --git a/Task/Parse-an-IP-Address/Lua/parse-an-ip-address-1.lua b/Task/Parse-an-IP-Address/Lua/parse-an-ip-address-1.lua new file mode 100644 index 0000000000..5c87c4d6e6 --- /dev/null +++ b/Task/Parse-an-IP-Address/Lua/parse-an-ip-address-1.lua @@ -0,0 +1,158 @@ +local Format = string.format +local tonumber = tonumber +local ipairs = ipairs +local Rep = string.rep + +-- there is no | so this is the best we can do in pure lua patt +local ipv4_addr_patt = "[12]?%d?%d%.[12]?%d?%d%.[12]?%d?%d%.[12]?%d?%d" +local ipv4_patt = "^(" .. ipv4_addr_patt .. "):?(%d*)$" + +-- ipv4 -> addr?, port? +local V4Parse = function (ipv4) + local addr, port = ipv4:match(ipv4_patt) + if addr then + for digitS in addr:gmatch"%d+" do + if tonumber(digitS)>255 then return nil end + end + end + return addr, port +end + +-- no check +local V4ToHex = function (ipv4_addr) + local hex = Format( + "%.2x%.2x%.2x%.2x" + , ipv4_addr:match"^(%d+)%.(%d+)%.(%d+)%.(%d+)$" + ) + return hex, tonumber("0x" .. hex) +end + +-- ipv4_address -> addr?, port?, hex? +local V4 = function (ipv4) -- "address:port" -> address:str|nil, port:str|nil, hex:str|nil + local addr, port = V4Parse(ipv4) + if addr then + return addr, port, V4ToHex(addr) + end + return nil +end + +--------------------------------- IPV6 Section +local ipv6_patternsT do + local v6 = "([%x:]*:[%x:]*:[%x:]*)" + local v64 = "([%x:]*:[%x:]*:" .. ipv4_addr_patt .. ")" + + ipv6_patternsT = { -- these are guessers/approximators + -- [addr] + "^%[" .. v6 .. "%]:(%d+)$" -- [v6]:port + ,"^%[" .. v6 .. "%]$" -- [v6] + ,"^%[" .. v64 .. "%]:(%d+)$" -- [v6+v4]:port + ,"^%[" .. v64 .. "%]$" -- [v6+v4] + + -- guesswork + ,"^" .. v64 .. ":(%d+)$" -- v6+v4+port + -- TODO: unsure if v6+v4[#p:.]port is valid + + ,"^(" .. v64 .. ")$" -- v6+v4 + + ,"^" .. v6 .. "[.p#](%d+)$" -- v6+port + -- portsep=":" handled bellow + -- There is no way to use port while using : as the port separator + -- the only method is if its complete or if its :::80 + , "^([%x:]*::):(%d+)$" -- v6+port + -- Complete + ,"^(" .. ("%x*:"):rep(7) .. "%x*):(%d+)$" -- v6+port + + ,"^" .. v6 .. "$" -- v6 + } +end + +-- addr, port -- nil if failure +-- addr will be returned as +-- ipv6_address port -> address, port, mini hexified address (no ipv4) +local V6Parse = function (ipv6_address) + -- get the port, then get the ip via position + for _,match in ipairs(ipv6_patternsT) do + local address, port = ipv6_address:match(match) + if address then + local addr = address -- addr is going to be in ipv6 hex (no ipv4) + if -- valid ipv6 address? +-- select(2, addr:gsub(":",""))==1 -- this shouldn't happen + -- 2 :: + addr:match"::.+::" + -- 3 ::: + or addr:match":::" + -- 4 %x per non [^:] ONLY + or addr:match"%x%x%x%x%x" + then + return nil + end + local v6,v4 = addr:match("^([%x:]+:)(%d+%.%d+%.%d+%.%d+)$") + if v4 and V4Parse(v4) then + addr = Format("%s%s:%s", v6, V4ToHex(v4):match"^(....)(....)$") + end + if addr:gsub(":", "", 7):match":" then return nil end + return address, port, addr + end + end + return nil, nil +end + +-- Returns ipv6 address filled (0:0:0:0:0) instead of :: +local V6Fill = function (addr) -- addr must be hexified +-- fill :: + if addr:match"::" then + local _, count = addr:gsub(":+","") + addr = addr:gsub("::" + ,(addr:match"^::" and "0000:" or ":") + .. Rep("0", 8-count,":") + ,1 + ) + end + +-- fill 0 + addr = addr:gsub("[^:]+" + ,function (section) + return Format("%.4x",tonumber("0x" .. section)) + end + ) + + return addr +end + +-- cannot return num after fff:ffff:ffff:ffff +-- this is dependant on tonumber() itself +local V6ToHex = function (addr) + local ipv6 = V6Fill(addr) + local hex = ipv6:gsub(":","") + local num do -- tonumber fails after 3: + local x = hex:gsub("^0+", "") + if #x<=15 then + num = x=="" and 0 or tonumber("0x" .. x) + end + end + return hex, num or -1, ipv6 -- cannot tonumber hex too big +end + +-- ipv6_address -> addr?, port?, hex? +local V6 = function (address) + local addr, port, ipv6 = V6Parse(address) + if addr then + return addr, port, V6ToHex(ipv6) + end + return addr, port +end + +local IpToHex = function (address) + if address:match(ipv4_patt) then + return 4, V4(address) + end + return 6, V6(address) +end + +for _, addr in ipairs{ + "127.0.0.1", "127.0.0.1:80", "::1", "[::1]:80", + "2605:2700:0:3::4713:93e3", + "[2605:2700:0:3::4713:93e3]:80" +} do + print(IpToHex(addr)) +end diff --git a/Task/Parse-an-IP-Address/Lua/parse-an-ip-address-2.lua b/Task/Parse-an-IP-Address/Lua/parse-an-ip-address-2.lua new file mode 100644 index 0000000000..755c4744c9 --- /dev/null +++ b/Task/Parse-an-IP-Address/Lua/parse-an-ip-address-2.lua @@ -0,0 +1,6 @@ +4 127.0.0.1 7f000001 2130706433 +4 127.0.0.1 80 7f000001 2130706433 +6 ::1 nil 00000000000000000000000000000001 1 0000:0000:0000:0000:0000:0000:0000:0001 +6 ::1 80 00000000000000000000000000000001 1 0000:0000:0000:0000:0000:0000:0000:0001 +6 2605:2700:0:3::4713:93e3 nil 260527000000000300000000471393e3 -1 2605:2700:0000:0003:0000:0000:4713:93e3 +6 2605:2700:0:3::4713:93e3 80 260527000000000300000000471393e3 -1 2605:2700:0000:0003:0000:0000:4713:93e3 diff --git a/Task/Parsing-RPN-calculator-algorithm/PascalABC.NET/parsing-rpn-calculator-algorithm.pas b/Task/Parsing-RPN-calculator-algorithm/PascalABC.NET/parsing-rpn-calculator-algorithm.pas new file mode 100644 index 0000000000..b6949afe1d --- /dev/null +++ b/Task/Parsing-RPN-calculator-algorithm/PascalABC.NET/parsing-rpn-calculator-algorithm.pas @@ -0,0 +1,15 @@ +## +var a := new Stack; +var b := new Dictionary real>; +b['+'] := (x, y) -> y + x; +b['-'] := (x, y) -> y - x; +b['*'] := (x, y) -> y * x; +b['/'] := (x, y) -> y / x; +b['^'] := (x, y) -> y ** x; + +foreach var c in '3 4 2 * 1 5 - 2 3 ^ ^ / +'.Split do +begin + if c in b then a.Push(b[c](a.Pop, a.Pop)) + else a.Push(c.ToReal); + println(c, a); +end; diff --git a/Task/Parsing-RPN-calculator-algorithm/Zig/parsing-rpn-calculator-algorithm.zig b/Task/Parsing-RPN-calculator-algorithm/Zig/parsing-rpn-calculator-algorithm.zig new file mode 100644 index 0000000000..cd70ad3288 --- /dev/null +++ b/Task/Parsing-RPN-calculator-algorithm/Zig/parsing-rpn-calculator-algorithm.zig @@ -0,0 +1,57 @@ +const std = @import("std"); + +fn rpn(text: []const u8, allocator: std.mem.Allocator) !f64 { + var tokens = std.mem.splitScalar(u8, text, ' '); + var stack = std.ArrayList(f64).init(allocator); + defer stack.deinit(); + + std.debug.print("input operation stack\n", .{}); + + while (tokens.next()) |token| { + if (token.len == 0) continue; + + std.debug.print("{s:^5} ", .{token}); + + const num = std.fmt.parseFloat(f64, token) catch { + if (stack.items.len < 2) { + return error.NotEnoughOperands; + } + + const b = stack.pop().?; + const a = stack.pop().?; + + if (std.mem.eql(u8, token, "+")) { + try stack.append(a + b); + } else if (std.mem.eql(u8, token, "-")) { + try stack.append(a - b); + } else if (std.mem.eql(u8, token, "*")) { + try stack.append(a * b); + } else if (std.mem.eql(u8, token, "/")) { + try stack.append(a / b); + } else if (std.mem.eql(u8, token, "^")) { + try stack.append(std.math.pow(f64, a, b)); + } else { + std.debug.panic("unknown operator {s}", .{token}); + } + + std.debug.print("calculate {any}\n", .{stack.items}); + continue; + }; + + try stack.append(num); + std.debug.print("push {any}\n", .{stack.items}); + } + + return if (stack.items.len > 0) stack.pop().? else 0.0; +} + +pub fn main() !void { + const text = "3 4 2 * 1 5 - 2 3 ^ ^ / +"; + + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + const result = try rpn(text, allocator); + std.debug.print("\nresult: {d}\n", .{result}); +} diff --git a/Task/Parsing-Shunting-yard-algorithm/Zig/parsing-shunting-yard-algorithm.zig b/Task/Parsing-Shunting-yard-algorithm/Zig/parsing-shunting-yard-algorithm.zig new file mode 100644 index 0000000000..c3ff757afe --- /dev/null +++ b/Task/Parsing-Shunting-yard-algorithm/Zig/parsing-shunting-yard-algorithm.zig @@ -0,0 +1,343 @@ +const std = @import("std"); +const print = std.debug.print; +const stdin = std.io.getStdIn().reader(); + +const StrTok = struct { + s: []const u8, + len: usize, + prec: i32, + assoc: i32, +}; + +const Pattern = struct { + str: []const u8, + assoc: i32 = 0, + prec: i32 = 0, +}; + +const Assoc = struct { + pub const NONE: i32 = 0; + pub const L: i32 = 1; + pub const R: i32 = 2; +}; + +const pat_eos = Pattern{ .str = "" }; + +const pat_ops = [_]Pattern{ + Pattern{ .str = ")", .assoc = Assoc.NONE, .prec = -1 }, + Pattern{ .str = "**", .assoc = Assoc.R, .prec = 3 }, + Pattern{ .str = "^", .assoc = Assoc.R, .prec = 3 }, + Pattern{ .str = "*", .assoc = Assoc.L, .prec = 2 }, + Pattern{ .str = "/", .assoc = Assoc.L, .prec = 2 }, + Pattern{ .str = "+", .assoc = Assoc.L, .prec = 1 }, + Pattern{ .str = "-", .assoc = Assoc.L, .prec = 1 }, + Pattern{ .str = "" }, +}; + +const pat_arg = [_]Pattern{ + Pattern{ .str = "number" }, // This will be matched differently + Pattern{ .str = "identifier" }, // This will be matched differently + Pattern{ .str = "(", .assoc = Assoc.L, .prec = -1 }, + Pattern{ .str = "" }, +}; + +const MAX_STACK = 128; +const MAX_QUEUE = 128; + +var stack: [MAX_STACK]StrTok = undefined; +var queue: [MAX_QUEUE]StrTok = undefined; +var l_queue: usize = 0; +var l_stack: usize = 0; +var prec_booster: i32 = 0; + +fn qpush(tok: StrTok) !void { + if (l_queue >= MAX_QUEUE) { + return error.QueueOverflow; + } + queue[l_queue] = tok; + l_queue += 1; +} + +fn spush(tok: StrTok) !void { + if (l_stack >= MAX_STACK) { + return error.StackOverflow; + } + stack[l_stack] = tok; + l_stack += 1; +} + +fn spop() StrTok { + if (l_stack == 0) { + @panic("Stack underflow"); + } + l_stack -= 1; + return stack[l_stack]; +} + +fn display(s: []const u8) !void { + print("\x1b[1;1H\x1b[JText | {s}\n", .{s}); + print("Stack| ", .{}); + + for (stack[0..l_stack]) |item| { + print("{s} ", .{item.s[0..item.len]}); + } + + print("\nQueue| ", .{}); + for (queue[0..l_queue]) |item| { + print("{s} ", .{item.s[0..item.len]}); + } + + print("\n\n\n", .{}); + var buf: [1]u8 = undefined; + _ = try stdin.read(&buf); +} + +fn fail(s1: []const u8, s2: []const u8) !bool { + print("[Error {s}] {s}\n", .{ s1, s2 }); + return error.ParseError; +} + +// Helper function to check if a character is a digit +fn isDigit(c: u8) bool { + return c >= '0' and c <= '9'; +} + +// Helper function to check if a character is a letter +fn isAlpha(c: u8) bool { + return (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z'); +} + +// Helper function to check if a character is alphanumeric or underscore +fn isAlnum(c: u8) bool { + return isAlpha(c) or isDigit(c) or c == '_'; +} + +fn match(s: []const u8, patterns: []const Pattern, tok: *StrTok) ?struct { pattern: *const Pattern, end_pos: usize } { + var pos: usize = 0; + + // Skip whitespace + while (pos < s.len and s[pos] == ' ') { + pos += 1; + } + + if (pos >= s.len) { + return null; + } + + const remaining = s[pos..]; + + // Check for numeric literals + if (remaining.len > 0 and (isDigit(remaining[0]) or + ((remaining[0] == '-' or remaining[0] == '+') and remaining.len > 1 and isDigit(remaining[1])) or + (remaining[0] == '.' and remaining.len > 1 and isDigit(remaining[1])))) { + + var i: usize = 0; + var hasDot = false; + var hasExp = false; + + // Handle sign + if (i < remaining.len and (remaining[i] == '-' or remaining[i] == '+')) { + i += 1; + } + + // Process digits before decimal point + while (i < remaining.len and isDigit(remaining[i])) { + i += 1; + } + + // Process decimal point and digits after it + if (i < remaining.len and remaining[i] == '.') { + hasDot = true; + i += 1; + while (i < remaining.len and isDigit(remaining[i])) { + i += 1; + } + } + + // Process exponent + if (i < remaining.len and (remaining[i] == 'e' or remaining[i] == 'E')) { + hasExp = true; + i += 1; + + // Optional sign for exponent + if (i < remaining.len and (remaining[i] == '-' or remaining[i] == '+')) { + i += 1; + } + + // There must be at least one digit in the exponent + if (i < remaining.len and isDigit(remaining[i])) { + i += 1; + while (i < remaining.len and isDigit(remaining[i])) { + i += 1; + } + } else if (hasExp) { + // Invalid exponent + return null; + } + } + + if (i > 0) { + tok.s = remaining; + tok.len = i; + return .{ .pattern = &pat_arg[0], .end_pos = pos + i }; + } + } + + // Check for identifiers + if (remaining.len > 0 and (isAlpha(remaining[0]) or remaining[0] == '_')) { + var i: usize = 1; + while (i < remaining.len and isAlnum(remaining[i])) { + i += 1; + } + + tok.s = remaining; + tok.len = i; + return .{ .pattern = &pat_arg[1], .end_pos = pos + i }; + } + + // Check for operators and parentheses + for (patterns) |p| { + if (p.str.len == 0) break; + + if (p.str[0] != '^') { // Not a special pattern like "number" or "identifier" + if (remaining.len >= p.str.len and std.mem.eql(u8, remaining[0..p.str.len], p.str)) { + tok.s = remaining; + tok.len = p.str.len; + return .{ .pattern = &p, .end_pos = pos + p.str.len }; + } + } + } + + return null; +} + +fn parse(text: []const u8) !bool { + var tok = StrTok{ .s = undefined, .len = 0, .prec = 0, .assoc = 0 }; + var pos: usize = 0; + + prec_booster = 0; + l_queue = 0; + l_stack = 0; + + try display(text); + + while (pos < text.len) { + const match_arg = match(text[pos..], &pat_arg, &tok); + if (match_arg == null) { + return try fail("parse arg", text[pos..]); + } + + const p_arg = match_arg.?.pattern; + pos = pos + (match_arg.?.end_pos - pos); + + // Don't stack the parens + if (std.mem.eql(u8, p_arg.str, "(")) { + prec_booster += 100; + } else { + try qpush(tok); + try display(text); + } + + // Check if we reached the end of the string + if (pos >= text.len) { + if (prec_booster != 0) { + return try fail("unmatched (", "end of string"); + } + + // If there are still operators on the stack, pop them all + while (l_stack > 0) { + try qpush(spop()); + try display(text); + } + + return true; + } + + re_op: { + const match_op = match(text[pos..], &pat_ops, &tok); + if (match_op == null) { + return try fail("parse op", text[pos..]); + } + + const p_op = match_op.?.pattern; + pos = pos + (match_op.?.end_pos - pos); + + tok.assoc = p_op.assoc; + tok.prec = p_op.prec; + + if (p_op.prec > 0) { + tok.prec = p_op.prec + prec_booster; + } else if (p_op.prec == -1) { + if (prec_booster < 100) { + return try fail("unmatched )", text[pos..]); + } + tok.prec = prec_booster; + } + + while (l_stack > 0) { + const t = &stack[l_stack - 1]; + if (!((t.prec == tok.prec and t.assoc == Assoc.L) or t.prec > tok.prec)) { + break; + } + try qpush(spop()); + try display(text); + } + + if (p_op.prec == -1) { + prec_booster -= 100; + break :re_op; + } + + if (p_op.prec == 0) { + try display(text); + if (prec_booster != 0) { + return try fail("unmatched (", text[pos..]); + } + return true; + } + + try spush(tok); + try display(text); + } + } + + return true; +} + +pub fn main() !void { + const tests = [_][]const u8{ + "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3", + "123", + "3+4 * 2 / ( 1 - 5 ) ^ 2 ^ 3.14", + "(((((((1+2+3**(4 + 5))))))", + "a^(b + c/d * .1e5)", // Removed '!' which was causing an error + "(1**2)**3", + "2 + 2 *", + }; + + for (tests) |test_str| { + print("Testing string `{s}' \n", .{test_str}); + var buf: [1]u8 = undefined; + _ = try stdin.read(&buf); + + const result = parse(test_str) catch |err| { + switch (err) { + error.ParseError => { + print("string `{s}': Error\n\n", .{test_str}); + continue; + }, + error.StackOverflow => { + print("string `{s}': Stack Overflow Error\n\n", .{test_str}); + continue; + }, + error.QueueOverflow => { + print("string `{s}': Queue Overflow Error\n\n", .{test_str}); + continue; + }, + else => return err, + } + }; + + print("string `{s}': {s}\n\n", .{ test_str, if (result) "Ok" else "Error" }); + } +} diff --git a/Task/Particle-fountain/EasyLang/particle-fountain.easy b/Task/Particle-fountain/EasyLang/particle-fountain.easy index 7fe0380628..64c00aeeb7 100644 --- a/Task/Particle-fountain/EasyLang/particle-fountain.easy +++ b/Task/Particle-fountain/EasyLang/particle-fountain.easy @@ -1,10 +1,12 @@ rad = 0.125 n = 6000 # -len x[] n ; len y[] n -len vx[] n ; len vy[] n -background 059 -color 999 +len x[] n +len y[] n +len vx[] n +len vy[] n +gbackground 059 +gcolor 999 on animate for i = 1 to 32 ind = (ind + 1) mod1 n @@ -13,11 +15,11 @@ on animate vx[ind] = (randomf - 0.5) * 0.4 vy[ind] = 2 + randomf * 0.1 . - clear + gclear for i = 1 to n - move x[i] y[i] - circle rad - x[i] += vx[i] ; y[i] += vy[i] + gcircle x[i] y[i] rad + x[i] += vx[i] + y[i] += vy[i] vy[i] -= 0.025 . . diff --git a/Task/Partition-an-integer-x-into-n-primes/BASIC/partition-an-integer-x-into-n-primes.basic b/Task/Partition-an-integer-x-into-n-primes/BASIC/partition-an-integer-x-into-n-primes.basic new file mode 100644 index 0000000000..8c6d9030b2 --- /dev/null +++ b/Task/Partition-an-integer-x-into-n-primes/BASIC/partition-an-integer-x-into-n-primes.basic @@ -0,0 +1,33 @@ +10 DIM P%(13000),PR(30),I%(50),N(50),NP%(50),CP(50): MP=99809! +20 FOR P=2 TO SQR(MP) +30 PRINT CHR$(13);"Sieving... ";P; +40 FOR C=P*P TO MP STEP P +50 B=FIX(C/8): V=C-B*8 +60 P%(B) = P%(B) OR 2^V +70 NEXT C,P +80 PRINT CHR$(13);"Sieving done " +90 READ N,NP% +100 IF N=0 THEN END +110 PRINT:PRINT "Partitioning";N;"with";NP%;"primes:" +120 S=1: N(0)=N: NP%(0)=NP%: I%(0)=1: CP(0)=1 +130 IF S=0 THEN PRINT CHR$(13);"Impossible":GOTO 90 +140 S=S-1: N=N(S): NP%=NP%(S): I%=I%(S): CP=CP(S) +150 CP=CP+1 +160 B=FIX(CP/8):V=CP-B*8 +170 IF P%(B) AND 2^V GOTO 150 +175 PRINT CHR$(13);"@";CP; +180 IF N n - return - . + if p > n : return find (n - p) (k - 1) (i + 1) found r[] if found = 1 swap res[] r[] @@ -45,9 +39,7 @@ for i to len test[][] find test[i][1] test[i][2] 1 f res[] write test[i][1] & "(" & test[i][2] & ") = " if f = 1 - for j = len res[] downto 2 - write res[j] & " + " - . + for j = len res[] downto 2 : write res[j] & " + " print res[1] else print "not possible" diff --git a/Task/Partition-an-integer-x-into-n-primes/PascalABC.NET/partition-an-integer-x-into-n-primes.pas b/Task/Partition-an-integer-x-into-n-primes/PascalABC.NET/partition-an-integer-x-into-n-primes.pas new file mode 100644 index 0000000000..ce20293691 --- /dev/null +++ b/Task/Partition-an-integer-x-into-n-primes/PascalABC.NET/partition-an-integer-x-into-n-primes.pas @@ -0,0 +1,22 @@ +uses School; + +function primepartition(x, n: Integer): List; +begin + result := new List; + foreach var combo in Primes(x).Combinations(n) do + if combo.Sum = x then + begin + result := combo.ToList; + exit + end; +end; + +begin + foreach var (x, n) in |(18, 2), (19, 3), (20, 4), (99807, 1), (99809, 1), + (2017, 24), (22699, 1), (22699, 2), (22699, 3), (22699, 4), (40355, 3)| do + begin + var ans := primepartition(x, n); + writeln('Partitioned', x:6, ' with', n:3, ' primes: ', + if ans.Count = 0 then 'impossible' else ans.JoinToString('+')); + end +end. diff --git a/Task/Partition-an-integer-x-into-n-primes/REXX/partition-an-integer-x-into-n-primes.rexx b/Task/Partition-an-integer-x-into-n-primes/REXX/partition-an-integer-x-into-n-primes.rexx index 63c2dbad83..8aad9f391a 100644 --- a/Task/Partition-an-integer-x-into-n-primes/REXX/partition-an-integer-x-into-n-primes.rexx +++ b/Task/Partition-an-integer-x-into-n-primes/REXX/partition-an-integer-x-into-n-primes.rexx @@ -1,52 +1,85 @@ -/*REXX program partitions integer(s) (greater than unity) into N primes. */ -parse arg what /*obtain an optional list from the C.L.*/ +-- 8 May 2025 +include Settings - do until what=='' /*possibly process a series of integers*/ - parse var what x n what; parse var x x '-' y /*get possible range and # partitions.*/ - parse var n n '-' m /* " " " " " " */ - if x=='' | x=="," then x= 19 /*Not specified? Then use the default.*/ - if y=='' | y=="," then y= x /* " " " " " " */ - if n=='' | n=="," then n= 3 /* " " " " " " */ - if m=='' | m=="," then m= n /* " " " " " " */ - call genP y /*generate Y number of primes. */ - do g=x to y /*partition X ───► Y into partitions.*/ - do q=n to m; call part /* " G into Q primes. */ - end /*q*/ - end /*g*/ - end /*until*/ +say 'PARTITION AN INTEGER X INTO N PRIMES' +say version +say +call GetPrimes 100000 +call ShowPartition 99809,1 +call ShowPartition 18,2 +call ShowPartition 19,3 +call ShowPartition 20,4 +call ShowPartition 2017,24 +call ShowPartition 22699,1 +call ShowPartition 22699,2 +call ShowPartition 22699,3 +call ShowPartition 22699,4 +call ShowPartition 40355,3 +exit -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: arg high; @.1= 2; @.2= 3; #= 2 /*get highest prime, assign some vars. */ - do j=@.#+2 by 2 until @.#>high /*only find odd primes from here on. */ - do k=2 while k*k<=j /*divide by some known low odd primes. */ - if j // @.k==0 then iterate j /*Is J divisible by P? Then ¬ prime.*/ - end /*k*/ /* [↓] a prime (J) has been found. */ - #= # + 1; @.#= j /*bump prime count; assign prime to @.*/ - end /*j*/; return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -getP: procedure expose i. p. @.; parse arg z /*bump the prime in the partition list.*/ - if i.z==0 then do; _= z - 1; i.z= i._; end - i.z= i.z + 1; _= i.z; p.z= @._; return 0 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -list: _= p.1; if $==g then do j=2 to q; _= _ p.j - end /*j*/ - else _= '__(not_possible)' - return 'prime' || word("s", 1 + (q==1)) translate(_, '+ ', " _") /*plural? */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -part: i.= 0; do j=1 for q; call getP j - end /*j*/ +GetPrimes: +procedure expose prim. +arg xx +call Time('r') +say 'Get primes up to' xx'...' +call Primes xx +say Format(Time('e'),,3) 'seconds'; say +return - do !=0 by 0; $= 0 /*!: a DO variable for LEAVE & ITERATE*/ - do s=1 for q; $= $ + p.s /* [↓] is sum of the primes too large?*/ - if $>g then do; if s==1 then leave ! /*perform a quick exit?*/ - do k=s to q; i.k= 0; end /*k*/ - do r=s-1 to q; call getP r; end /*r*/ - iterate ! - end - end /*s*/ - if $==g then leave /*is sum of the primes exactly right ? */ - if $ xx then do + do i = yy by -1 to 2 while s > xx + i1 = i-1; a = work.i1+1 + if prim.a > xx then + leave z + work.i1 = a + do j = i to yy + a = a+1; work.j = a + end + s = Sumwork(yy) + end + end + end +end +if s = xx then do + p = work.1; z = prim.p + do i = 2 to yy + p = work.i; z = z'+'prim.p + end +end +else do + z = 'not possible' +end +say xx 'partitioned into' yy 'primes is' z +say Format(Time('e'),,3) 'seconds'; say +return + +Sumwork: +procedure expose prim. work. +arg yy +s = 0 +do i = 1 to yy + a = work.i; p = prim.a; s = s+p +end +return s + +include Sequences +include Functions +include Constants +include Abend diff --git a/Task/Partition-an-integer-x-into-n-primes/Raku/partition-an-integer-x-into-n-primes.raku b/Task/Partition-an-integer-x-into-n-primes/Raku/partition-an-integer-x-into-n-primes.raku index 2808ee71cd..0cf1c50e59 100644 --- a/Task/Partition-an-integer-x-into-n-primes/Raku/partition-an-integer-x-into-n-primes.raku +++ b/Task/Partition-an-integer-x-into-n-primes/Raku/partition-an-integer-x-into-n-primes.raku @@ -1,17 +1,20 @@ -use Math::Primesieve; -my $sieve = Math::Primesieve.new; - # short circuit for '1' partition multi partition ( Int $number, 1 ) { $number.is-prime ?? $number !! () } -multi partition ( Int $number, Int $parts where * > 0 = 2 ) { - my @these = $sieve.primes($number); - for @these.combinations($parts) { .return if .sum == $number }; +my @primes = lazy (^Inf).grep: &is-prime; + +multi partition ( Int $number, Int $parts where * > 1 = 2 ) { + my @these = @primes[^($number div $parts)]; + shift @these if (($number %% 2) && ($parts %% 2)) || (($number % 2) && ($parts % 2)); + for @these.combinations($parts - 1) { + my $maybe = $number - .sum; + return (|$_, $maybe) if $maybe.is-prime && ($maybe ∉ $_) + }; () } # TESTING -(18,2, 19,3, 20,4, 99807,1, 99809,1, 2017,24, 22699,1, 22699,2, 22699,3, 22699,4, 40355,3)\ +(18,2, 19,3, 20,4, 99807,1, 99809,1, 99820,6, 2017,24, 22699,1, 22699,2, 22699,3, 22699,4, 40355,3)\ .race(:1batch).map: -> $number, $parts { say (sprintf "Partition %5d into %2d prime piece", $number, $parts), $parts == 1 ?? ': ' !! 's: ', join '+', partition($number, $parts) || 'not possible' diff --git a/Task/Pascal-matrix-generation/PascalABC.NET/pascal-matrix-generation.pas b/Task/Pascal-matrix-generation/PascalABC.NET/pascal-matrix-generation.pas new file mode 100644 index 0000000000..8afaf3170d --- /dev/null +++ b/Task/Pascal-matrix-generation/PascalABC.NET/pascal-matrix-generation.pas @@ -0,0 +1,16 @@ +## +function binomial(n, k: integer): biginteger; +begin + result := 1bi; + for var i := 1 to k do + result := result * (n - i + 1) div i; +end; + +var m := (0..4).Select(i -> (0..4).Select(j -> binomial(i, j))); +MatrByCol(m).println; +println; +m := (0..4).Select(i -> (0..4).Select(j -> binomial(j, i))); +MatrByCol(m).println; +println; +m := (0..4).Select(i -> (0..4).Select(j -> binomial(j + i, j))); +MatrByCol(m).println; diff --git a/Task/Pascals-triangle-Puzzle/PascalABC.NET/pascals-triangle-puzzle.pas b/Task/Pascals-triangle-Puzzle/PascalABC.NET/pascals-triangle-puzzle.pas new file mode 100644 index 0000000000..f948c1790c --- /dev/null +++ b/Task/Pascals-triangle-Puzzle/PascalABC.NET/pascals-triangle-puzzle.pas @@ -0,0 +1,20 @@ +function pascal(a, b, mid, top: Integer): (integer, integer, integer); +begin + var yd := (top - 4 * (a + b)) / 7; + if yd <> yd.Round then + begin + result := (0, 0, 0); + exit + end; + var y := yd.Round; + var x := mid - 2 * a - y; + result := (x, y, y - x); +end; + +begin + var (x, y, z) := pascal(11, 4, 40, 151); + if x <> 0 then + println('Solution: x =', x, 'y =', y, 'z =', z) + else + println('There is no solution.') +end. diff --git a/Task/Pascals-triangle/EasyLang/pascals-triangle.easy b/Task/Pascals-triangle/EasyLang/pascals-triangle.easy index b8ea383ede..4f80121d68 100644 --- a/Task/Pascals-triangle/EasyLang/pascals-triangle.easy +++ b/Task/Pascals-triangle/EasyLang/pascals-triangle.easy @@ -1,12 +1,10 @@ -numfmt 0 4 -proc pascal n . . +numfmt 4 0 +proc pascal n . r[] = [ 1 ] for i to n rn[] = [ ] l = 0 - for j to n - len r[] - write " " - . + for j to n - len r[] : write " " for r in r[] write r rn[] &= l + r diff --git a/Task/Pathological-floating-point-problems/EasyLang/pathological-floating-point-problems.easy b/Task/Pathological-floating-point-problems/EasyLang/pathological-floating-point-problems.easy index efa8b72473..5c9abfed32 100644 --- a/Task/Pathological-floating-point-problems/EasyLang/pathological-floating-point-problems.easy +++ b/Task/Pathological-floating-point-problems/EasyLang/pathological-floating-point-problems.easy @@ -1,5 +1,5 @@ -numfmt 10 0 -proc task1 . . +numfmt 0 10 +proc task1 . print "--- Task 1 pathologic ---" vpp = 2 vp = -4 @@ -15,7 +15,7 @@ proc task1 . . task1 print "" # -proc task2 . . +proc task2 . print "--- Task 2 pathologic ---" e = 2.718281828459045 bal = e - 1 @@ -27,7 +27,7 @@ proc task2 . . task2 print "" # -proc mul f . bal bal$[] . +proc mul f &bal &bal$[] . for i = len bal$[] downto 1 dig = number bal$[i] h = dig * f + c @@ -36,7 +36,7 @@ proc mul f . bal bal$[] . . bal += c . -proc task2ok . . +proc task2ok . print "--- Task 2 OK ---" e$ = "2.7182818284590452353602874713526624977572470" bal = number substr e$ 1 1 diff --git a/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-1.hs b/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-1.hs new file mode 100644 index 0000000000..886d138cec --- /dev/null +++ b/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-1.hs @@ -0,0 +1,11 @@ +-- | Show at least n decimal places + +showRational :: Natural -> Rational -> String +showRational n r = let + + sign = if r < 0 then '-' else '+' + (integer, rest) = (numerator r `quotRem` denominator r) + decimal = show $ rest * 10 ^ n `quot` denominator r + zeroes = replicate (fromIntegral n - length decimal) '0' + + in sign : show integer ++ "." ++ zeroes ++ decimal diff --git a/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-2.hs b/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-2.hs new file mode 100644 index 0000000000..3e5dca21df --- /dev/null +++ b/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-2.hs @@ -0,0 +1,16 @@ +import Numeric.Natural (Natural) +import Data.Ratio as Rational + +-- | Infinite List of Rational numbers in the series, zips itself to produce more values + +v :: [Rational] +v = 2 : -4 : zipWith combine (drop 1 v) v + where + combine prev prev2 = 111 - 1130 / prev + 3000 / (prev * prev2) + + +-- >>> showRational 5 (1%3) +-- "+0.33333" + +main :: IO () +main = mapM_ (putStrLn . showRational 16 . (v !!)) [3, 4, 5, 6, 7, 8, 20, 30, 50, 100] diff --git a/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-3.hs b/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-3.hs new file mode 100644 index 0000000000..8385954b66 --- /dev/null +++ b/Task/Pathological-floating-point-problems/Haskell/pathological-floating-point-problems-3.hs @@ -0,0 +1,30 @@ +import Data.Ratio ((%), numerator, denominator) +import Data.List (genericIndex) + +balances :: [Rational] +balances = e - 1 : zipWith nextYear [1..] balances + where + nextYear n b = n * b - 1 + + e = brothersFormulae 1000 + + +factorial :: [Integer] +factorial = 0 : 1 : zipWith (*) (drop 1 factorial) [2..] + +-- >>> take 10 factorial +-- [0,1,2,6,24,120,720,5040,40320,362880] + +brothersFormulae :: Integer -> Rational +brothersFormulae n = sum $ map step [0..n] + where + step i = (2 * i + 2) % genericIndex factorial (2 * i + 1) + +task2 :: String +task2 = showRational 30 . (balances !!) $ 25 + +-- >>> task2 +-- "+0.039938729673230208903671455210" + +main :: IO () +main = putStrLn task2 diff --git a/Task/Pathological-floating-point-problems/PascalABC.NET/pathological-floating-point-problems.pas b/Task/Pathological-floating-point-problems/PascalABC.NET/pathological-floating-point-problems.pas new file mode 100644 index 0000000000..16ae66209b --- /dev/null +++ b/Task/Pathological-floating-point-problems/PascalABC.NET/pathological-floating-point-problems.pas @@ -0,0 +1,45 @@ +uses numlibabc; + +function muller_seq(n: integer): real; +begin + var seq := Lst(Frc(0), Frc(2), Frc(-4)); + foreach var i in range(3, n + 1) do + begin + var next_value := 111 - 1130 / seq[i - 1] + 3000 / (seq[i - 1] * seq[i - 2]); + seq.Add(next_value); + end; + result := seq[n].ToReal +end; + +function tofraction(s: string): Fraction; +begin + var period := s.IndexOf('.'); + result := Frc(s.Remove(period, 1).ToBigInteger, Power(10bi, s.Length - period - 1)); +end; + +function bank(years: integer): real; +const + e = '2.71828182845904523536028747135266249775724709369995'; +begin + var bigE := ToFraction(e); + var balance := bigE - 1; + for var year := 1 to years do + balance := balance * year - 1; + result := balance.ToReal; +end; + +function rump(a, b: biginteger): real; +begin + var f := ToFraction('333.75') * b ** 6 + + a ** 2 * (11 * a ** 2 * b ** 2 - b ** 6 - 121 * b ** 4 - 2) + + ToFraction('5.5') * b ** 8 + Frc(a, 2 * b); + result := f.ToReal; +end; + +begin + println('Task 1:'); + foreach var n in [3, 4, 5, 6, 7, 8, 20, 30, 50, 100] do + println(n, muller_seq(n)); + println('Task 2: ', bank(25)); + println('Task 3: ', rump(77617, 33096)); +end. diff --git a/Task/Peano-curve/EasyLang/peano-curve.easy b/Task/Peano-curve/EasyLang/peano-curve.easy index 4b695b0ad2..b55b67d5d2 100644 --- a/Task/Peano-curve/EasyLang/peano-curve.easy +++ b/Task/Peano-curve/EasyLang/peano-curve.easy @@ -1,4 +1,4 @@ -proc lsysexp level . axiom$ rules$[] . +proc lsysexp level &axiom$ &rules$[] . for l to level an$ = "" for c$ in strchars axiom$ @@ -13,14 +13,15 @@ proc lsysexp level . axiom$ rules$[] . swap axiom$ an$ . . -proc lsysdraw axiom$ x y ang . . - linewidth 0.3 - move x y +proc lsysdraw axiom$ x y ang . + glinewidth 0.3 for c$ in strchars axiom$ if c$ = "F" + px = x + py = y x += cos dir y += sin dir - line x y + gline px py x y elif c$ = "-" dir -= ang elif c$ = "+" diff --git a/Task/Pells-equation/PascalABC.NET/pells-equation.pas b/Task/Pells-equation/PascalABC.NET/pells-equation.pas new file mode 100644 index 0000000000..123613e4ee --- /dev/null +++ b/Task/Pells-equation/PascalABC.NET/pells-equation.pas @@ -0,0 +1,31 @@ +function solvePell(n: integer): (biginteger, biginteger); +begin + var x: biginteger := n.sqrt.floor; + var (y, z, r) := (x, 1bi, x shl 1); + var (e1, e2) := (1bi, 0bi); + var (f1, f2) := (0bi, 1bi); + + repeat + y := r * z - y; + z := (n - y * y) div z; + r := (x + y) div z; + + (e1, e2) := (e2, e1 + e2 * r); + (f1, f2) := (f2, f1 + f2 * r); + + var (a, b) := (f2 * x + e2, f2); + if a * a - n * b * b = 1 then + begin + result := (a, b); + exit + end; + until false; +end; + +begin + foreach var n in |61, 109, 181, 277| do + begin + var (x, y) := solvePell(n); + writeln('x² - ', n:3, ' * y² = 1 for (x, y) = (', x:21, ',',y:20, ')'); + end; +end. diff --git a/Task/Penneys-game/Dart/penneys-game.dart b/Task/Penneys-game/Dart/penneys-game.dart new file mode 100644 index 0000000000..4f4d5fe9d8 --- /dev/null +++ b/Task/Penneys-game/Dart/penneys-game.dart @@ -0,0 +1,89 @@ +import 'dart:math'; +import 'dart:io'; + +class Penney { + int pW = 0; + int cW = 0; + String playerChoice = ''; + String computerChoice = ''; + String sequence = ''; + final Random _random = Random(); + + void gameLoop() { + String a; + while (true) { + playerChoice = ''; + computerChoice = ''; + if (_random.nextInt(2) == 1) { + computer(); + player(); + } else { + player(); + computer(); + } + + play(); + + stdout.write("[Y] to play again "); + a = stdin.readLineSync() ?? ''; // Read input from the console + + if (a.isNotEmpty && a[0].toUpperCase() != 'Y') { + print("Computer won $cW times."); + print("Player won $pW times."); + break; + } + print('\n\n'); + } + } + + void computer() { + if (playerChoice.isEmpty) { + for (int x = 0; x < 3; x++) { + computerChoice += (_random.nextInt(2) == 0) ? "H" : "T"; + } + } else { + computerChoice += (playerChoice[1] == 'T') ? "H" : "T"; + computerChoice += playerChoice.substring(0, 2); + } + print("Computer's sequence of three is: $computerChoice"); + } + + void player() { + stdout.write("Enter your sequence of three (H/T) "); + playerChoice = stdin.readLineSync() ?? ''; // Read input from the console + } + + void play() { + sequence = ''; + while (true) { + sequence += (_random.nextInt(2) == 0) ? "H" : "T"; + if (sequence.contains(playerChoice)) { + showWinner(1); + break; + } else if (sequence.contains(computerChoice)) { + showWinner(0); + break; + } + } + } + + void showWinner(int i) { + String s; + if (i == 1) { + s = "Player wins!"; + pW++; + } else { + s = "Computer wins!"; + cW++; + } + print("Tossed sequence: $sequence"); + print(s); + print('\n'); + } +} + +void main() { + // Dart does not need srand, Random() creates a new seeded random number generator. + final game = Penney(); + game.gameLoop(); +} diff --git a/Task/Pentagram/EasyLang/pentagram.easy b/Task/Pentagram/EasyLang/pentagram.easy index b8712411f7..6aa9bc629a 100644 --- a/Task/Pentagram/EasyLang/pentagram.easy +++ b/Task/Pentagram/EasyLang/pentagram.easy @@ -1,16 +1,15 @@ -xp = 10 -yp = 60 -linewidth 2 -move xp yp +x = 10 +y = 60 +glinewidth 2 while angle < 720 - x = xp + cos angle * 80 - y = yp + sin -angle * 80 - line x y - f[] &= x - f[] &= y xp = x yp = y + x += cos angle * 80 + y += sin -angle * 80 + gline xp yp x y + f[] &= x + f[] &= y angle += 144 . -color 900 -polygon f[] +gcolor 900 +gpolygon f[] diff --git a/Task/Percolation-Mean-run-density/EasyLang/percolation-mean-run-density.easy b/Task/Percolation-Mean-run-density/EasyLang/percolation-mean-run-density.easy index 3dabbe5a78..40bc29f1dd 100644 --- a/Task/Percolation-Mean-run-density/EasyLang/percolation-mean-run-density.easy +++ b/Task/Percolation-Mean-run-density/EasyLang/percolation-mean-run-density.easy @@ -1,4 +1,4 @@ -numfmt 3 6 +numfmt 6 3 for p in [ 0.1 0.3 0.5 0.7 0.9 ] theory = p * (1 - p) print "p:" & p & " theory:" & theory @@ -9,9 +9,7 @@ for p in [ 0.1 0.3 0.5 0.7 0.9 ] run = 0 for j to n h = if randomf < p - if h = 1 and run = 0 - sum += 1 - . + if h = 1 and run = 0 : sum += 1 run = h . . diff --git a/Task/Perfect-numbers/REXX/perfect-numbers-1.rexx b/Task/Perfect-numbers/REXX/perfect-numbers-1.rexx index f726911248..5cf11e7b50 100644 --- a/Task/Perfect-numbers/REXX/perfect-numbers-1.rexx +++ b/Task/Perfect-numbers/REXX/perfect-numbers-1.rexx @@ -1,12 +1,38 @@ -/*REXX version of the ooRexx program (the code was modified to run with Classic REXX).*/ - do i=1 to 10000 /*statement changed: LOOP ──► DO*/ - if perfectNumber(i) then say i "is a perfect number" - end +-- 25 Mar 2025 +include Settings + +say 'PERFECT NUMBERS' +say version +say +numeric digits 100 +call Show 1,34000000 +call Show 137438691328 +call Show 2658455991569831744654692615953842176 +call Show 9658455991569831744654692615953842176 exit -perfectNumber: procedure; parse arg n /*statements changed: ROUTINE,USE*/ -sum=0 - do i=1 to n%2 /*statement changed: LOOP ──► DO*/ - if n//i==0 then sum=sum+i /*statement changed: sum += i */ - end -return sum=n +Show: +procedure +call Time('r') +arg xx,yy +if yy = '' then + yy = xx +interpret 'xx =' xx'+0'; interpret 'yy =' yy'+0' +say 'Perfect numbers between' xx 'and' yy'...' +xx = xx+Odd(xx); yy = yy-Odd(yy) +n = 0 +do i = xx to yy by 2 + if Perfect(i) then do + n = n+1 + call Charout ,i' ' + end +end +say +say n 'such numbers found' +say Format(Time('e'),,3) 'seconds' +say +return + +include Numbers +include Functions +include Abend diff --git a/Task/Perfect-numbers/REXX/perfect-numbers-2.rexx b/Task/Perfect-numbers/REXX/perfect-numbers-2.rexx index d4bd1a89bf..f726911248 100644 --- a/Task/Perfect-numbers/REXX/perfect-numbers-2.rexx +++ b/Task/Perfect-numbers/REXX/perfect-numbers-2.rexx @@ -1,17 +1,12 @@ -/*REXX version of the PL/I program (code was modified to run with Classic REXX). */ -parse arg low high . /*obtain the specified number(s).*/ -if high=='' & low=='' then high=34000000 /*if no arguments, use a range. */ -if low=='' then low=1 /*if no LOW, then assume unity.*/ -if high=='' then high=low /*if no HIGH, then assume LOW. */ - - do i=low to high /*process the single # or range. */ - if perfect(i) then say i 'is a perfect number.' - end /*i*/ +/*REXX version of the ooRexx program (the code was modified to run with Classic REXX).*/ + do i=1 to 10000 /*statement changed: LOOP ──► DO*/ + if perfectNumber(i) then say i "is a perfect number" + end exit -perfect: procedure; parse arg n /*get the number to be tested. */ -sum=0 /*the sum of the factors so far. */ - do i=1 for n-1 /*starting at 1, find all factors*/ - if n//i==0 then sum=sum+i /*I is a factor of N, so add it.*/ - end /*i*/ -return sum=n /*if the sum matches N, perfect! */ +perfectNumber: procedure; parse arg n /*statements changed: ROUTINE,USE*/ +sum=0 + do i=1 to n%2 /*statement changed: LOOP ──► DO*/ + if n//i==0 then sum=sum+i /*statement changed: sum += i */ + end +return sum=n diff --git a/Task/Perfect-numbers/REXX/perfect-numbers-3.rexx b/Task/Perfect-numbers/REXX/perfect-numbers-3.rexx index 981fd22097..d4bd1a89bf 100644 --- a/Task/Perfect-numbers/REXX/perfect-numbers-3.rexx +++ b/Task/Perfect-numbers/REXX/perfect-numbers-3.rexx @@ -1,21 +1,17 @@ -/*REXX program tests if a number (or a range of numbers) is/are perfect. */ -parse arg low high . /*obtain optional arguments from the CL*/ -if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */ -if low=='' then low=1 /*if no LOW, then assume unity. */ -if high=='' then high=low /*if no HIGH, then assume LOW. */ -w=length(high) /*use W for formatting the output. */ -numeric digits max(9,w+2) /*ensure enough digits to handle number*/ +/*REXX version of the PL/I program (code was modified to run with Classic REXX). */ +parse arg low high . /*obtain the specified number(s).*/ +if high=='' & low=='' then high=34000000 /*if no arguments, use a range. */ +if low=='' then low=1 /*if no LOW, then assume unity.*/ +if high=='' then high=low /*if no HIGH, then assume LOW. */ - do i=low to high /*process the single number or a range.*/ - if isPerfect(i) then say right(i,w) 'is a perfect number.' - end /*i*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPerfect: procedure; parse arg x /*obtain the number to be tested. */ - if x<6 then return 0 /*perfect numbers can't be < six. */ - s=1 /*the first factor of X. ___*/ - do j=2 while j*j<=x /*starting at 2, find the factors ≤√ X */ - if x//j\==0 then iterate /*J isn't a factor of X, so skip it.*/ - s = s + j + x%j /* ··· add it and the other factor. */ - end /*j*/ /*(above) is marginally faster. */ - return s==x /*if the sum matches X, it's perfect! */ + do i=low to high /*process the single # or range. */ + if perfect(i) then say i 'is a perfect number.' + end /*i*/ +exit + +perfect: procedure; parse arg n /*get the number to be tested. */ +sum=0 /*the sum of the factors so far. */ + do i=1 for n-1 /*starting at 1, find all factors*/ + if n//i==0 then sum=sum+i /*I is a factor of N, so add it.*/ + end /*i*/ +return sum=n /*if the sum matches N, perfect! */ diff --git a/Task/Perfect-numbers/REXX/perfect-numbers-4.rexx b/Task/Perfect-numbers/REXX/perfect-numbers-4.rexx index 5f6b191337..981fd22097 100644 --- a/Task/Perfect-numbers/REXX/perfect-numbers-4.rexx +++ b/Task/Perfect-numbers/REXX/perfect-numbers-4.rexx @@ -1,28 +1,21 @@ -/*REXX program tests if a number (or a range of numbers) is/are perfect. */ -parse arg low high . /*obtain the specified number(s). */ -if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */ -if low=='' then low=1 /*if no LOW, then assume unity. */ -if high=='' then high=low /*if no HIGH, then assume LOW. */ -w=length(high) /*use W for formatting the output. */ +/*REXX program tests if a number (or a range of numbers) is/are perfect. */ +parse arg low high . /*obtain optional arguments from the CL*/ +if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */ +if low=='' then low=1 /*if no LOW, then assume unity. */ +if high=='' then high=low /*if no HIGH, then assume LOW. */ +w=length(high) /*use W for formatting the output. */ numeric digits max(9,w+2) /*ensure enough digits to handle number*/ - do i=low to high /*process the single number or a range.*/ - if isPerfect(i) then say right(i,w) 'is a perfect number.' - end /*i*/ + do i=low to high /*process the single number or a range.*/ + if isPerfect(i) then say right(i,w) 'is a perfect number.' + end /*i*/ exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ -isPerfect: procedure; parse arg x 1 y /*obtain the number to be tested. */ - if x==6 then return 1 /*handle the special case of six. */ - /*[↓] perfect number's digitalRoot = 1*/ - do until y<10 /*find the digital root of Y. */ - parse var y r 2; do k=2 for length(y)-1; r=r+substr(y,k,1); end /*k*/ - y=r /*find digital root of the digit root. */ - end /*until*/ /*wash, rinse, repeat ··· */ - - if r\==1 then return 0 /*Digital root ¬ 1? Then ¬ perfect. */ +isPerfect: procedure; parse arg x /*obtain the number to be tested. */ + if x<6 then return 0 /*perfect numbers can't be < six. */ s=1 /*the first factor of X. ___*/ do j=2 while j*j<=x /*starting at 2, find the factors ≤√ X */ - if x//j\==0 then iterate /*J isn't a factor of X, so skip it. */ - s = s + j + x%j /*··· add it and the other factor. */ + if x//j\==0 then iterate /*J isn't a factor of X, so skip it.*/ + s = s + j + x%j /* ··· add it and the other factor. */ end /*j*/ /*(above) is marginally faster. */ - return s==x /*if the sum matches X, it's perfect! */ + return s==x /*if the sum matches X, it's perfect! */ diff --git a/Task/Perfect-numbers/REXX/perfect-numbers-5.rexx b/Task/Perfect-numbers/REXX/perfect-numbers-5.rexx index 966599a864..5f6b191337 100644 --- a/Task/Perfect-numbers/REXX/perfect-numbers-5.rexx +++ b/Task/Perfect-numbers/REXX/perfect-numbers-5.rexx @@ -1,29 +1,28 @@ /*REXX program tests if a number (or a range of numbers) is/are perfect. */ -parse arg low high . /*obtain optional arguments from the CL*/ -if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */ +parse arg low high . /*obtain the specified number(s). */ +if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */ if low=='' then low=1 /*if no LOW, then assume unity. */ -low=low+low//2 /*if LOW is odd, bump it by one. */ -if high=='' then high=low /*if no HIGH, then assume LOW. */ +if high=='' then high=low /*if no HIGH, then assume LOW. */ w=length(high) /*use W for formatting the output. */ numeric digits max(9,w+2) /*ensure enough digits to handle number*/ - do i=low to high by 2 /*process the single number or a range.*/ - if isPerfect(i) then say right(i,w) 'is a perfect number.' - end /*i*/ + do i=low to high /*process the single number or a range.*/ + if isPerfect(i) then say right(i,w) 'is a perfect number.' + end /*i*/ exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ isPerfect: procedure; parse arg x 1 y /*obtain the number to be tested. */ - if x==6 then return 1 /*handle the special case of six. */ + if x==6 then return 1 /*handle the special case of six. */ + /*[↓] perfect number's digitalRoot = 1*/ + do until y<10 /*find the digital root of Y. */ + parse var y r 2; do k=2 for length(y)-1; r=r+substr(y,k,1); end /*k*/ + y=r /*find digital root of the digit root. */ + end /*until*/ /*wash, rinse, repeat ··· */ - do until y<10 /*find the digital root of Y. */ - parse var y 1 r 2; do k=2 for length(y)-1; r=r+substr(y,k,1); end /*k*/ - y=r /*find digital root of the digital root*/ - end /*until*/ /*wash, rinse, repeat ··· */ - - if r\==1 then return 0 /*Digital root ¬ 1 ? Then ¬ perfect.*/ - s=3 + x%2 /*the first 3 factors of X. ___*/ - do j=3 while j*j<=x /*starting at 3, find the factors ≤√ X */ - if x//j\==0 then iterate /*J isn't a factor o f X, so skip it.*/ - s = s + j + x%j /* ··· add it and the other factor. */ - end /*j*/ /*(above) is marginally faster. */ - return s==x /*if sum matches X, then it's perfect!*/ + if r\==1 then return 0 /*Digital root ¬ 1? Then ¬ perfect. */ + s=1 /*the first factor of X. ___*/ + do j=2 while j*j<=x /*starting at 2, find the factors ≤√ X */ + if x//j\==0 then iterate /*J isn't a factor of X, so skip it. */ + s = s + j + x%j /*··· add it and the other factor. */ + end /*j*/ /*(above) is marginally faster. */ + return s==x /*if the sum matches X, it's perfect! */ diff --git a/Task/Perfect-numbers/REXX/perfect-numbers-6.rexx b/Task/Perfect-numbers/REXX/perfect-numbers-6.rexx index 6b00ec353c..966599a864 100644 --- a/Task/Perfect-numbers/REXX/perfect-numbers-6.rexx +++ b/Task/Perfect-numbers/REXX/perfect-numbers-6.rexx @@ -1,33 +1,29 @@ /*REXX program tests if a number (or a range of numbers) is/are perfect. */ -parse arg low high . /*obtain the optional arguments from CL*/ -if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */ -if low=='' then low=1 /*if no LOW, then assume unity. */ -low=low+low//2 /*if LOW is odd, bump it by one. */ -if high=='' then high=low /*if no HIGH, then assume LOW. */ -w=length(high) /*use W for formatting the output. */ +parse arg low high . /*obtain optional arguments from the CL*/ +if high=='' & low=="" then high=34000000 /*if no arguments, then use a range. */ +if low=='' then low=1 /*if no LOW, then assume unity. */ +low=low+low//2 /*if LOW is odd, bump it by one. */ +if high=='' then high=low /*if no HIGH, then assume LOW. */ +w=length(high) /*use W for formatting the output. */ numeric digits max(9,w+2) /*ensure enough digits to handle number*/ -@.=0; @.1=2 /*highest magic number and its index. */ do i=low to high by 2 /*process the single number or a range.*/ if isPerfect(i) then say right(i,w) 'is a perfect number.' end /*i*/ exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ -isPerfect: procedure expose @.; parse arg x /*obtain the number to be tested. */ - /*Lucas-Lehmer know that perfect */ - /* numbers can be expressed as: */ - /* [2**n - 1] * [2** (n-1) ] */ +isPerfect: procedure; parse arg x 1 y /*obtain the number to be tested. */ + if x==6 then return 1 /*handle the special case of six. */ - if @.01; q=q%4; _=z-r-q; r=r%2; if _>=0 then do; z=_; r=r+q; end - end /*while q>1*/ /* [↑] compute the integer SQRT of X.*/ - /* _____*/ - do j=3 to r /*starting at 3, find factors ≤ √ X */ - if x//j==0 then s=s+j+x%j /*J divisible by X? Then add J and X÷J*/ - end /*j*/ - return s==x /*if the sum matches X, then perfect! */ + if @.x==0 then return 0 /*Didn't pass Lucas-Lehmer test? */ + s = 3 + x%2 /*we know the following factors: */ + /* 1 ('cause Mama said so.) */ + /* 2 ('cause it's even.) */ + /* x÷2 ( " " " ) ___*/ + do j=3 while j*j<=x /*starting at 3, find the factors ≤√ X */ + if x//j\==0 then iterate /*J divides X evenly, so ··· */ + s=s + j + x%j /*··· add it and the other factor. */ + end /*j*/ /*(above) is marginally faster. */ + return s==x /*if the sum matches X, it's perfect!*/ diff --git a/Task/Perfect-numbers/REXX/perfect-numbers-8.rexx b/Task/Perfect-numbers/REXX/perfect-numbers-8.rexx new file mode 100644 index 0000000000..bb38ef701e --- /dev/null +++ b/Task/Perfect-numbers/REXX/perfect-numbers-8.rexx @@ -0,0 +1,47 @@ +/*REXX program tests if a number (or a range of numbers) is/are perfect. */ +parse arg low high . /*obtain optional arguments from the CL*/ +if high=='' & low=="" then high=34000000 /*No arguments? Then use a range. */ +if low=='' then low=1 /*if no LOW, then assume unity. */ +low=low+low//2 /*if LOW is odd, bump it by one. */ +if high=='' then high=low /*if no HIGH, then assume LOW. */ +w=length(high) /*use W for formatting the output. */ +numeric digits max(9,w+2) /*ensure enough decimal digits for nums*/ +@. =0; @.1=2; !.=2; _=' 6' /*highest magic number and its index.*/ +!._=22; !.16=12; !.28=8; !.36=20; !.56=20; !.76=20; !.96=20 + /* [↑] "Lucas' numbers, in 1891. */ + do i=low to high by 0 /*process the single number or a range.*/ + if isPerfect(i) then say right(i,w) 'is a perfect number.' + i=i+!.? /*use a fast advance for the DO index. */ + end /*i*/ /* [↑] note: the DO index is modified.*/ +exit /*stick a fork in it, we're all done. */ +/*──────────────────────────────────────────────────────────────────────────────────────*/ +isPerfect: procedure expose @. !. ? /*expose (make global) some variables. */ + parse arg x 1 y '' -2 ? /*# (and copy), and the last 2 digits.*/ + if x==6 then return 1 /*handle the special case of six. */ + if !.?==2 then return 0 /*test last two digits: François Lucas.*/ + /*╔═════════════════════════════════════════════╗ + ║ Lucas─Lehmer know that perfect numbers can ║ + ║ be expressed as: [2^n -1] * {2^(n-1) } ║ + ╚═════════════════════════════════════════════╝*/ + if @.01; q=q%4; _=z-r-q; r=r%2; if _>=0 then do; z=_; r=r+q; end + end /*while q>1*/ /* [↑] compute the integer SQRT of X.*/ + /* _____*/ + do j=3 to r /*starting at 3, find factors ≤ √ X */ + if x//j==0 then s=s+j+x%j /*J divisible by X? Then add J and X÷J*/ + end /*j*/ + return s==x /*if the sum matches X, then perfect! */ diff --git a/Task/Perfect-shuffle/EasyLang/perfect-shuffle.easy b/Task/Perfect-shuffle/EasyLang/perfect-shuffle.easy index 9873feded1..65312f6022 100644 --- a/Task/Perfect-shuffle/EasyLang/perfect-shuffle.easy +++ b/Task/Perfect-shuffle/EasyLang/perfect-shuffle.easy @@ -1,4 +1,4 @@ -proc pshuffle . deck[] . +proc pshuffle &deck[] . mp = len deck[] / 2 in[] = deck[] for i = 1 to mp @@ -6,10 +6,8 @@ proc pshuffle . deck[] . deck[2 * i] = in[i + mp] . . -proc test size . . - for i to size - deck0[] &= i - . +proc test size . + for i to size : deck0[] &= i deck[] = deck0[] repeat pshuffle deck[] diff --git a/Task/Perfect-shuffle/PascalABC.NET/perfect-shuffle.pas b/Task/Perfect-shuffle/PascalABC.NET/perfect-shuffle.pas new file mode 100644 index 0000000000..ded0f45d7b --- /dev/null +++ b/Task/Perfect-shuffle/PascalABC.NET/perfect-shuffle.pas @@ -0,0 +1,19 @@ +function shuffle(deck: list) := deck[:deck.Count div 2].Interleave(deck[deck.Count div 2:]); + +function number(size: integer): integer; +begin + assert(size mod 2 = 0, 'size must be even'); + var start := Range(1, size).ToList; + var deck := Range(1, size).ToList; + var counter := 0; + repeat + deck := shuffle(deck).ToList; + counter += 1; + until deck.SequenceEqual(start); + result := counter; +end; + +begin + foreach var size in |8, 24, 52, 100, 1020, 1024, 10_000| do + writeln(size:5, ': ', number(size):4); +end. diff --git a/Task/Perfect-totient-numbers/PascalABC.NET/perfect-totient-numbers.pas b/Task/Perfect-totient-numbers/PascalABC.NET/perfect-totient-numbers.pas new file mode 100644 index 0000000000..66862598cd --- /dev/null +++ b/Task/Perfect-totient-numbers/PascalABC.NET/perfect-totient-numbers.pas @@ -0,0 +1,23 @@ +uses school; + +function totient(n: int64) := (1..n).Select(k -> (if gcd(n, k) = 1 then 1 else 0)).Sum; + +function perfect(): sequence of integer; +begin + var n := 1; + repeat + var tot := n; + var sum := 0; + while tot <> 1 do + begin + tot := totient(tot); + sum += tot; + end; + if sum = n then yield n; + n += 2; + until false; +end; + +begin + perfect.Take(20).Println; +end. diff --git a/Task/Periodic-table/EasyLang/periodic-table.easy b/Task/Periodic-table/EasyLang/periodic-table.easy index 99c61ba5bf..0f25dd9a26 100644 --- a/Task/Periodic-table/EasyLang/periodic-table.easy +++ b/Task/Periodic-table/EasyLang/periodic-table.easy @@ -1,16 +1,12 @@ -proc mpos n . . +proc mpos n . a[] = [ 1 2 5 13 57 72 89 104 ] b[] = [ -1 15 25 35 72 21 58 7 ] i = len a[] - while a[i] > n - i -= 1 - . + while a[i] > n : i -= 1 m = n + b[i] r = m div 18 + 1 c = m mod 18 + 1 print "Atomic number " & n & "-> " & r & ", " & c . elem[] = [ 1 2 29 42 57 58 59 71 72 89 90 103 113 ] -for e in elem[] - mpos e -. +for e in elem[] : mpos e diff --git a/Task/Peripheral-drift-illusion/EasyLang/peripheral-drift-illusion.easy b/Task/Peripheral-drift-illusion/EasyLang/peripheral-drift-illusion.easy index e1b61bf007..d8b58f906b 100644 --- a/Task/Peripheral-drift-illusion/EasyLang/peripheral-drift-illusion.easy +++ b/Task/Peripheral-drift-illusion/EasyLang/peripheral-drift-illusion.easy @@ -3,25 +3,22 @@ offs = 10 / n r = (100 / (3 * n + 1)) step = 360 * 2 / (n - 1) # -background 470 -clear +gbackground 470 +gclear for row = 0 to n - 1 for col = 0 to n - 1 x = (3 * col + 2) * r y = (3 * row + 2) * r # h = col * step + row * step - move (x + offs * cos h) (y + offs * sin h) - color 999 - circle r + gcolor 999 + gcircle (x + offs * cos h) (y + offs * sin h) r # h += 180 - move (x + offs * cos h) (y + offs * sin h) - color 000 - circle r + gcolor 000 + gcircle (x + offs * cos h) (y + offs * sin h) r # - move x y - color 128 - circle r + gcolor 128 + gcircle x y r . . diff --git a/Task/Perlin-noise/EasyLang/perlin-noise.easy b/Task/Perlin-noise/EasyLang/perlin-noise.easy index 4b0f9dda52..8fd4b68670 100644 --- a/Task/Perlin-noise/EasyLang/perlin-noise.easy +++ b/Task/Perlin-noise/EasyLang/perlin-noise.easy @@ -1,7 +1,6 @@ p[] = [ 151 160 137 91 90 15 131 13 201 95 96 53 194 233 7 225 140 36 103 30 69 142 8 99 37 240 21 10 23 190 6 148 247 120 234 75 0 26 197 62 94 252 219 203 117 35 11 32 57 177 33 88 237 149 56 87 174 20 125 136 171 168 68 175 74 165 71 134 139 48 27 166 77 146 158 231 83 111 229 122 60 211 133 230 220 105 92 41 55 46 245 40 244 102 143 54 65 25 63 161 1 216 80 73 209 76 132 187 208 89 18 169 200 196 135 130 116 188 159 86 164 100 109 198 173 186 3 64 52 217 226 250 124 123 5 202 38 147 118 126 255 82 85 212 207 206 59 227 47 16 58 17 182 189 28 42 223 183 170 213 119 248 152 2 44 154 163 70 221 153 101 155 167 43 172 9 129 22 39 253 19 98 108 110 79 113 224 232 178 185 112 104 218 246 97 228 251 34 242 193 238 210 144 12 191 179 162 241 81 51 145 235 249 14 239 107 49 192 214 31 181 199 106 157 184 84 204 176 115 121 50 45 127 4 150 254 138 236 205 93 222 114 67 29 24 72 243 141 128 195 78 66 215 61 156 180 ] -for i to 256 - p[] &= p[i] -. +for i to 256 : p[] &= p[i] +# func fade t . return t * t * t * (t * (t * 6 - 15) + 10) . @@ -61,15 +60,14 @@ func noise x y z . k8 = grad p[b2 + 2] (xx - 1) (yy - 1) (zz - 1) return lerp w (lerp v (lerp u k1 k2) (lerp u k3 k4)) (lerp v (lerp u k5 k6) (lerp u k7 k8)) . -numfmt 17 0 +numfmt 0 17 print noise 3.14 42 7 # # demo for y = 0 to 199 for x = 0 to 199 p = noise (x / 30) (y / 30) 0.1 - move x / 2 y / 2 - color3 p p p - rect 0.6 0.6 + gcolor3 p p p + grect x / 2 y / 2 0.6 0.6 . . diff --git a/Task/Perlin-noise/JavaScript/perlin-noise.js b/Task/Perlin-noise/JavaScript/perlin-noise.js new file mode 100644 index 0000000000..e982437274 --- /dev/null +++ b/Task/Perlin-noise/JavaScript/perlin-noise.js @@ -0,0 +1,80 @@ +let p = Array(512).fill(0); + +function fade(t) { + return t * t * t * (t * (t * 6 - 15) + 10); +} + +function lerp(t, a, b) { + return a + t * (b - a); +} + +function grad(hash, x, y, z) { + const h = hash & 15; // CONVERT LOW 4 BITS OF HASH CODE + const u = h < 8 ? x : y; // INTO 12 GRADIENT DIRECTIONS. + const v = h < 4 ? y : (h == 12 || h == 14) ? x : z; + return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); +} + +function perlinNoise(x, y, z) { + const X = Math.floor(x) & 0xff; // FIND UNIT CUBE THAT + const Y = Math.floor(y) & 0xff; // CONTAINS POINT. + const Z = Math.floor(z) & 0xff; + x -= Math.floor(x); // FIND RELATIVE X,Y,Z + y -= Math.floor(y); // OF POINT IN CUBE. + z -= Math.floor(z); + + const u = fade(x); // COMPUTE FADE CURVES + const v = fade(y); // FOR EACH OF X,Y,Z. + const w = fade(z); + + const A = p[X] + Y; + const AA = p[A] + Z; + const AB = p[A + 1] + Z; // HASH COORDINATES OF + const B = p[X + 1] + Y; + const BA = p[B] + Z; + const BB = p[B + 1] + Z; // THE 8 CUBE CORNERS, + + return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD + grad(p[BA ], x - 1, y , z )), // BLENDED + lerp(u, grad(p[AB ], x , y - 1, z ), // RESULTS + grad(p[BB ], x - 1, y - 1, z ))), // FROM 8 + lerp(v, lerp(u, grad(p[AA + 1], x , y , z - 1), // CORNERS + grad(p[BA + 1], x - 1, y , z - 1)), // OF CUBE + lerp(u, grad(p[AB + 1], x , y - 1, z - 1), + grad(p[BB + 1], x - 1, y - 1, z - 1)))); +} + +async function readFile(fileName) { + try { + const response = await fetch('../' + fileName); + if (!response.ok) { + throw new Error('Cannot open file'); + } + const text = await response.text(); + const lines = text.split('\n'); + let index = 0; + + for (const line of lines) { + const numbers = line.split(','); + for (const word of numbers) { + if (word.trim()) { + const number = parseInt(word); + p[index] = number; + p[256 + index] = number; + index++; + } + } + } + } catch (error) { + console.error(error.message); + } +} + +async function main() { + await readFile('permutation.txt'); + + console.log('Perlin noise applied to (3.14, 42.0, 7.0) gives ' + + perlinNoise(3.14, 42.0, 7.0).toFixed(16)); +} + +main(); diff --git a/Task/Permutation-test/ALGOL-68/permutation-test.alg b/Task/Permutation-test/ALGOL-68/permutation-test.alg new file mode 100644 index 0000000000..3bfcbfa927 --- /dev/null +++ b/Task/Permutation-test/ALGOL-68/permutation-test.alg @@ -0,0 +1,36 @@ +BEGIN # Permutation test - translated from the C sample # + + PROC pick = ( INT at, remain, accu, treat, []INT data )INT: + IF remain < 1 + THEN IF accu > treat THEN 1 ELSE 0 FI + ELSE pick( at - 1, remain - 1, accu + data[ at - 1 ], treat, data ) + + IF at > remain THEN pick( at - 1, remain, accu, treat, data ) ELSE 0 FI + FI # pick # ; + + PROC permutation test = ( []INT data, REF INT le, gt, REF REAL total )VOID: + IF LWB data /= 0 + THEN print( ( "LWB data is not 0", newline ) ); stop + ELSE INT treat := 0; + INT mid = UPB data OVER 2; + + total := 1; + FOR i FROM LWB data TO mid - 1 DO treat +:= data[ i ] OD; + FOR i FROM UPB data + 1 BY -1 TO mid + 2 DO total *:= i OD; + FOR i FROM mid BY -1 TO LWB data + 1 DO total /:= i OD; + + gt := pick( UPB data + 1, mid, LWB data, treat, data ); + le := ENTIER ( total - gt ) + FI # permutation test # ; + + BEGIN + REAL total := 0; + INT gt := -1, le := -1; + permutation test( []INT( 85, 88, 75, 66, 25, 29, 83, 39, 97 + , 68, 41, 10, 49, 16, 65, 32, 92, 28, 98 + )[ AT 0 ] + , le, gt, total + ); + print( ( "<= : ", fixed( 100 * le / total, -9, 6 ), "% ", whole( le, 0 ), newline ) ); + print( ( " > : ", fixed( 100 * gt / total, -9, 6 ), "% ", whole( gt, 0 ), newline ) ) + END +END diff --git a/Task/Permutation-test/EasyLang/permutation-test.easy b/Task/Permutation-test/EasyLang/permutation-test.easy new file mode 100644 index 0000000000..e443d06ffc --- /dev/null +++ b/Task/Permutation-test/EasyLang/permutation-test.easy @@ -0,0 +1,17 @@ +data[] = [ 85 88 75 66 25 29 83 39 97 68 41 10 49 16 65 32 92 28 98 ] +func pick at remain accu treat . + if remain = 0 : return if accu > treat + a = pick (at - 1) (remain - 1) (accu + data[at]) treat + if at > remain : b = pick (at - 1) remain accu treat + return a + b +. +proc main . + total = 1 + for i to 9 : treat += data[i] + for i = 19 downto 11 : total *= i + for i = 9 downto 1 : total /= i + gt = pick 19 9 0 treat + le = total - gt + print 100 * le / total & "% " & 100 * gt / total & "%" +. +main diff --git a/Task/Permutation-test/M2000-Interpreter/permutation-test-2.m2000 b/Task/Permutation-test/M2000-Interpreter/permutation-test-2.m2000 index 84aa33ecad..34eac751d9 100644 --- a/Task/Permutation-test/M2000-Interpreter/permutation-test-2.m2000 +++ b/Task/Permutation-test/M2000-Interpreter/permutation-test-2.m2000 @@ -17,25 +17,19 @@ Module CheckThis { } treated=(85, 88, 75, 66, 25, 29, 83, 39, 97) placebo=(68, 41, 10, 49, 16, 65, 32, 92, 28, 98) - treat=0 - m=each(treated): while m {treat+=array(m)} - total=1 + treat=treated#sum() + double total=1 for i=len(placebo)+1 to len(placebo) +len(treated):total*=i:next i for i=len(placebo)-1 to 1: total/=i:next i d=total div 10**int(log(total)) k=false StepA=CombinationsStep(cons(treated, placebo),len(treated)) - counter=0 - gt=0 - While not k { - comb=StepA(&k) - accu=0 - m=each(comb) - while m {accu+=array(m)} - gt+=if(accu>treat->1,0) - counter++ - if counter mod d=0 then Print over str$(counter/total," #0.0%"): Refresh 1000 - } + long counter=0 + long gt=0 + While not k + if StepA(&k)#sum()>treat then gt++ + counter++: if counter mod d=0 then Print over str$(counter/total," #0.0%"):Refresh + End While print over str$(counter/total," #0.0%") print lt=total-gt diff --git a/Task/Permutation-test/PascalABC.NET/permutation-test.pas b/Task/Permutation-test/PascalABC.NET/permutation-test.pas new file mode 100644 index 0000000000..98aae8ae01 --- /dev/null +++ b/Task/Permutation-test/PascalABC.NET/permutation-test.pas @@ -0,0 +1,20 @@ +function permutationTest(a, b: array of integer): real; +begin + var ab := a + b; + var Tobs := a.Sum; + var under := 0; + var count := 0; + foreach var perm in ab.Combinations(a.Length) do + begin + if perm.Sum <= Tobs then under += 1; + count += 1; + end; + result := under * 100 / count; +end; + +begin + var treatmentGroup := [85, 88, 75, 66, 25, 29, 83, 39, 97]; + var controlGroup := [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]; + var under := permutationTest(treatmentGroup, controlGroup); + write('under= ', under:2:2, '%, over= ', (100 - under):2:2, '%'); +end diff --git a/Task/Permutations-Derangements/EasyLang/permutations-derangements.easy b/Task/Permutations-Derangements/EasyLang/permutations-derangements.easy index 48b56cd0d9..dd74803959 100644 --- a/Task/Permutations-Derangements/EasyLang/permutations-derangements.easy +++ b/Task/Permutations-Derangements/EasyLang/permutations-derangements.easy @@ -1,10 +1,8 @@ global list[] rlist[][] . -proc permlist k . . +proc permlist k . if k >= len list[] for i to len list[] - if i = list[i] - return - . + if i = list[i] : return . rlist[][] &= list[] return @@ -16,12 +14,10 @@ proc permlist k . . . . # -proc derang n . r[][] . +proc derang n &r[][] . rlist[][] = [ ] list[] = [ ] - for i to n - list[] &= i - . + for i to n : list[] &= i permlist 1 r[][] = rlist[][] . @@ -30,9 +26,7 @@ derang 4 r[][] print r[][] # func subfac n . - if n < 2 - return 1 - n - . + if n < 2 : return 1 - n return (subfac (n - 1) + subfac (n - 2)) * (n - 1) . # diff --git a/Task/Permutations-Rank-of-a-permutation/EasyLang/permutations-rank-of-a-permutation.easy b/Task/Permutations-Rank-of-a-permutation/EasyLang/permutations-rank-of-a-permutation.easy index db99f09c13..7cd6ccf0fc 100644 --- a/Task/Permutations-Rank-of-a-permutation/EasyLang/permutations-rank-of-a-permutation.easy +++ b/Task/Permutations-Rank-of-a-permutation/EasyLang/permutations-rank-of-a-permutation.easy @@ -1,14 +1,10 @@ func[] init n . - for i to n - r[] &= i - 1 - . + for i to n : r[] &= i - 1 return r[] . func fac n . f = 1 - for i to n - f *= i - . + for i to n : f *= i return f . func[] perm n r . @@ -32,9 +28,7 @@ func rank n p[] . fa /= i h = p[n - i + 1] d = 1 - while perm[d] <> h - d += 1 - . + while perm[d] <> h : d += 1 r += fa * (d - 1) for j = d to i - 1 perm[j] = perm[j + 1] @@ -42,7 +36,7 @@ func rank n p[] . . return r . -proc show . . +proc show . for i = 0 to 5 h[] = perm 3 i print i & " -> " & h[] & " -> " & rank 3 h[] diff --git a/Task/Permutations-by-swapping/EasyLang/permutations-by-swapping.easy b/Task/Permutations-by-swapping/EasyLang/permutations-by-swapping.easy index 73e3bdc40b..3ff65eddba 100644 --- a/Task/Permutations-by-swapping/EasyLang/permutations-by-swapping.easy +++ b/Task/Permutations-by-swapping/EasyLang/permutations-by-swapping.easy @@ -1,6 +1,6 @@ # Heap's Algorithm sig = 1 -proc generate k . ar[] . +proc generate k &ar[] . if k = 1 print ar[] & " " & sig sig = -sig diff --git a/Task/Permutations/C/permutations-1.c b/Task/Permutations/C/permutations-1.c index 9312ae9af6..94f6b852bd 100644 --- a/Task/Permutations/C/permutations-1.c +++ b/Task/Permutations/C/permutations-1.c @@ -1,54 +1,65 @@ #include -int main (int argc, char *argv[]) { -//here we check arguments - if (argc < 2) { - printf("Enter an argument. Example 1234 or dcba:\n"); - return 0; - } -//it calculates an array's length - int x; - for (x = 0; argv[1][x] != '\0'; x++); -//buble sort the array - int f, v, m; - for(f=0; f < x; f++) { - for(v = x-1; v > f; v-- ) { - if (argv[1][v-1] > argv[1][v]) { - m=argv[1][v-1]; - argv[1][v-1]=argv[1][v]; - argv[1][v]=m; +#include + +#define ARR_SIZE 4 + +int ifactorial(int n) { + if (n == 0) { + return 1; } - } + + int result = 1; + + for (int i = 1; i <= n; i++) { + result *= i; + } + + return result; } -//it calculates a factorial to stop the algorithm - char a[x]; - int k=0; - int fact=k+1; - while (k!=x) { - a[k]=argv[1][k]; - k++; - fact = k*fact; - } - a[k]='\0'; -//Main part: here we permutate - int i, j; - int y=0; - char c; - while (y != fact) { - printf("%s\n", a); - i=x-2; - while(a[i] > a[i+1] ) i--; - j=x-1; - while(a[j] < a[i] ) j--; - c=a[j]; - a[j]=a[i]; - a[i]=c; -i++; -for (j = x-1; j > i; i++, j--) { - c = a[i]; - a[i] = a[j]; - a[j] = c; - } -y++; - } +void swap(char *a, char *b) { + char tmp = *a; + *a = *b; + *b = tmp; +} + +void permutations(char *arr, int arr_size) { + int factorial = ifactorial(arr_size); + + int k = 0; + while (k < factorial) { + printf("%s\n", arr); + + int i = arr_size - 2; + while (arr[i] > arr[i + 1]) { + i--; + } + + int j = arr_size - 1; + while (arr[j] < arr[i]) { + j--; + } + + swap(&arr[j], &arr[i]); + i++; + + for (j = arr_size - 1; j > i; i++, j--) { + swap(&arr[i], &arr[j]); + } + + k++; + } +} + +int compare(const void *a, const void *b) { + return (int)(*(char *)a - *(char *)b); // ascending order +} + +int main(void) { + char arr[ARR_SIZE + 1] = "dbac"; + + qsort(arr, ARR_SIZE, sizeof(char), compare); // "abcd" + permutations(arr, ARR_SIZE); + + return EXIT_SUCCESS; } diff --git a/Task/Permutations/C/permutations-2.c b/Task/Permutations/C/permutations-2.c index d1a15c5d17..2863886f1f 100644 --- a/Task/Permutations/C/permutations-2.c +++ b/Task/Permutations/C/permutations-2.c @@ -1,23 +1,65 @@ #include -int main() { - char a[] = "4321"; //array - int i, j; - int f=24; //factorial - char c; //buffer - while (f--) { - printf("%s\n", a); - i=1; - while(a[i] > a[i-1]) i++; - j=0; - while(a[j] < a[i])j++; - c=a[j]; - a[j]=a[i]; - a[i]=c; -i--; -for (j = 0; j < i; i--, j++) { - c = a[i]; - a[i] = a[j]; - a[j] = c; - } - } +#include + +#define ARR_SIZE 4 + +int ifactorial(int n) { + if (n == 0) { + return 1; + } + + int result = 1; + + for (int i = 1; i <= n; i++) { + result *= i; + } + + return result; +} + +void swap(char *a, char *b) { + char tmp = *a; + *a = *b; + *b = tmp; +} + +void permutations(char *arr, int arr_size) { + int factorial = ifactorial(arr_size); + + int k = factorial; + while (k > 0) { + printf("%s\n", arr); + + int i = 1; + while (arr[i] > arr[i - 1]) { + i++; + } + + int j = 0; + while (arr[j] < arr[i]) { + j++; + } + + swap(&arr[j], &arr[i]); + i--; + + for (j = 0; j < i; i--, j++) { + swap(&arr[i], &arr[j]); + } + + k--; + } +} + +int compare(const void *a, const void *b) { + return (int)(*(char *)b - *(char *)a); // descending order +} + +int main(void) { + char arr[ARR_SIZE + 1] = "2431"; + + qsort(arr, ARR_SIZE, sizeof(char), compare); // "4321" + permutations(arr, ARR_SIZE); + + return EXIT_SUCCESS; } diff --git a/Task/Permutations/C/permutations-4.c b/Task/Permutations/C/permutations-4.c deleted file mode 100644 index 771af27207..0000000000 --- a/Task/Permutations/C/permutations-4.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include - -/* print a list of ints */ -int show(int *x, int len) -{ - int i; - for (i = 0; i < len; i++) - printf("%d%c", x[i], i == len - 1 ? '\n' : ' '); - return 1; -} - -/* next lexicographical permutation */ -int next_lex_perm(int *a, int n) { -# define swap(i, j) {t = a[i]; a[i] = a[j]; a[j] = t;} - int k, l, t; - - /* 1. Find the largest index k such that a[k] < a[k + 1]. If no such - index exists, the permutation is the last permutation. */ - for (k = n - 1; k && a[k - 1] >= a[k]; k--); - if (!k--) return 0; - - /* 2. Find the largest index l such that a[k] < a[l]. Since k + 1 is - such an index, l is well defined */ - for (l = n - 1; a[l] <= a[k]; l--); - - /* 3. Swap a[k] with a[l] */ - swap(k, l); - - /* 4. Reverse the sequence from a[k + 1] to the end */ - for (k++, l = n - 1; l > k; l--, k++) - swap(k, l); - return 1; -# undef swap -} - -void perm1(int *x, int n, int callback(int *, int)) -{ - do { - if (callback) callback(x, n); - } while (next_lex_perm(x, n)); -} - -/* Boothroyd method; exactly N! swaps, about as fast as it gets */ -void boothroyd(int *x, int n, int nn, int callback(int *, int)) -{ - int c = 0, i, t; - while (1) { - if (n > 2) boothroyd(x, n - 1, nn, callback); - if (c >= n - 1) return; - - i = (n & 1) ? 0 : c; - c++; - t = x[n - 1], x[n - 1] = x[i], x[i] = t; - if (callback) callback(x, nn); - } -} - -/* entry for Boothroyd method */ -void perm2(int *x, int n, int callback(int*, int)) -{ - if (callback) callback(x, n); - boothroyd(x, n, n, callback); -} - -/* same as perm2, but flattened recursions into iterations */ -void perm3(int *x, int n, int callback(int*, int)) -{ - /* calloc isn't strictly necessary, int c[32] would suffice - for most practical purposes */ - int d, i, t, *c = calloc(n, sizeof(int)); - - /* curiously, with GCC 4.6.1 -O3, removing next line makes - it ~25% slower */ - if (callback) callback(x, n); - for (d = 1; ; c[d]++) { - while (d > 1) c[--d] = 0; - while (c[d] >= d) - if (++d >= n) goto done; - - t = x[ i = (d & 1) ? c[d] : 0 ], x[i] = x[d], x[d] = t; - if (callback) callback(x, n); - } -done: free(c); -} - -#define N 4 - -int main() -{ - int i, x[N]; - for (i = 0; i < N; i++) x[i] = i + 1; - - /* three different methods */ - perm1(x, N, show); - perm2(x, N, show); - perm3(x, N, show); - - return 0; -} diff --git a/Task/Permutations/EasyLang/permutations.easy b/Task/Permutations/EasyLang/permutations.easy index cadd9844a5..7144ec6808 100644 --- a/Task/Permutations/EasyLang/permutations.easy +++ b/Task/Permutations/EasyLang/permutations.easy @@ -1,4 +1,4 @@ -proc permlist k . list[] . +proc permlist k &list[] . if k = len list[] print list[] return diff --git a/Task/Permutations/K/permutations-4.k b/Task/Permutations/K/permutations-4.k index cb244368a1..7dc2fb607f 100644 --- a/Task/Permutations/K/permutations-4.k +++ b/Task/Permutations/K/permutations-4.k @@ -1,5 +1,5 @@ prm:{$[x~*x;;:x@o@#x];(x-1){,/'((,(#*x)##x),x)m*(!l)+&\m:~=l:1+#x}/0} -perm:{x[prm[#x]] +perm:{x[prm[#x]]} perm[" "\"some random text"] (("text";"text";"random";"some";"random";"some") diff --git a/Task/Pernicious-numbers/REXX/pernicious-numbers.rexx b/Task/Pernicious-numbers/REXX/pernicious-numbers.rexx index db31ab7b0b..878d9c865f 100644 --- a/Task/Pernicious-numbers/REXX/pernicious-numbers.rexx +++ b/Task/Pernicious-numbers/REXX/pernicious-numbers.rexx @@ -1,32 +1,39 @@ -/*REXX program computes and displays a number (and also a range) of pernicious numbers.*/ -numeric digits 100 /*be able to handle large numbers. */ -parse arg N L H . /*obtain optional arguments from the CL*/ -if N=='' | N==',' then N=25 /*N not given? Then use the default. */ -if L=='' | L==',' then L=888888877 /*L " " " " " " */ -if H=='' | H==',' then H=888888888 /*H " " " " " " */ -say 'The 1st ' N " pernicious numbers are:" /*display a nice title for the numbers.*/ -say pernicious(1,,N) /*get all pernicious # from 1 ─~─► N. */ -say /*display a blank line for a separator.*/ -say 'Pernicious numbers between ' L " and " H ' (inclusive) are:' -say pernicious(L,H) /*get all pernicious # from L ───► H. */ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -pernicious: procedure; parse arg bot,top,lim /*obtain the bot and top numbers, limit*/ - p='2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101' - @.=0 - do k=1 until _=='' /*examine the list of some low primes.*/ - _=word(p, k); @._=1 /*generate an array " " " " */ - end /*k*/ - $= /*list of pernicious numbers (so far). */ - if m=='' then m=999999999 /*Not given? Then use a gihugic limit.*/ - if top=='' then top=999999999 /* " " " " " " " */ - #=0 /*number of pernicious numbers (so far)*/ - do j=bot to top until #==lim /*generate pernicious #s 'til satisfied*/ - pc=popCount(j) /*obtain the population count for J. */ - if \@.pc then iterate /*if popCount not in @.prime, skip it.*/ - $=$ j /*append a pernicious number to list. */ - #=#+1 /*bump the pernicious number count. */ - end /*j*/ - return substr($, 2) /*return the results, sans 1st blank. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -popCount: return length( space( translate( x2b( d2x(arg(1))) +0,, 0), 0)) /*count 1's.*/ +-- 8 May 2025 +include Settings + +say 'PERNICIOUS NUMBERS' +say version +say +numeric digits 100 +call Show 1,36 +call Show 888888877,888888888 +exit + +Show: +procedure +call Time('r') +arg xx,yy +if yy = '' then + yy = xx +interpret 'xx =' xx'+0'; interpret 'yy =' yy'+0' +say 'Pernicious numbers between' xx 'and' yy'...' +say +n = 0 +do i = xx to yy + if Prime(Digitsum(Basenn(i,2))) then do + n = n+1 + call Charout ,i' ' + if n//10 = 0 then + say + end +end +say +say n 'such numbers found' +say Format(Time('e'),,3) 'seconds' +say +return + +include Numbers +include Functions +include Special +include Abend diff --git a/Task/Phrase-reversals/Crystal/phrase-reversals.cr b/Task/Phrase-reversals/Crystal/phrase-reversals.cr new file mode 100644 index 0000000000..b8366f5d52 --- /dev/null +++ b/Task/Phrase-reversals/Crystal/phrase-reversals.cr @@ -0,0 +1,5 @@ +str = "rosetta code phrase reversal" + +puts str.reverse # Reversed string. +puts str.split.map(&.reverse).join(" ") # Words reversed. +puts str.split.reverse.join(" ") # Word order reversed. diff --git a/Task/Pi/Atari-BASIC/pi.basic b/Task/Pi/Atari-BASIC/pi.basic new file mode 100644 index 0000000000..f7765e435b --- /dev/null +++ b/Task/Pi/Atari-BASIC/pi.basic @@ -0,0 +1,51 @@ +10 REM ADOPTED FROM COMMODORE BASIC +20 N = 100: REM N MAY BE INCREASED, BUT WILL SLOW EXECUTION +30 LN = INT(10*N/3)+16 +40 ND = 1 +50 DIM A(LN) +60 N9 = 0 +70 PD = 0:REM FIRST PRE-DIGIT IS A 0 +80 REM +90 FOR J = 1 TO LN +100 A(J-1) = 2:REM START WITH 2S +110 NEXT J +120 REM +130 FOR J = 1 TO N +140 Q = 0 +150 FOR I = LN TO 1 STEP -1:REM WORK BACKWARDS +160 X = 10*A(I-1) + Q*I +170 A(I-1) = X - (2*I-1)*INT(X/(2*I-1)):REM X - INT ( X / Y) * Y +180 Q = INT(X/(2*I - 1)) +190 NEXT I +200 A(0) = Q-10*INT(Q/10) +210 Q = INT(Q/10) +220 IF Q=9 THEN N9 = N9 + 1: GOTO 450 +240 IF Q<>10 THEN GOTO 350 +250 REM Q == 10 +260 D = PD+1: GOSUB 500 +270 IF N9 <= 0 THEN GOTO 320 +280 FOR K = 1 TO N9 +290 D = 0: GOSUB 500 +300 NEXT K +310 REM END IF +320 PD = 0 +330 N9 = 0 +335 GOTO 450 +340 REM Q <> 10 +350 D = PD: GOSUB 500 +360 PD = Q +370 IF N9 = 0 THEN GOTO 450 +380 FOR K = 1 TO N9 +390 D = 9: GOSUB 500 +400 NEXT K +410 N9 = 0 +450 NEXT J +460 PRINT PD +470 END +480 REM +490 REM OUTPUT DIGITS +500 IF ND=0 THEN PRINT D;: RETURN +510 IF D=0 THEN RETURN +520 PRINT D;"."; +530 ND = 0 +550 RETURN diff --git a/Task/Pick-random-element/Zig/pick-random-element.zig b/Task/Pick-random-element/Zig/pick-random-element.zig index 2cccbfd088..d5a019e88e 100644 --- a/Task/Pick-random-element/Zig/pick-random-element.zig +++ b/Task/Pick-random-element/Zig/pick-random-element.zig @@ -1,11 +1,11 @@ const std = @import("std"); const debug = std.debug; -const rand = std.rand; +const rand = std.Random; const time = std.time; -test "pick random element" { - var pcg = rand.Pcg.init(time.milliTimestamp()); +pub fn main() void { + var pcg = rand.Pcg.init(@intCast(time.milliTimestamp())); const chars = [_]u8{ 'A', 'B', 'C', 'D', @@ -18,13 +18,13 @@ test "pick random element" { '<', '>', '(', ')', }; - var i: usize = 0; - while (i < 32) : (i += 1) { + + for(0..32) |i| { if (i % 4 == 0) { - debug.warn("\n ", .{}); + debug.print("\n ", .{}); } - debug.warn("'{c}', ", .{chars[pcg.random.int(usize) % chars.len]}); + debug.print("'{c}', ", .{chars[pcg.random().uintLessThan(usize, chars.len)]}); } - debug.warn("\n", .{}); + debug.print("\n", .{}); } diff --git a/Task/Pierpont-primes/REXX/pierpont-primes-1.rexx b/Task/Pierpont-primes/REXX/pierpont-primes-1.rexx new file mode 100644 index 0000000000..9893ca2589 --- /dev/null +++ b/Task/Pierpont-primes/REXX/pierpont-primes-1.rexx @@ -0,0 +1,76 @@ +-- 11 Apr 2025 +include Settings + +call Time('r') +say 'PIERPOINT PRIMES (BRUTE FORCE)' +say version +say +numeric digits 40 +call GetPierpont +call Sort 'firs.' +call Sort 'seco.' +call ShowPierpont +say Format(Time('e'),,3) 'seconds'; say +exit + +GetPierpont: +procedure expose firs. glob. seco. +say 'Get Pierpont primes...' +n1 = 0; firs. = 0; n2 = 0; seco. = 0 +p = 0; m = 1e40 +do u = 0 to 120 + a = 2**u + if a > m then + leave u + do v = 0 to 80 + b = 3**v + if b > m then + iterate u + px = a*b + if px > m then + iterate v + p1 = px+1; p = p+1 + if Prime(p1) then do + n1 = n1+1; firs.n1 = p1 + end + p2 = px-1; p = p+1 + if Prime(p2) then do + n2 = n2+1; seco.n2 = p2 + end + end +end +firs.0 = n1; seco.0 = n2 +say p 'primality tests performed' +say n1 'numbers of the first kind generated' +say n2 'numbers of the second kind generated' +say +return + +ShowPierpont: +procedure expose firs. seco. +say 'Pierpont primes of the first kind nos 1 thru 50...' +do i = 1 to 50 + call Charout, Right(firs.i,9) + if i//10 = 0 then + say +end +say +say 'Pierpont primes of the second kind nos 1 thru 50...' +do i = 1 to 50 + call Charout, Right(seco.i,9) + if i//10 = 0 then + say +end +say +say 'Pierpont prime of the first kind no 250...' +say firs.250 +say +say 'Pierpont prime of the second kind no 250...' +say seco.250 +say +return + +include Numbers +include Functions +include Helper +include Abend diff --git a/Task/Pierpont-primes/REXX/pierpont-primes-2.rexx b/Task/Pierpont-primes/REXX/pierpont-primes-2.rexx new file mode 100644 index 0000000000..c6f72e9921 --- /dev/null +++ b/Task/Pierpont-primes/REXX/pierpont-primes-2.rexx @@ -0,0 +1,72 @@ +-- 11 Apr 2025 +include Settings + +call Time('r') +say 'PIERPOINT PRIMES (USING 3-SMOOTH NUMBERS)' +say version +say +numeric digits 40 +call GetSmooth +call GetPierpont +call ShowPierpont +say Format(Time('e'),,3) 'seconds'; say +exit + +GetSmooth: +procedure expose prim. smoo. +say 'Get 3-smooth numbers up to 10^40...' +n = Smooths(1e40,3) +say n '3-smooth numbers generated' +say +return + +GetPierpont: +procedure expose smoo. firs. seco. glob. +say 'Get Pierpont primes...' +n1 = 0; firs. = 0; n2 = 0; seco. = 0; p = 0 +do i = 1 to smoo.0 + p1 = smoo.i+1; p = p+1 + if Prime(p1) then do + n1 = n1+1; firs.n1 = p1 + end + p2 = smoo.i-1; p = p+1 + if Prime(p2) then do + n2 = n2+1; seco.n2 = p2 + end +end +firs.0 = n1; seco.0 = n2 +say p 'primality tests performed' +say n1 'numbers of the first kind generated' +say n2 'numbers of the second kind generated' +say +return + +ShowPierpont: +procedure expose firs. seco. +say 'Pierpont primes of the first kind nos 1 thru 50...' +do i = 1 to 50 + call Charout, Right(firs.i,9) + if i//10 = 0 then + say +end +say +say 'Pierpont primes of the second kind nos 1 thru 50...' +do i = 1 to 50 + call Charout, Right(seco.i,9) + if i//10 = 0 then + say +end +say +say 'Pierpont prime of the first kind no 250...' +say firs.250 +say +say 'Pierpont prime of the second kind no 250...' +say seco.250 +say +return + +include Numbers +include Constants +include Sequences +include Functions +include Abend diff --git a/Task/Pierpont-primes/REXX/pierpont-primes.rexx b/Task/Pierpont-primes/REXX/pierpont-primes.rexx deleted file mode 100644 index 1a751c2c12..0000000000 --- a/Task/Pierpont-primes/REXX/pierpont-primes.rexx +++ /dev/null @@ -1,36 +0,0 @@ -/*REXX program finds and displays Pierpont primes of the first and second kinds. */ -parse arg n . /*obtain optional argument from the CL.*/ -if n=='' | n=="," then n= 50 /*Not specified? Then use the default.*/ -numeric digits n /*ensure enough decimal digs (bit int).*/ -big= copies(9, digits() ) /*BIG: used as a max number (a limit).*/ -@.= '2nd'; @.1= '1st' - do t=1 to -1 by -2; usum= 0; vsum= 0; s= 0 /*T is 1, then -1.*/ - #= 0 /*number of Pierpont primes (so far). */ - $=; do j=0 until #>=n /*$: the list " " " " */ - if usum<=s then usum= get(2, 3); if vsum<=s then vsum= get(3, 2) - s= min(vsum, usum); if \isPrime(s) then iterate /*get min; Not prime? */ - #= # + 1; $= $ s /*bump counter; append.*/ - end /*j*/ - say - w= length(word($, #) ) /*biggest prime length.*/ - say center(n " Pierpont primes of the " @.t ' kind', max(10 *(w+1), 80), "═") - - do p=1 by 10 to #; _=; do k=p for 10; _= _ right( word($, k), w) - end /*k*/ - if _\=='' then say substr( strip(_, "T"), 2) - end /*p*/ - end /*t*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure; parse arg x '' -1 _; if x<17 then return wordpos(x,"2 3 5 7 11 13")>0 - if _==5 then return 0; if x//2==0 then return 0 /*not prime. */ - if x//3==0 then return 0; if x//7==0 then return 0 /* " " */ - do j=11 by 6 until j*j>x /*skip ÷ 3's.*/ - if x//j==0 then return 0; if x//(j+2)==0 then return 0 /*not prime. */ - end /*j*/; return 1 /*it's prime.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -get: parse arg c1,c2; m=big; do ju=0; pu= c1**ju; if pu+t>s then return min(m, pu+t) - do jv=0; pv= c2**jv; if pv >s then iterate ju - _= pu*pv + t; if _ >s then m= min(_, m) - end /*jv*/ - end /*ju*/ /*see the RETURN (above). */ diff --git a/Task/Pig-the-dice-game/EasyLang/pig-the-dice-game.easy b/Task/Pig-the-dice-game/EasyLang/pig-the-dice-game.easy index 6cab7a1c42..924d58c02c 100644 --- a/Task/Pig-the-dice-game/EasyLang/pig-the-dice-game.easy +++ b/Task/Pig-the-dice-game/EasyLang/pig-the-dice-game.easy @@ -5,56 +5,48 @@ subr initvars sum[] = [ 0 0 ] player = 1 . -proc btn x y txt$ . . - color 666 - linewidth 18 - move x y - line x + 15 y - move x - 4 y - 3 - color 000 - textsize 10 - text txt$ +proc btn x y txt$ . + gcolor 666 + glinewidth 18 + gline x y x + 15 y + gcolor 000 + gtextsize 10 + gtext x - 4 y - 3 txt$ . -proc show . . - background col[player] - clear - move 8 78 - color 000 - textsize 10 - text "Player-" & player - textsize 8 - move 8 66 - text "Total: " & sum[player] - textsize 5 +proc show . + gbackground col[player] + gclear + gcolor 000 + gtextsize 10 + gtext 8 78 "Player-" & player + gtextsize 8 + gtext 8 66 "Total: " & sum[player] + gtextsize 5 # h = 3 - player - color col[h] - move 65 63 - rect 30 19 - move 68 74 - color 000 - text "Player-" & h - textsize 4 - move 68 67 - text "Total: " & sum[h] + gcolor col[h] + grect 65 63 30 19 + gcolor 000 + gtext 68 74 "Player-" & h + gtextsize 4 + gtext 68 67 "Total: " & sum[h] # btn 20 20 "Roll" btn 70 20 "Hold" . -proc nxtplayer . . +proc nxtplayer . sum[player] += sum if sum > 0 sum = 0 show . - move 10 92 - textsize 7 - color 000 + gtextsize 7 + gcolor 000 if sum[player] >= 100 - text "You won !" + gtext 10 92 "You won !" stat = 3 else - text "Switch player ..." + gtext 10 92 "Switch player ..." player = 3 - player stat = 2 . @@ -64,28 +56,25 @@ on timer if stat = 1 # roll if tmcnt = 0 - move 44 37 - color col[player] - rect 30 10 + gcolor col[player] + grect 44 34 30 13 if dice > 1 sum += dice stat = 0 else sum = 0 . - color 000 - text sum + gcolor 000 + gtext 44 37 sum if dice = 1 nxtplayer . else - color 555 - move 24 34 - rect 13 13 - color 000 - move 27 37 + gcolor 555 + grect 24 34 13 13 + gcolor 000 dice = random 6 - text dice + gtext 27 37 dice tmcnt -= 1 if tmcnt = 0 timer 0.5 @@ -97,19 +86,17 @@ on timer stat = 0 show elif stat = 3 - move 0 0 - color col[player] - rect 100 30 - color 000 - move 10 30 - text "Click for new game" + gcolor col[player] + grect 0 0 100 30 + gcolor 000 + gtext 10 30 "Click for new game" stat = 4 . . -proc roll . . +proc roll . stat = 1 tmcnt = 10 - textsize 10 + gtextsize 10 timer 0 . on mouse_down diff --git a/Task/Pinstripe-Display/EasyLang/pinstripe-display.easy b/Task/Pinstripe-Display/EasyLang/pinstripe-display.easy index 50ccee3074..c861a920d8 100644 --- a/Task/Pinstripe-Display/EasyLang/pinstripe-display.easy +++ b/Task/Pinstripe-Display/EasyLang/pinstripe-display.easy @@ -2,9 +2,8 @@ for i = 1 to 4 col = 000 y = 100 - i * 25 for x = 0 step i / 4 to 100 - i / 4 - color col - move x y - rect i / 4 25 + gcolor col + grect x y i / 4 25 col = 999 - col . . diff --git a/Task/Pisano-period/EasyLang/pisano-period.easy b/Task/Pisano-period/EasyLang/pisano-period.easy index ba4646f7bd..bce914c4fe 100644 --- a/Task/Pisano-period/EasyLang/pisano-period.easy +++ b/Task/Pisano-period/EasyLang/pisano-period.easy @@ -1,33 +1,23 @@ fastfunc isprim num . if num mod 2 = 0 - if num = 2 - return 1 - . + if num = 2 : return 1 return 0 . if num mod 3 = 0 - if num = 3 - return 1 - . + if num = 3 : return 1 return 0 . i = 5 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 4 . return 1 . func gcd a b . - if b = 0 - return a - . + if b = 0 : return a return gcd b (a mod b) . func lcm a b . @@ -36,15 +26,13 @@ func lcm a b . func ipow x p . prod = 1 while p > 0 - if p mod 2 = 1 - prod *= x - . + if p mod 2 = 1 : prod *= x p = p div 2 x *= x . return prod . -proc getprims n . prims[] . +proc getprims n &prims[] . prims[] = [ ] for i = 2 to n d = n / i @@ -67,16 +55,12 @@ func pisanoPeriod m . for i = 1 to m * m swap p c c = (p + c) mod m - if p = 0 and c = 1 - return i - . + if p = 0 and c = 1 : return i . return 1 . func pisanoPrime p k . - if isprim p = 0 or k = 0 - return 0 - . + if isprim p = 0 or k = 0 : return 0 return ipow p (k - 1) * pisanoPeriod p . func pisano m . @@ -84,40 +68,30 @@ func pisano m . for i = 1 step 2 to len p[] - 1 pps[] &= pisanoPrime p[i] p[i + 1] . - if len pps[] = 0 - return 1 - . - if len pps[] = 1 - return pps[1] - . + if len pps[] = 0 : return 1 + if len pps[] = 1 : return pps[1] f = pps[1] for i = 2 to len pps[] f = lcm f pps[i] . return f . -proc main . . +proc main . for p = 2 to 14 pp = pisanoPrime p 2 - if pp > 0 - print "pisanoPrime(" & p & ": 2) = " & pp - . + if pp > 0 : print "pisanoPrime(" & p & ": 2) = " & pp . print "" for p = 2 to 179 pp = pisanoPrime p 1 - if pp > 0 - print "pisanoPrime(" & p & ": 1) = " & pp - . + if pp > 0 : print "pisanoPrime(" & p & ": 1) = " & pp . print "" - numfmt 0 3 + numfmt 3 0 print "pisano(n) for integers 'n' from 1 to 180 are:" for n = 1 to 180 write pisano (n) & " " - if n mod 15 = 0 - print "" - . + if n mod 15 = 0 : print "" . . main diff --git a/Task/Pisano-period/REXX/pisano-period.rexx b/Task/Pisano-period/REXX/pisano-period.rexx index f2141bb1ab..dcdf9efc2f 100644 --- a/Task/Pisano-period/REXX/pisano-period.rexx +++ b/Task/Pisano-period/REXX/pisano-period.rexx @@ -1,37 +1,70 @@ -/*REXX pgm calculates pisano period for a range of N, and pisanoPrime(N,m) [for primes]*/ -numeric digits 500 /*ensure enough decimal digits for Fib.*/ -parse arg lim.1 lim.2 lim.3 . /*obtain optional arguments from the CL*/ -if lim.1=='' | lim.1=="," then lim.1= 15 - 1 /*Not specified? Then use the default.*/ -if lim.2=='' | lim.2=="," then lim.2= 180 - 1 /* " " " " " " */ -if lim.3=='' | lim.3=="," then lim.3= 180 /* " " " " " " */ -call Fib /* " " Fibonacci numbers. */ - do i=1 for max(lim.1, lim.2, lim.3); call pisano(i) /*find pisano periods.*/ - end /*i*/; w= length(i) +-- 26 Mar 2025 +include Settings +call Time('r') +numeric digits 500 - do j=1 for 2; #= word(2 1, j) - do p=1 for lim.j; if \isPrime(p) then iterate /*Not prime? Skip this number.*/ - say ' pisanoPrime('right(p, w)", "#') = 'right( pisanoPrime(p, #), 5) - end /*p*/; say - end /*j*/ +say 'PISANO PERIOD' +say version +say +call GetFibo 1000 +call ShowPisanoPrime 15,2 +call ShowPisanoPrime 180,1 +call ShowPisano 180 +say Format(Time('e'),,3) 'seconds'; say +exit -say center(' pisano numbers for 1──►'lim.3" ", 20*4 - 1, "═") /*display a title.*/ -$= - do j=1 for lim.3; $= $ right(@.j, w) /*append pisano number to the $ list.*/ - if j//20==0 then do; say substr($, 2); $=; end /*display 20 numbers to a line*/ - end /*j*/ - say substr($, 2) /*possible display any residuals──►term*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -fib: procedure expose fib.; parse arg x; fib.=.; if x=='' then x= 1000 - fib.0= 0; fib.1= 1; if fib.x\==. then return fib.x - do k=2 for x-1; a= k-1; b= k-2; fib.k= fib.a + fib.b - end /*k*/; return fib.k -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: parse arg n; if n<11 then return pos(n, '2 3 5 7')>0; if n//2==0 then return 0 - do k=3 by 2 while k*k<=n; if n//k==0 then return 0; end /*k*/; return 1 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -pisano: procedure expose @. fib.; parse arg m; if m==1 then do; @.m=1; return 1; end - do k=1; _= k+1; if fib.k//m==0 & fib._//m==1 then leave - end /*k*/; @.m= k; return k -/*──────────────────────────────────────────────────────────────────────────────────────*/ -pisanoPrime: procedure expose @. fib.; parse arg m,n; return m**(n-1) * pisano(m) +GetFibo: +procedure expose fibo. +arg xx +say 'Get first' xx 'Fibonacci numbers...' +call Fibonaccis -xx +say fibo.0 'numbers found' +say +return + +ShowPisanoPrime: +procedure expose fibo. prim. +arg xx,yy +say 'Pisano primes for p^'yy'...' +do i = 1 to xx + if Prime(i) then + say 'PisanoPrime('i','yy') = ' Pisanoprime(i,yy) +end +say +return + +ShowPisano: +procedure expose fibo. prim. +arg xx +say 'Pisano(n) for n = 1...'xx'...' +do i = 1 to xx + call Charout ,Right(Pisano(i),5) + if i//10 = 0 then + say +end +say +return + +Pisanoprime: +procedure expose fibo. +arg xx,yy +return xx**(yy-1)*Pisano(xx) + +Pisano: +procedure expose fibo. +arg xx +if xx = 1 then + return 1 +do i = 1 + j = i+1 + if fibo.i//xx = 0 then + if fibo.j//xx = 1 then + leave i +end +return i + +include Sequences +include Numbers +include Functions +include Constants +include Abend diff --git a/Task/Plasma-effect/EasyLang/plasma-effect.easy b/Task/Plasma-effect/EasyLang/plasma-effect.easy index 42060fa850..6ced409589 100644 --- a/Task/Plasma-effect/EasyLang/plasma-effect.easy +++ b/Task/Plasma-effect/EasyLang/plasma-effect.easy @@ -1,6 +1,7 @@ # lodev.org/cgtutor/plasma.html (last example) func dist a b c d . - d1 = a - c ; d2 = b - d + d1 = a - c + d2 = b - d return 15 * sqrt (d1 * d1 + d2 * d2) . on animate @@ -11,9 +12,8 @@ on animate val += sin (dist x (y + time / 7) 75 50 * 1.2) val += sin dist x y 75 40 col = (val + 4) / 16 - color3 col col * 2 1 - col - move x y - rect 0.5 0.5 + gcolor3 col col * 2 1 - col + grect x y 0.5 0.5 . . time += 1 diff --git a/Task/Playfair-cipher/JavaScript/playfair-cipher.js b/Task/Playfair-cipher/JavaScript/playfair-cipher.js new file mode 100644 index 0000000000..5742a124b9 --- /dev/null +++ b/Task/Playfair-cipher/JavaScript/playfair-cipher.js @@ -0,0 +1,269 @@ +const readline = require('readline'); + +// Enum-like object for Playfair options +const playfairOption = { + NO_Q: 0, + I_EQUALS_J: 1, +}; + +// Represents the Playfair cipher state and methods +class Playfair { + constructor(keyword, pfo) { + this.keyword = keyword; + this.pfo = pfo; // playfairOption + this.table = Array(5).fill(null).map(() => Array(5).fill('')); // 5x5 table + } + + // Initializes the 5x5 Playfair table based on the keyword and option + init() { + const used = Array(26).fill(false); // Track used letters + if (this.pfo === playfairOption.NO_Q) { + used['Q'.charCodeAt(0) - 65] = true; // Q is used/omitted + } else { + used['J'.charCodeAt(0) - 65] = true; // J is used/replaced by I + } + + const alphabet = this.keyword.toUpperCase() + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + let row = 0; + let col = 0; + + for (const char of alphabet) { + const charCode = char.charCodeAt(0); + + // Check if it's a letter A-Z + if (charCode >= 'A'.charCodeAt(0) && charCode <= 'Z'.charCodeAt(0)) { + const charIndex = charCode - 65; // 0-25 index + + // Handle J if I_EQUALS_J option is selected + let charToUse = char; + let indexToUse = charIndex; + if (char === 'J' && this.pfo === playfairOption.I_EQUALS_J) { + charToUse = 'I'; + indexToUse = 'I'.charCodeAt(0) - 65; + } + + // Skip Q if NO_Q option is selected + if (charToUse === 'Q' && this.pfo === playfairOption.NO_Q) { + continue; + } + + + if (!used[indexToUse]) { + this.table[row][col] = charToUse; + used[indexToUse] = true; + col++; + if (col === 5) { + row++; + if (row === 5) { + break; // Table filled + } + col = 0; + } + } + } + } + } + + // Prepares the plaintext: uppercase, removes non-letters, + // handles Q/J based on option, inserts X between duplicate letters, + // pads with X/Z if length is odd. + getCleanText(plainText) { + plainText = plainText.toUpperCase(); + const cleanChars = []; + let prevChar = ''; // Use '' to indicate no previous character + + for (let i = 0; i < plainText.length; i++) { + let currentChar = plainText[i]; + const charCode = currentChar.charCodeAt(0); + + // Skip non-letters + if (charCode < 'A'.charCodeAt(0) || charCode > 'Z'.charCodeAt(0)) { + continue; + } + + // Handle J if I_EQUALS_J option is specified, replace J with I + if (currentChar === 'J' && this.pfo === playfairOption.I_EQUALS_J) { + currentChar = 'I'; + } + + // Skip Q if NO_Q option is specified (already handled in init, but good here too) + if (currentChar === 'Q' && this.pfo === playfairOption.NO_Q) { + continue; + } + + + // Insert 'X' between duplicate consecutive letters + // Only compare if prevChar is set (not the very first character) + if (prevChar !== '' && currentChar === prevChar) { + cleanChars.push('X'); + } + + cleanChars.push(currentChar); + prevChar = currentChar; // Store the character *after* potential X insertion + } + + // If length is odd, add a padding character + if (cleanChars.length % 2 === 1) { + // Add 'X' unless the last letter is 'X', then add 'Z' + if (cleanChars[cleanChars.length - 1] !== 'X') { + cleanChars.push('X'); + } else { + cleanChars.push('Z'); + } + } + + return cleanChars.join(''); + } + + // Finds the row and column of a character in the table + findChar(char) { + for (let i = 0; i < 5; i++) { + for (let j = 0; j < 5; j++) { + if (this.table[i][j] === char) { + return [i, j]; // Return [row, col] + } + } + } + return [-1, -1]; // Should not happen if getCleanText is correct + } + + // Encodes plaintext using the Playfair cipher + encode(plainText) { + const cleanText = this.getCleanText(plainText); + const cipherChars = []; + + for (let i = 0; i < cleanText.length; i += 2) { + const char1 = cleanText[i]; + const char2 = cleanText[i + 1]; // cleanText length is always even + const [row1, col1] = this.findChar(char1); + const [row2, col2] = this.findChar(char2); + + let encodedChar1, encodedChar2; + + if (row1 === row2) { // Same row + encodedChar1 = this.table[row1][(col1 + 1) % 5]; + encodedChar2 = this.table[row2][(col2 + 1) % 5]; + } else if (col1 === col2) { // Same column + encodedChar1 = this.table[(row1 + 1) % 5][col1]; + encodedChar2 = this.table[(row2 + 1) % 5][col2]; + } else { // Different row and column (rectangle) + encodedChar1 = this.table[row1][col2]; + encodedChar2 = this.table[row2][col1]; + } + + cipherChars.push(encodedChar1); + cipherChars.push(encodedChar2); + + // Add space after each digram, matching Go's output format + if (i + 2 < cleanText.length) { + cipherChars.push(' '); + } + } + + return cipherChars.join(''); + } + + // Decodes ciphertext using the Playfair cipher + decode(cipherText) { + // The Go code processes the ciphertext including spaces, + // stepping by 3. We'll do the same by stripping spaces first + // and then processing in pairs. This is conceptually simpler in JS. + // Or, we can replicate the Go loop that steps by 3. Let's replicate for exact match. + const decodedChars = []; + const l = cipherText.length; + + for (let i = 0; i < l; i += 3) { // Step by 3 due to spaces in encoded text + const char1 = cipherText[i]; + const char2 = cipherText[i + 1]; + // cipherText[i+2] will be a space, which findChar will correctly not find (-1, -1) + // But the Go code explicitly finds the *bytes* at i and i+1. Let's stick to that. + + // Ensure we only process valid character pairs + if (!char1 || !char2 || char1 === ' ' || char2 === ' ') { + // This shouldn't happen with the i+=3 loop structure if the input + // format from encode is followed, but good to be safe. + continue; + } + + + const [row1, col1] = this.findChar(char1); + const [row2, col2] = this.findChar(char2); + + let decodedChar1, decodedChar2; + + // Decoding rules are the reverse of encoding + if (row1 === row2) { // Same row + // Shift left: (col - 1 + 5) % 5 + decodedChar1 = this.table[row1][(col1 + 4) % 5]; + decodedChar2 = this.table[row2][(col2 + 4) % 5]; + } else if (col1 === col2) { // Same column + // Shift up: (row - 1 + 5) % 5 + decodedChar1 = this.table[(row1 + 4) % 5][col1]; + decodedChar2 = this.table[(row2 + 4) % 5][col2]; + } else { // Different row and column (rectangle) + decodedChar1 = this.table[row1][col2]; + decodedChar2 = this.table[row2][col1]; + } + + decodedChars.push(decodedChar1); + decodedChars.push(decodedChar2); + + // Add space after each digram in decoded text, matching Go's output format + if (i + 3 < l) { // Check if there's more content after the current digram+space + decodedChars.push(' '); + } + } + + return decodedChars.join(''); + } + + // Prints the 5x5 table to the console + printTable() { + console.log("The table to be used is :\n"); + for (let i = 0; i < 5; i++) { + console.log(this.table[i].join(' ')); // Join row elements with space + } + console.log(); // Add a blank line for spacing + } +} + +// Main execution function using async/await for readline +async function main() { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + + const question = (query) => new Promise((resolve) => rl.question(query, resolve)); + + try { + const keyword = await question("Enter Playfair keyword : "); + + let ignoreQ = ''; + while (ignoreQ !== "y" && ignoreQ !== "n") { + ignoreQ = (await question("Ignore Q when building table y/n : ")).toLowerCase(); + } + + const pfo = (ignoreQ === "y") ? playfairOption.NO_Q : playfairOption.I_EQUALS_J; + + const pf = new Playfair(keyword, pfo); + pf.init(); + pf.printTable(); + + const plainText = await question("\nEnter plain text : "); + + const encodedText = pf.encode(plainText); + console.log("\nEncoded text is :", encodedText); + + // The Go code decodes the encoded text *including* the spaces it added. + // Pass the encoded text as is to the decode function. + const decodedText = pf.decode(encodedText); + console.log("Decoded text is :", decodedText); + + } finally { + rl.close(); // Close the readline interface + } +} + +// Execute the main function +main(); diff --git a/Task/Playfair-cipher/Rust/playfair-cipher.rs b/Task/Playfair-cipher/Rust/playfair-cipher.rs new file mode 100644 index 0000000000..074935a132 --- /dev/null +++ b/Task/Playfair-cipher/Rust/playfair-cipher.rs @@ -0,0 +1,225 @@ +use std::io::{self, Write}; + +struct Playfair { + txt: String, + m: [[char; 5]; 5], +} + +impl Playfair { + fn new() -> Self { + Playfair { + txt: String::new(), + m: [[' '; 5]; 5], + } + } + + fn do_it(&mut self, k: &str, t: &str, ij: bool, e: bool) { + self.create_grid(k, ij); + self.get_text_ready(t, ij, e); + + if e { + self.process(1); + } else { + self.process(-1); + } + + self.display(); + } + + fn process(&mut self, dir: i32) { + let mut ntxt = String::new(); + let mut chars = self.txt.chars().collect::>(); + let mut i = 0; + + while i < chars.len() { + if i + 1 >= chars.len() { + break; + } + + let mut a = 0; + let mut b = 0; + let mut c = 0; + let mut d = 0; + + if self.get_char_pos(chars[i], &mut a, &mut b) && + self.get_char_pos(chars[i+1], &mut c, &mut d) { + if a == c { + ntxt.push(self.get_char(a, b + dir)); + ntxt.push(self.get_char(c, d + dir)); + } else if b == d { + ntxt.push(self.get_char(a + dir, b)); + ntxt.push(self.get_char(c + dir, d)); + } else { + ntxt.push(self.get_char(c, b)); + ntxt.push(self.get_char(a, d)); + } + } + + i += 2; + } + + self.txt = ntxt; + } + + fn display(&self) { + println!("\n\n OUTPUT:\n========="); + let chars = self.txt.chars().collect::>(); + let mut cnt = 0; + let mut i = 0; + + while i < chars.len() { + if i + 1 < chars.len() { + print!("{}{} ", chars[i], chars[i+1]); + i += 2; + cnt += 1; + + if cnt >= 26 { + println!(); + cnt = 0; + } + } else { + print!("{}", chars[i]); + i += 1; + } + } + + println!("\n"); + } + + fn get_char(&self, a: i32, b: i32) -> char { + let row = ((b + 5) % 5) as usize; + let col = ((a + 5) % 5) as usize; + self.m[row][col] + } + + fn get_char_pos(&self, l: char, a: &mut i32, b: &mut i32) -> bool { + for y in 0..5 { + for x in 0..5 { + if self.m[y][x] == l { + *a = x as i32; + *b = y as i32; + return true; + } + } + } + false + } + + fn get_text_ready(&mut self, t: &str, ij: bool, e: bool) { + self.txt.clear(); + + for c in t.chars() { + let c_upper = c.to_ascii_uppercase(); + + if c_upper < 'A' || c_upper > 'Z' { + continue; + } + + if c_upper == 'J' && ij { + self.txt.push('I'); + } else if c_upper == 'Q' && !ij { + continue; + } else { + self.txt.push(c_upper); + } + } + + if e { + let mut ntxt = String::new(); + let chars = self.txt.chars().collect::>(); + let len = chars.len(); + + let mut x = 0; + while x < len { + ntxt.push(chars[x]); + + if x + 1 < len { + if chars[x] == chars[x + 1] { + ntxt.push('X'); + } + ntxt.push(chars[x + 1]); + } + + x += 2; + } + + self.txt = ntxt; + } + + if self.txt.len() % 2 == 1 { + self.txt.push('X'); + } + } + + fn create_grid(&mut self, k: &str, ij: bool) { + let mut key = k.to_string(); + if key.is_empty() { + key = "KEYWORD".to_string(); + } + + key.push_str("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + let mut nk = String::new(); + + for c in key.chars() { + let c_upper = c.to_ascii_uppercase(); + + if c_upper < 'A' || c_upper > 'Z' { + continue; + } + + if (c_upper == 'J' && ij) || (c_upper == 'Q' && !ij) { + continue; + } + + if !nk.contains(c_upper) { + nk.push(c_upper); + } + } + + let mut idx = 0; + for y in 0..5 { + for x in 0..5 { + if idx < nk.len() { + self.m[y][x] = nk.chars().nth(idx).unwrap(); + idx += 1; + } + } + } + } +} + +fn main() -> io::Result<()> { + let mut input = String::new(); + + print!("(E)ncode or (D)ecode? "); + io::stdout().flush()?; + io::stdin().read_line(&mut input)?; + let e = input.trim().to_lowercase().starts_with('e'); + + input.clear(); + print!("Enter a en/decryption key: "); + io::stdout().flush()?; + io::stdin().read_line(&mut input)?; + let key = input.trim().to_string(); + + input.clear(); + print!("I <-> J (Y/N): "); + io::stdout().flush()?; + io::stdin().read_line(&mut input)?; + let ij = input.trim().to_lowercase().starts_with('y'); + + input.clear(); + print!("Enter the text: "); + io::stdout().flush()?; + io::stdin().read_line(&mut input)?; + let txt = input.trim().to_string(); + + let mut pf = Playfair::new(); + pf.do_it(&key, &txt, ij, e); + + println!("Press Enter to continue..."); + input.clear(); + io::stdin().read_line(&mut input)?; + + Ok(()) +} diff --git a/Task/Playing-cards/EasyLang/playing-cards.easy b/Task/Playing-cards/EasyLang/playing-cards.easy index 05e4bb79ff..c2c5a56b1d 100644 --- a/Task/Playing-cards/EasyLang/playing-cards.easy +++ b/Task/Playing-cards/EasyLang/playing-cards.easy @@ -1,9 +1,7 @@ global deck[] top . -proc new . . +proc new . deck[] = [ ] - for i to 52 - deck[] &= i - . + for i to 52 : deck[] &= i top = 52 . suit$[] = [ "♠" "♦" "♥" "♣" ] @@ -11,14 +9,12 @@ val$[] = [ 2 3 4 5 6 7 8 9 10 "J" "Q" "K" "A" ] func$ name card . return suit$[card mod1 4] & val$[card div1 4] . -proc show . . - for i to top - write name deck[i] & " " - . +proc show . + for i to top : write name deck[i] & " " print "" print "" . -proc shuffle . . +proc shuffle . for i = 52 downto 2 r = random i swap deck[i] deck[r] diff --git a/Task/Plot-coordinate-pairs/EasyLang/plot-coordinate-pairs.easy b/Task/Plot-coordinate-pairs/EasyLang/plot-coordinate-pairs.easy index e6f2741331..2d3e711232 100644 --- a/Task/Plot-coordinate-pairs/EasyLang/plot-coordinate-pairs.easy +++ b/Task/Plot-coordinate-pairs/EasyLang/plot-coordinate-pairs.easy @@ -1,38 +1,30 @@ x[] = [ 0 1 2 3 4 5 6 7 8 9 ] y[] = [ 2.7 2.8 31.4 38.1 58.0 76.2 100.5 130.0 149.3 180.0 ] # -clear -linewidth 0.5 -move 10 97 -line 10 5 -line 95 5 -textsize 3 +gclear +glinewidth 0.5 +gline 10 5 10 97 +gline 10 5 95 5 +gtextsize 3 n = len x[] -m = 0 for i = 1 to n - if y[i] > m - m = y[i] - . -. -linewidth 0.1 -sty = m div 9 -for i range0 10 - move 10 5 + i * 10 - line 95 5 + i * 10 - move 2 4 + i * 10 - text i * sty + max = higher y[i] max . +glinewidth 0.1 +sty = max div 9 stx = x[n] div 9 for i range0 10 - move i * 9 + 10 5 - line i * 9 + 10 97 - move i * 9 + 10 1 - text i * stx + gline 10 5 + i * 10 95 5 + i * 10 + gtext 2 4 + i * 10 i * sty + gline i * 9 + 10 5 i * 9 + 10 97 + gtext i * 9 + 10 1 i * stx . color 900 linewidth 0.5 for i = 1 to n + xp = x + yp = y x = x[i] * 9 / stx + 10 y = y[i] / sty * 10 + 5 - line x y + if i > 1 : gline xp yp x y . diff --git a/Task/Polynomial-long-division/REXX/polynomial-long-division-2.rexx b/Task/Polynomial-long-division/REXX/polynomial-long-division-2.rexx index ecba80277b..5846bb92c0 100644 --- a/Task/Polynomial-long-division/REXX/polynomial-long-division-2.rexx +++ b/Task/Polynomial-long-division/REXX/polynomial-long-division-2.rexx @@ -1,5 +1,8 @@ include Settings -say version; say 'Polynomial long division'; say + +say 'POLYNOMIAL LONG DIVISION - 2 Mar 2025' +say version +say call Divide '1 -12 0 -42','1 -3' call Divide '5 4 1','2 3' call Divide '5 0 0 4 0 0 0 0 0 0 1','2 0 2 0 3' diff --git a/Task/Polynomial-regression/EasyLang/polynomial-regression.easy b/Task/Polynomial-regression/EasyLang/polynomial-regression.easy index 8bd9ec21df..c608f605c7 100644 --- a/Task/Polynomial-regression/EasyLang/polynomial-regression.easy +++ b/Task/Polynomial-regression/EasyLang/polynomial-regression.easy @@ -1,7 +1,7 @@ func eval a b c x . return a + (b + c * x) * x . -proc regression xa[] ya[] . . +proc regression xa[] ya[] . n = len xa[] for i = 1 to n xm = xm + xa[i] @@ -30,7 +30,7 @@ proc regression xa[] ya[] . . c = (sx2y * sxx - sxy * sxx2) / (sxx * sx2x2 - sxx2 * sxx2) a = ym - b * xm - c * x2m print "y = " & a & " + " & b & "x + " & c & "x^2" - numfmt 0 3 + numfmt 3 0 for i = 1 to n print xa[i] & " " & ya[i] & " " & eval a b c xa[i] . diff --git a/Task/Polynomial-regression/Rust/polynomial-regression.rs b/Task/Polynomial-regression/Rust/polynomial-regression.rs new file mode 100644 index 0000000000..5d1857e848 --- /dev/null +++ b/Task/Polynomial-regression/Rust/polynomial-regression.rs @@ -0,0 +1,41 @@ +fn poly_regression(x: &[i32], y: &[i32]) { + let n = x.len(); + let r: Vec = (0..n as i32).collect(); + + let xm = x.iter().sum::() as f64 / x.len() as f64; + let ym = y.iter().sum::() as f64 / y.len() as f64; + let x2m: f64 = r.iter().map(|&a| (a * a) as f64).sum::() / r.len() as f64; + let x3m: f64 = r.iter().map(|&a| (a * a * a) as f64).sum::() / r.len() as f64; + let x4m: f64 = r.iter().map(|&a| (a * a * a * a) as f64).sum::() / r.len() as f64; + + let xym: f64 = x.iter().zip(y.iter()).map(|(&a, &b)| (a as f64) * (b as f64)).sum::() / x.len().min(y.len()) as f64; + + let x2ym: f64 = x.iter().zip(y.iter()).map(|(&a, &b)| (a * a) as f64 * (b as f64)).sum::() / x.len().min(y.len()) as f64; + + let sxx = x2m - xm * xm; + let sxy = xym - xm * ym; + let sxx2 = x3m - xm * x2m; + let sx2x2 = x4m - x2m * x2m; + let sx2y = x2ym - x2m * ym; + + let b = (sxy * sx2x2 - sx2y * sxx2) / (sxx * sx2x2 - sxx2 * sxx2); + let c = (sx2y * sxx - sxy * sxx2) / (sxx * sx2x2 - sxx2 * sxx2); + let a = ym - b * xm - c * x2m; + + let abc = |xx: i32| a + b * (xx as f64) + c * (xx * xx) as f64; + + println!("y = {} + {}x + {}x^2", a, b, c); + println!(" Input Approximation"); + println!(" x y y1"); + + for (&x_val, &y_val) in x.iter().zip(y.iter()) { + println!("{:2} {:3} {:5.1}", x_val, y_val, abc(x_val)); + } +} + +fn main() { + let x: Vec = (0..11).collect(); + let y: Vec = vec![1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321]; + + poly_regression(&x, &y); +} diff --git a/Task/Polynomial-regression/XPL0/polynomial-regression.xpl0 b/Task/Polynomial-regression/XPL0/polynomial-regression.xpl0 new file mode 100644 index 0000000000..e21bbb84cb --- /dev/null +++ b/Task/Polynomial-regression/XPL0/polynomial-regression.xpl0 @@ -0,0 +1,60 @@ +proc PolyReg(XA, YA, N); +real XA, YA; int N; +int I; +real XM, YM, X2M, X3M, X4M, XYM, X2YM; +real SXX, SXY, SXX2, SX2X2, SX2Y; +real A, B, C, Y, RN; +[XM:= 0.; YM:= 0.; +X2M:= 0.; X3M:= 0.; X4M:= 0.; +XYM:= 0.; X2YM:= 0.; +for I:= 0 to N-1 do + [XM:= XM + XA(I); + YM:= YM + YA(I); + X2M:= X2M + XA(I)*XA(I); + X3M:= X3M + XA(I)*XA(I)*XA(I); + X4M:= X4M + XA(I)*XA(I)*XA(I)*XA(I); + XYM:= XYM + XA(I)*YA(I); + X2YM:= X2YM + XA(I)*XA(I)*YA(I); + ]; +RN:= float(N); +XM:= XM/RN; +YM:= YM/RN; +X2M:= X2M/RN; +X3M:= X3M/RN; +X4M:= X4M/RN; +XYM:= XYM/RN; +X2YM:= X2YM/RN; + +SXX:= X2M - XM*XM; +SXY:= XYM - XM*YM; +SXX2:= X3M - XM*X2M; +SX2X2:= X4M - X2M*X2M; +SX2Y:= X2YM - X2M*YM; + +B:= (SXY*SX2X2 - SX2Y*SXX2) / (SXX*SX2X2 - SXX2*SXX2); +C:= (SX2Y*SXX - SXY*SXX2) / (SXX*SX2X2 - SXX2*SXX2); +A:= YM - B*XM - C*X2M; + +Format(1, 0); +Text(0, "y = "); RlOut(0, A); +Text(0, " + "); RlOut(0, B); +Text(0, "x + "); RlOut(0, C); +Text(0, "x^^2"); CrLf(0); +Text(0, " Input Approx^m^j"); +Text(0, " x y y1^m^j"); +for I:=0 to N-1 do + [Format(3, 0); + RlOut(0, XA(I)); Text(0, " "); + RlOut(0, YA(I)); Text(0, " "); + Y:= A + (B + C*XA(I)) * XA(I); + Format(3, 1); + RlOut(0, Y); + CrLf(0); + ]; +]; + +real XA, YA; +[XA:= [0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]; + YA:= [1., 6., 17., 34., 57., 86., 121., 162., 209., 262., 321.]; +PolyReg(XA, YA, 11); +] diff --git a/Task/Polyspiral/EasyLang/polyspiral.easy b/Task/Polyspiral/EasyLang/polyspiral.easy index fc81a83df9..0a2d0116c7 100644 --- a/Task/Polyspiral/EasyLang/polyspiral.easy +++ b/Task/Polyspiral/EasyLang/polyspiral.easy @@ -1,19 +1,18 @@ -color 944 -linewidth 0.3 +gcolor 944 +glinewidth 0.3 on animate - clear + gclear incr = (incr + 0.05) mod 360 - x1 = 50 - y1 = 50 + x = 50 + y = 50 length = 1 angle = incr - move x1 y1 for i = 1 to 150 - x2 = x1 + cos angle * length - y2 = y1 + sin angle * length - line x2 y2 - x1 = x2 - y1 = y2 + xp = x + yp = y + x += cos angle * length + y += sin angle * length + gline xp yp x y length += 1 angle += incr . diff --git a/Task/Population-count/EasyLang/population-count.easy b/Task/Population-count/EasyLang/population-count.easy index 5d9bfc2c3b..74545e76a2 100644 --- a/Task/Population-count/EasyLang/population-count.easy +++ b/Task/Population-count/EasyLang/population-count.easy @@ -5,7 +5,7 @@ func popcnt x . . return r . -proc show3 . . +proc show3 . write "3^n:" bb = 1 for i = 1 to 30 @@ -14,7 +14,7 @@ proc show3 . . . print "" . -proc show s$ x . . +proc show s$ x . write s$ while n < 30 if popcnt i mod 2 = x diff --git a/Task/Power-set/Crystal/power-set.cr b/Task/Power-set/Crystal/power-set.cr new file mode 100644 index 0000000000..4e94945ee1 --- /dev/null +++ b/Task/Power-set/Crystal/power-set.cr @@ -0,0 +1,14 @@ +struct Set + def powerset + result = Set(typeof(self)).new + arr = to_a + (0..size).each do |n| + arr.each_combination(n, true) do |comb| + result << comb.to_set + end + end + result + end +end + +p [1, 2, 3, 4].to_set.powerset diff --git a/Task/Power-set/M2000-Interpreter/power-set.m2000 b/Task/Power-set/M2000-Interpreter/power-set.m2000 new file mode 100644 index 0000000000..6a9d634cd6 --- /dev/null +++ b/Task/Power-set/M2000-Interpreter/power-set.m2000 @@ -0,0 +1,72 @@ +Function ToStringSet { + if match("A") then + read SetA + else.if not empty then + SetA=Cons(array([])) + else + SetA=(,) + End if + k=each(SetA) + variant z + while k + z=Array(k) + if type$(z)="tuple" then + if len(Array(k))=0 then + data "∅" + else.if type$(z, 0)="tuple" then + data "{∅}" + else + data "{"+(Array(k)#str$(", "))+"}" + end if + else + data z + end if + end while + if len(SetA)=0 then + ="∅" + else + ="{"+Array([])#Str$(", ")+"}" + end if +} +Function PowerSet { + if match("A") then + read SetA + else.if not empty then + SetA=Cons(array([])) + else + SetA=(,) + End if + a$=string$("0",Len(SetA)) + p=lambda a$ -> { + boolean ok + if len(a$)=0 then ="": exit + for i=1 to len(A$) + if mid$(a$,i,1)="0" then insert i,1 a$="1": ok=true : exit else insert i,1 a$="0" + next + if ok then =a$ else ="" + } + if Len(setA)>1 then + setAll=("{}",) + else + setAll=((,),) + end if + do + z=p() + if len(z)=0 then exit + SetB=(,) + for i=1 to len(z) + if mid$(z, i,1)="1" then + SetB=SetB#end(SetA#Slice(i-1, i-1)) + end if + next + Append setAll, (SetB,) + always + =setAll +} +open dir$+"powerset.txt" for wide output as #f + Print #f, "P(";ToStringSet();")=";ToStringSet(PowerSet()) + Print #f, "P(";ToStringSet(PowerSet());")=";ToStringSet(PowerSet(PowerSet())) + Print #f, "P(";ToStringSet(1,2,3,4);")=";ToStringSet(PowerSet(1,2,3,4)) + Print #f, "P(";ToStringSet("A", "B");")=";ToStringSet(PowerSet("A", "B")) +close #f +win notepad.exe, dir$+"powerset.txt" diff --git a/Task/Power-set/Refal/power-set.refal b/Task/Power-set/Refal/power-set.refal new file mode 100644 index 0000000000..077d5098c5 --- /dev/null +++ b/Task/Power-set/Refal/power-set.refal @@ -0,0 +1,15 @@ +$ENTRY Go { + = > + > + >; +}; + +Powerset { + = (); + e.X t.I, : e.F = e.F ; +}; + +Append { + t.I = ; + t.I (e.X) e.Y = (e.X t.I) ; +}; diff --git a/Task/Primality-by-Wilsons-theorem/REXX/primality-by-wilsons-theorem.rexx b/Task/Primality-by-Wilsons-theorem/REXX/primality-by-wilsons-theorem.rexx index 732ea49377..7e3c3bfd7e 100644 --- a/Task/Primality-by-Wilsons-theorem/REXX/primality-by-wilsons-theorem.rexx +++ b/Task/Primality-by-Wilsons-theorem/REXX/primality-by-wilsons-theorem.rexx @@ -1,53 +1,74 @@ -/*REXX pgm tests for primality via Wilson's theorem: a # is prime if p divides (p-1)! +1*/ -parse arg LO zz /*obtain optional arguments from the CL*/ -if LO=='' | LO=="," then LO= 120 /*Not specified? Then use the default.*/ -if zz ='' | zz ="," then zz=2 3 9 15 29 37 47 57 67 77 87 97 237 409 659 /*use default?*/ -sw= linesize() - 1; if sw<1 then sw= 79 /*obtain the terminal's screen width. */ -digs = digits() /*the current number of decimal digits.*/ -#= 0 /*number of (LO) primes found so far.*/ -!.= 1 /*placeholder for factorial memoization*/ -$= /* " to hold a list of primes.*/ - do p=1 until #=LO; oDigs= digs /*remember the number of decimal digits*/ - ?= isPrimeW(p) /*test primality using Wilson's theorem*/ - if digs>Odigs then numeric digits digs /*use larger number for decimal digits?*/ - if \? then iterate /*if not prime, then ignore this number*/ - #= # + 1; $= $ p /*bump prime counter; add prime to list*/ - end /*p*/ +-- 26 Mar 2025 +include Settings +numeric digits 10 -call show 'The first ' LO " prime numbers are:" -w= max( length(LO), length(word(reverse(zz),1))) /*used to align the number being tested*/ -@is.0= " isn't"; @is.1= 'is' /*2 literals used for display: is/ain't*/ +say 'PRIMALITY BY WILSON''S THEOREM' +say version say - do z=1 for words(zz); oDigs= digs /*remember the number of decimal digits*/ - p= word(zz, z) /*get a number from user─supplied list.*/ - ?= isPrimeW(p) /*test primality using Wilson's theorem*/ - if digs>Odigs then numeric digits digs /*use larger number for decimal digits?*/ - say right(p, max(w,length(p) ) ) @is.? "prime." - end /*z*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrimeW: procedure expose !. digs; parse arg x '' -1 last; != 1; xm= x - 1 - if x<2 then return 0 /*is the number too small to be prime? */ - if x==2 | x==5 then return 1 /*is the number a two or a five? */ - if last//2==0 | last==5 then return 0 /*is the last decimal digit even or 5? */ - if !.xm\==1 then != !.xm /*has the factorial been pre─computed? */ - else do; if xm>!.0 then do; base= !.0+1; _= !.0; != !._; end - else base= 2 /* [↑] use shortcut.*/ - do j=!.0+1 to xm; != ! * j /*compute factorial.*/ - if pos(., !)\==0 then do; parse var ! 'E' expon - numeric digits expon +99 - digs = digits() - end /* [↑] has exponent,*/ - end /*j*/ /*bump numeric digs.*/ - if xm<999 then do; !.xm=!; !.0=xm; end /*assign factorial. */ - end /*only save small #s*/ - if (!+1)//x==0 then return 1 /*X is a prime.*/ - return 0 /*" isn't " " */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -show: parse arg header,oo; say header /*display header for the first N primes*/ - w= length( word($, LO) ) /*used to align prime numbers in $ list*/ - do k=1 for LO; _= right( word($, k), w) /*build list for displaying the primes.*/ - if length(oo _)>sw then do; say substr(oo,2); oo=; end /*a line overflowed?*/ - oo= oo _ /*display a line. */ - end /*k*/ /*does pretty print.*/ - if oo\='' then say substr(oo, 2); return /*display residual (if any overflowed).*/ +call ShowWilson 1,660 +call ShowWilson 7901,8269 +do i = 3 to 6 + a = 1'E'i; a = a+1; b = a+999 + call CompareWilsonMR a,b +end +exit + +ShowWilson: +procedure expose glob. +arg xx,yy +call Time('r') +say 'Primes between' Std(xx) 'and' Std(yy) +n = 0; w = Xpon(yy)+2 +do i = xx to yy + if Isprime(i) then do + n = n+1 + call Charout ,Right(i,w) + if n//10 = 0 then + say + end +end +say +say n 'primes found' +say Format(Time('e'),,3) 'seconds'; say +return + +CompareWilsonMR: +procedure +arg xx,yy +call Time('r') +do i = xx to yy + call Isprime i +end +e1 = Time('e') +call Time('r') +do i = xx to yy + call Prime i +end +e2 = Time('e') +say 'For n between' Right(Std(xx),7) 'and' Right(Std(yy),7), +'Wilson took' Format(e1,3,3)'s and Miller-Rabin' Format(e2,3,3)'s' +return + +Isprime: +procedure expose glob. +arg xx +if xx < 2 then + return 0 +if xx = 2 then + return 1 +if Even(xx) then + return 0 +f = 1; x1 = xx-1 +do i = 2 to x1 + f = (f*i)//xx +end +if f = x1 then + return 1 +else + return 0 + +include Sequences +include Numbers +include Functions +include Constants +include Abend diff --git a/Task/Primality-by-trial-division/Odin/primality-by-trial-division.odin b/Task/Primality-by-trial-division/Odin/primality-by-trial-division.odin new file mode 100644 index 0000000000..4c922f4a26 --- /dev/null +++ b/Task/Primality-by-trial-division/Odin/primality-by-trial-division.odin @@ -0,0 +1,29 @@ +package main + +import "core:fmt" +import "core:math" + +prime ::proc(n:i32)->bool{ + if (n<2){ + return false + } + else { + + test:=true + for i:=2;i<=int(math.sqrt_f16(f16(n)));i+=1{ + if (n%i32(i))==0{ + return false + } + } + return test + } + +} + +main :: proc() { + + for i:=2;i<=100;i+=1{ + fmt.printf("%i: ", i) + fmt.println(prime(i32(i))) + } +} diff --git a/Task/Primality-by-trial-division/PascalABC.NET/primality-by-trial-division.pas b/Task/Primality-by-trial-division/PascalABC.NET/primality-by-trial-division.pas index fc3525df36..f2bc28dfb8 100644 --- a/Task/Primality-by-trial-division/PascalABC.NET/primality-by-trial-division.pas +++ b/Task/Primality-by-trial-division/PascalABC.NET/primality-by-trial-division.pas @@ -3,7 +3,7 @@ begin if N = 1 then Result := False else Result := True; - for var i:=2 to N.Sqrt.Round do + for var i:=2 to N.Sqrt.Trunc do if N.Divs(i) then begin Result := False; diff --git a/Task/Primality-by-trial-division/REXX/primality-by-trial-division-1.rexx b/Task/Primality-by-trial-division/REXX/primality-by-trial-division-1.rexx deleted file mode 100644 index 8341632309..0000000000 --- a/Task/Primality-by-trial-division/REXX/primality-by-trial-division-1.rexx +++ /dev/null @@ -1,21 +0,0 @@ -/*REXX program tests for primality by using (kinda smartish) trial division. */ -parse arg n .; if n=='' then n=10000 /*let the user choose the upper limit. */ -tell=(n>0); n=abs(n) /*display the primes only if N > 0. */ -p=0 /*a count of the primes found (so far).*/ - do j=-57 to n /*start in the cellar and work up. */ - if \isPrime(j) then iterate /*if not prime, then keep looking. */ - p=p+1 /*bump the jelly bean counter. */ - if tell then say right(j,20) 'is prime.' /*maybe display prime to the terminal. */ - end /*j*/ -say -say "There are " p " primes up to " n ' (inclusive).' -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure; parse arg x /*get the number to be tested. */ - if wordpos(x, '2 3 5 7')\==0 then return 1 /*is number a teacher's pet? */ - if x<2 | x//2==0 | x//3==0 then return 0 /*weed out the riff-raff. */ - do k=5 by 6 until k*k>x /*skips odd multiples of 3. */ - if x//k==0 | x//(k+2)==0 then return 0 /*a pair of divides. ___ */ - end /*k*/ /*divide up through the √ x */ - /*Note: // is ÷ remainder.*/ - return 1 /*done dividing, it's prime. */ diff --git a/Task/Primality-by-trial-division/REXX/primality-by-trial-division-2.rexx b/Task/Primality-by-trial-division/REXX/primality-by-trial-division-2.rexx deleted file mode 100644 index b8afb7f1e1..0000000000 --- a/Task/Primality-by-trial-division/REXX/primality-by-trial-division-2.rexx +++ /dev/null @@ -1,22 +0,0 @@ -/*REXX program tests for primality by using (kinda smartish) trial division. */ -parse arg n .; if n=='' then n=10000 /*let the user choose the upper limit. */ -tell=(n>0); n=abs(n) /*display the primes only if N > 0. */ -p=0 /*a count of the primes found (so far).*/ - do j=-57 to n /*start in the cellar and work up. */ - if \isPrime(j) then iterate /*if not prime, then keep looking. */ - p=p+1 /*bump the jelly bean counter. */ - if tell then say right(j,20) 'is prime.' /*maybe display prime to the terminal. */ - end /*j*/ -say -say "There are " p " primes up to " n ' (inclusive).' -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure; parse arg x /*get integer to be investigated.*/ - if x<11 then return wordpos(x, '2 3 5 7')\==0 /*is it a wee prime? */ - if x//2==0 then return 0 /*eliminate all the even numbers.*/ - if x//3==0 then return 0 /* ··· and eliminate the triples.*/ - do k=5 by 6 until k*k>x /*this skips odd multiples of 3. */ - if x//k ==0 then return 0 /*perform a divide (modulus), */ - if x//(k+2)==0 then return 0 /* ··· and the next umpty one. */ - end /*k*/ /*Note: REXX // is ÷ remainder.*/ - return 1 /*did all divisions, it's prime. */ diff --git a/Task/Primality-by-trial-division/REXX/primality-by-trial-division-3.rexx b/Task/Primality-by-trial-division/REXX/primality-by-trial-division-3.rexx deleted file mode 100644 index bbc635e32f..0000000000 --- a/Task/Primality-by-trial-division/REXX/primality-by-trial-division-3.rexx +++ /dev/null @@ -1,49 +0,0 @@ -/*REXX program tests for primality by using (kinda smartish) trial division. */ -parse arg n .; if n=='' then n=10000 /*let the user choose the upper limit. */ -tell=(n>0); n=abs(n) /*display the primes only if N > 0. */ -p=0 /*a count of the primes found (so far).*/ - do j=-57 to n /*start in the cellar and work up. */ - if \isPrime(j) then iterate /*if not prime, then keep looking. */ - p=p+1 /*bump the jelly bean counter. */ - if tell then say right(j,20) 'is prime.' /*maybe display prime to the terminal. */ - end /*j*/ -say -say "There are " p " primes up to " n ' (inclusive).' -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure; parse arg x /*get the integer to be investigated. */ - if x<107 then return wordpos(x, '2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53', - '59 61 67 71 73 79 83 89 97 101 103')\==0 /*some low primes.*/ - if x// 2 ==0 then return 0 /*eliminate all the even numbers. */ - if x// 3 ==0 then return 0 /* ··· and eliminate the triples. */ - parse var x '' -1 _ /* obtain the rightmost digit.*/ - if _ ==5 then return 0 /* ··· and eliminate the nickels. */ - if x// 7 ==0 then return 0 /* ··· and eliminate the luckies. */ - if x//11 ==0 then return 0 - if x//13 ==0 then return 0 - if x//17 ==0 then return 0 - if x//19 ==0 then return 0 - if x//23 ==0 then return 0 - if x//29 ==0 then return 0 - if x//31 ==0 then return 0 - if x//37 ==0 then return 0 - if x//41 ==0 then return 0 - if x//43 ==0 then return 0 - if x//47 ==0 then return 0 - if x//53 ==0 then return 0 - if x//59 ==0 then return 0 - if x//61 ==0 then return 0 - if x//67 ==0 then return 0 - if x//71 ==0 then return 0 - if x//73 ==0 then return 0 - if x//79 ==0 then return 0 - if x//83 ==0 then return 0 - if x//89 ==0 then return 0 - if x//97 ==0 then return 0 - if x//101==0 then return 0 - if x//103==0 then return 0 /*Note: REXX // is ÷ remainder. */ - do k=107 by 6 while k*k<=x /*this skips odd multiples of three. */ - if x//k ==0 then return 0 /*perform a divide (modulus), */ - if x//(k+2)==0 then return 0 /* ··· and the next also. ___ */ - end /*k*/ /*divide up through the √ x */ - return 1 /*after all that, ··· it's a prime. */ diff --git a/Task/Primality-by-trial-division/REXX/primality-by-trial-division.rexx b/Task/Primality-by-trial-division/REXX/primality-by-trial-division.rexx new file mode 100644 index 0000000000..f823f29a39 --- /dev/null +++ b/Task/Primality-by-trial-division/REXX/primality-by-trial-division.rexx @@ -0,0 +1,90 @@ +-- 26 Mar 2025 +include Settings +numeric digits 15 + +say 'PRIMALITY BY TRIAL DIVISION' +say version +say +call ShowTrial 1,100 +call ShowMR 1,100 +do i = 3 to 13 + a = 1'E'i; a = a+1; b = a+999 + call CompareTrialMR a,b +end +exit + +ShowTrial: +procedure +arg xx,yy +call Time('r') +say 'Primes between' std(xx) 'and' std(yy) 'by trial division' +n = 0; w = Xpon(yy)+2 +do i = xx to yy + if Isprime(i) then do + n = n+1 + call Charout ,Right(i,w) + if n//10 = 0 then + say + end +end +say +say n 'primes found' +say Format(Time('e'),,3) 'seconds'; say +return + +ShowMR: +procedure +arg xx,yy +call Time('r') +say 'Primes between' std(xx) 'and' std(yy) 'by Miller-Rabin' +n = 0; w = Xpon(yy)+2 +do i = xx to yy + if Prime(i) then do + n = n+1 + call Charout ,Right(i,w) + if n//10 = 0 then + say + end +end +say +say n 'primes found' +say Format(Time('e'),,3) 'seconds'; say +return + +CompareTrialMR: +procedure +arg xx,yy +call Time('r') +do i = xx to yy + call Isprime i +end +e1 = Time('e') +call Time('r') +do i = xx to yy + call Prime i +end +e2 = Time('e') +say 'For n between' Right(Std(xx),14) 'and' Right(Std(yy),14), +'trial division took' Format(e1,2,3)'s and Miller-Rabin' Format(e2,2,3)'s' +return + +Isprime: +procedure +arg xx +if xx < 2 then + return 0 +if xx = 2 then + return 1 +if Even(xx) then + return 0 +do i = 3 by 2 to Isqrt(xx) + if xx//i = 0 then + return 0 +end +return 1 + +include Sequences +include Numbers +include Functions +include Constants +include Abend diff --git a/Task/Prime-conspiracy/REXX/prime-conspiracy.rexx b/Task/Prime-conspiracy/REXX/prime-conspiracy-1.rexx similarity index 100% rename from Task/Prime-conspiracy/REXX/prime-conspiracy.rexx rename to Task/Prime-conspiracy/REXX/prime-conspiracy-1.rexx diff --git a/Task/Prime-conspiracy/REXX/prime-conspiracy-2.rexx b/Task/Prime-conspiracy/REXX/prime-conspiracy-2.rexx new file mode 100644 index 0000000000..e705a5fdb3 --- /dev/null +++ b/Task/Prime-conspiracy/REXX/prime-conspiracy-2.rexx @@ -0,0 +1,67 @@ +-- 8 May 2025 +include Settings +numeric digits 10 +arg xx +if xx = '' then + xx = 1e6 + +say 'PRIME CONSPIRACY' +say version +say +call GetPrimes xx +call CollectStats +call ShowStats +exit + +GetPrimes: +call Time('r') +arg xx +say 'Analysis for first' xx 'primes follows' +say +say 'Get primes...' +call Primes -xx; prim.0 = xx +say xx 'primes found' +say Format(Time('e'),,3) 'seconds'; say +return + +CollectStats: +call Time('r') +say 'Collect statistics...' +tran. = 0 +a = Right(prim.1,1); tran.2 = 1 +do i = 2 to prim.0 + b = Right(prim.i,1); d = Right(prim.i,2)+0 + tran.a.b = tran.a.b+1; tran.d = tran.d+1 + a = b +end +say Format(Time('e'),,3) 'seconds'; say +return + +ShowStats: +say 'Transition count...' +do i = 1 to 9 + do j = 1 to 9 + if tran.i.j > 0 then do + say 'Transition' i'->'j 'Count' Right(tran.i.j,5) 'Freq' Format(100*tran.i.j/(prim.0-1),2,3)'%' + end + end +end +say +say 'Last 2 digits count...' +do i = 1 to 99 + if tran.i > 0 then do + if i < 10 then + d = '0'i + else + d = i + say 'Digits' d 'Count' Right(tran.i,6) 'Freq' Format(100*tran.i/prim.0,2,3)'%' + end +end +say +return + +include Sequences +include Functions +include Special +include Constants +include Abend diff --git a/Task/Prime-decomposition/REXX/prime-decomposition-1.rexx b/Task/Prime-decomposition/REXX/prime-decomposition-1.rexx deleted file mode 100644 index dcbc1d8c1d..0000000000 --- a/Task/Prime-decomposition/REXX/prime-decomposition-1.rexx +++ /dev/null @@ -1,82 +0,0 @@ -/*REXX pgm does prime decomposition of a range of positive integers (with a prime count)*/ -Numeric Digits 1000 /*handle thousand digits For the powers*/ -Parse Arg bot top step base add /*get optional arguments from the C.L. */ -If bot='?' Then Do - Say 'rexx pfoo bot top step base add' - Exit - End -If bot=='' Then /* no arguments given */ - Parse Value 1 100 With bot top /* set default range .*/ -If top=='' Then top=bot /* process one number */ -If step=='' Then step=1 /* step=2 to process only odd numbers */ -If add =='' Then add=-1 /* for Mersenne tests */ -tell=top>0 /*If TOP is negative, suppress displays*/ -top=abs(top) -w=length(top) /*get maximum width For aligned display*/ -If base\=='' Then - w=length(base**top) /*will be testing powers of two later? */ -tag.=left('', 7) /*some literals: pad; prime (or not).*/ -tag.0='{unity}' -tag.1='[prime]' -Numeric Digits max(9,w+1) /*maybe increase the digits precision. */ -np=0 /*np: is the number of primes found.*/ -Do n=bot To top by step /*process a single number or a range. */ - ?=n - If base\=='' Then /*should we perform a 'Mersenne' test? */ - ?=base**n+add - pf=factr(?) /* get prime factors */ - f=words(pf) /* number of prime factors */ - If f=1 Then /* If the number is prime */ - np=np+1 /* Then bump prime counter */ - If tell Then - Say right(?,w) right('('f')',9) 'prime factors: ' tag.f pf - End /*n*/ -Say '' -ps='prime' -If f>1 Then ps=ps's' /*setup For proper English in sentence.*/ -Say right(np, w+9+1) ps 'found.' /*display the number of primes found. */ -Exit /*stick a fork in it, we're all done. */ -/*---------------------------------------------------------------------------*/ -factr: Procedure - Parse Arg x 1 d,pl /*set X, D to argument 1, pl to null */ - If x==1 Then Return '' /*handle the special case of X=1. */ - primes=2 3 5 7 - Do While primes>'' /* first check the small primes */ - Parse Var primes prime primes - Do While x//prime==0 - pl=pl prime - x=x%prime - End - End - r=isqrt(x) - Do j=11 by 6 To r /*insure that J isn't divisible by 3. */ - Parse var j '' -1 _ /*obtain the last decimal digit of J. */ - If _\==5 Then Do - Do While x//j==0 - pl=pl j - x=x%j - End /*maybe reduce by J. */ - End - If _ ==3 Then Iterate /*If next Y is divisible by 5? Skip. */ - y=j+2 - Do While x//y==0 - pl=pl y - x=x%y - End /*maybe reduce by y. */ - End /*j*/ - - If x==1 Then Return pl /*Is residual=unity? Then don't append.*/ - Return pl x /*return pl with appended residual.*/ - -isqrt: Procedure - Parse Arg x - x=abs(x) - Parse Value 0 x with lo hi - Do While lo<=hi - t=(lo+hi)%2 - If t**2>x Then - hi=t-1 - Else - lo=t+1 - End - Return t diff --git a/Task/Prime-decomposition/REXX/prime-decomposition-2.rexx b/Task/Prime-decomposition/REXX/prime-decomposition-2.rexx deleted file mode 100644 index 864480da70..0000000000 --- a/Task/Prime-decomposition/REXX/prime-decomposition-2.rexx +++ /dev/null @@ -1,81 +0,0 @@ -/*REXX pgm does prime decomposition of a range of positive integers (with a prime count)*/ -Numeric Digits 1000 /*handle thousand digits For the powers*/ -Parse Arg bot top step base add /*get optional arguments from the C.L. */ -If bot='?' Then Do - Say 'rexx pfoo bot top step base add' - Exit - End -If bot=='' Then /* no arguments given */ - Parse Value 1 100 With bot top /* set default range .*/ -If top=='' Then top=bot /* process one number */ -If step=='' Then step=1 /* step=2 to process only odd numbers */ -If add =='' Then add=-1 /* for Mersenne tests */ -tell=top>0 /*If TOP is negative, suppress displays*/ -top=abs(top) -w=length(top) /*get maximum width For aligned display*/ -If base\=='' Then - w=length(base**top) /*will be testing powers of two later? */ -tag.=left('', 7) /*some literals: pad; prime (or not).*/ -tag.0='{unity}' -tag.1='[prime]' -Numeric Digits max(9,w+1) /*maybe increase the digits precision. */ -np=0 /*np: is the number of primes found.*/ -Do n=bot To top by step /*process a single number or a range. */ - ?=n - If base\=='' Then /*should we perform a 'Mersenne' test? */ - ?=base**n+add - pf=factr(?) /* get prime factors */ - f=words(pf) /* number of prime factors */ - If f=1 Then /* If the number is prime */ - np=np+1 /* Then bump prime counter */ - If tell Then - Say right(?,w) right('('f')',9) 'prime factors: ' tag.f pf - End /*n*/ -Say '' -ps='prime' -If f>1 Then ps=ps's' /*setup For proper English in sentence.*/ -Say right(np, w+9+1) ps 'found.' /*display the number of primes found. */ -Exit /*stick a fork in it, we're all done. */ -/*---------------------------------------------------------------------------*/ -factr: Procedure - Parse Arg x 1 d,pl /*set X, D to argument 1, pl to null */ - If x==1 Then Return '' /*handle the special case of X=1. */ - primes=2 3 5 7 11 13 17 19 23 - Do While primes>'' /* first check the small primes */ - Parse Var primes prime primes - Do While x//prime==0 - pl=pl prime - x=x%prime - End - End - r=isqrt(x) - Do j=29 by 6 To r /*insure that J isn't divisible by 3.*/ - Parse var j '' -1 _ /*obtain the last decimal digit of J. */ - If _\==5 Then Do - Do While x//j==0 - pl=pl j - x=x%j - End /*maybe reduce by J. */ - End - If _ ==3 Then Iterate /*If next Y is divisible by 5? Skip. */ - y=j+2 - Do While x//y==0 - pl=pl y - x=x%y - End /*maybe reduce by y. */ - End /*j*/ - If x==1 Then Return pl /*Is residual=unity? Then don't append.*/ - Return pl x /*return pl with appended residual.*/ - -isqrt: Procedure - Parse Arg x - x=abs(x) - Parse Value 0 x with lo hi - Do While lo<=hi - t=(lo+hi)%2 - If t**2>x Then - hi=t-1 - Else - lo=t+1 - End - Return t diff --git a/Task/Prime-decomposition/REXX/prime-decomposition-3.rexx b/Task/Prime-decomposition/REXX/prime-decomposition-3.rexx deleted file mode 100644 index 86902ca626..0000000000 --- a/Task/Prime-decomposition/REXX/prime-decomposition-3.rexx +++ /dev/null @@ -1,69 +0,0 @@ -/*REXX pgm does prime decomposition of a range of positive integers (with a prime count)*/ -call time('r') -Numeric Digits 1000 /*handle thousand digits For the powers*/ -Parse Arg bot top step base add /*get optional arguments from the C.L. */ -If bot='?' Then Do - Say 'rexx pfoo bot top step base add' - Exit - End -If bot=='' Then /* no arguments given */ - Parse Value 1 100 With bot top /* set default range .*/ -If top=='' Then top=bot /* process one number */ -If step=='' Then step=1 /* step=2 to process only odd numbers */ -If add =='' Then add=-1 /* for Mersenne tests */ -tell=top>0 /*If TOP is negative, suppress displays*/ -top=abs(top) -w=length(top) /*get maximum width For aligned display*/ -If base\=='' Then - w=length(base**top) /*will be testing powers of two later? */ -tag.=left('', 7) /*some literals: pad; prime (or not).*/ -tag.0='{unity}' -tag.1='[prime]' -Numeric Digits max(9,w+1) /*maybe increase the digits precision. */ -np=0 /*np: is the number of primes found.*/ -Do n=bot To top by step /*process a single number or a range. */ - ?=n - If base\=='' Then /*should we perform a 'Mersenne' test? */ - ?=base**n+add - pf=factr(?) /* get prime factors */ - f=words(pf) /* number of prime factors */ - If f=1 Then /* If the number is prime */ - np=np+1 /* Then bump prime counter */ - If tell Then - Say right(?,w) right('('f')',9) 'prime factors: ' tag.f pf - End /*n*/ -Say '' -ps='prime' -If f>1 Then ps=ps's' /*setup For proper English in sentence.*/ -Say right(np, w+9+1) ps 'found.' /*display the number of primes found. */ -say format(time('e'),,3) 'seconds' -Exit /*stick a fork in it, we're all done. */ -/*---------------------------------------------------------------------------*/ -Factr: -procedure expose glob. -arg x -primes = '2 3 5 7 11 13 17 19 23'; pl = '' -do n = 1 to words(primes) - prime = word(primes,n) - do while x//prime = 0 - pl = pl prime; x = x%prime - end -end -do j = 29 by 6 while j*j <= x - d = right(j,1) - if d <> 5 then do - do while x//j = 0 - pl = pl j; x = x%j - end - end - if d = 3 then - iterate - y = j+2 - do while x//y = 0 - pl = pl y; x = x%y - end -end -if x = 1 then - return pl -else - return pl x diff --git a/Task/Prime-decomposition/REXX/prime-decomposition-4.rexx b/Task/Prime-decomposition/REXX/prime-decomposition-4.rexx deleted file mode 100644 index 20904dd265..0000000000 --- a/Task/Prime-decomposition/REXX/prime-decomposition-4.rexx +++ /dev/null @@ -1,103 +0,0 @@ -/*REXX pgm does prime decomposition of a range of positive integers (with a prime count)*/ -include Settings - -say version; say 'Prime decompositoion'; say -Numeric Digits 1000 /*handle thousand digits For the powers*/ -Parse Arg bot top step base add /*get optional arguments from the C.L. */ -If bot='qq' Then Do - Say 'rexx pfoo bot top step base add' - Exit - End -If bot=='' Then /* no arguments given */ - Parse Value 1 100 With bot top /* set default range .*/ -If top=='' Then top=bot /* process one Number */ -If step=='' Then step=1 /* step=2 to process only Odd numbers */ -If add =='' Then add=-1 /* for Mersenne tests */ -tell=top>0 /*If TOP is negative, suppress displays*/ -top=Abs(top) -w=Length(top) /*get maximum width For aligned display*/ -If base\=='' Then - w=Length(base**top) /*will be testing powers of two laterqq */ -tag.=Left('', 7) /*some literals: pad; Prime (or not).*/ -tag.0='{unity}' -tag.1='[Prime]' -Numeric Digits Max(9,w+1) /*maybe increase the digits precision. */ -np=0 /*np: is the Number of Primes found.*/ -Do n=bot To top by step /*process a single Number or a range. */ - qq=n - If base\=='' Then /*should we perform a 'Mersenne' testqq */ - qq=base**n+add - f=Factors(qq) /* Number of Prime Factors */ - If f=1 Then /* If the Number is Prime */ - np=np+1 /* Then bump Prime counter */ - If tell Then do - pf = '' - do i = 1 to f - pf = pf glob.factor.i - end - Say Right(qq,w) Right('('f')',9) 'Prime Factors: ' tag.f pf - end - End /*n*/ -Say '' -ps='Prime' -If f>1 Then ps=ps's' /*setup For proper English in sentence.*/ -Say Right(np, w+9+1) ps 'found.' /*display the Number of Primes found. */ -say Format(Time('e'),,3) 'seconds' -Exit /*stick a fork in it, we're all done. */ - -Factors: -/* Prime factors of an integer */ -procedure expose glob. -arg x -/* Fast values */ -if x = 1 then do - glob.factor.0 = 0 - return 0 -end -if x < 4 then do - glob.factor.1 = x; glob.factor.0 = 1 - return 1 -end -if Prime(x) then do - glob.factor.1 = x; glob.factor.0 = 1 - return 1 -end -/* Check low factors */ -n = 0 -pr = '2 3 5 7 11 13 17 19 23' -do i = 1 to Words(pr) - p = Word(pr,i) - do while x//p = 0 - n = n+1; glob.factor.n = p - x = x%p - end -end -/* Check higher factors */ -do j = 29 by 6 while j*j <= x - p = Right(j,1) - if p <> 5 then do - do while x//j = 0 - n = n+1; glob.factor.n = j - x = x%j - end - end - if p = 3 then - iterate - y = j+2 - do while x//y = 0 - n = n+1; glob.factor.n = y - x = x%y - end -end -/* Last factor */ -if x > 1 then do - n = n+1; glob.factor.n = x -end -glob.factor.0 = n -/* Return number of factors */ -return n - -include Functions -include Numbers -include Sequences -include Abend diff --git a/Task/Prime-decomposition/REXX/prime-decomposition.rexx b/Task/Prime-decomposition/REXX/prime-decomposition.rexx new file mode 100644 index 0000000000..9136f5edb0 --- /dev/null +++ b/Task/Prime-decomposition/REXX/prime-decomposition.rexx @@ -0,0 +1,41 @@ +-- 22 Mar 2025 +include Settings + +say 'PRIME DECOMPOSITION' +say version +say +numeric digits 50 +call ShowFactors 100,120 +call ShowFactors 720720 +call ShowFactors 9007199254740991 +call ShowFactors 2543821448263974486045199 +call ShowFactors 340282366920938463463374607431768211455 +exit + +ShowFactors: +arg xx,yy +if yy = '' then + yy = xx +do i = xx to yy + call Charout ,i '= ' + f = Factors(i) + if f = 1 then + call Charout ,'Prime' + else do + do j = 1 to f + if j < f then + call Charout ,fact.j 'x ' + else + call Charout ,fact.j + end + end + say +end +say Format(Time('e'),,3) 'seconds' +say +return + +include Functions +include Numbers +include Sequences +include Abend diff --git a/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/EasyLang/prime-numbers-whose-neighboring-pairs-are-tetraprimes.easy b/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/EasyLang/prime-numbers-whose-neighboring-pairs-are-tetraprimes.easy new file mode 100644 index 0000000000..8e93391ba7 --- /dev/null +++ b/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/EasyLang/prime-numbers-whose-neighboring-pairs-are-tetraprimes.easy @@ -0,0 +1,64 @@ +len nfac[] 1000000 +proc sieve . + nfac[1] = 1 + for i = 2 to len nfac[] + if nfac[i] = 0 + j = i + i + while j <= len nfac[] + if j div i mod i = 0 : nfac[j] = 5 + nfac[j] += 1 + j += i + . + . + . +. +sieve +# +fastfunc isprim num . + i = 3 + while i <= sqrt num + if num mod i = 0 : return 0 + i += 2 + . + return 1 +. +fastfunc nextprim prim . + if prim = 2 : return 3 + repeat + prim += 2 + until isprim prim = 1 + . + return prim +. +proc sort &d[] . + for i = 1 to len d[] - 1 : for j = i + 1 to len d[] + if d[j] < d[i] : swap d[j] d[i] + . +. +proc calc max dir . + h$ = " preceeded" + if dir = 1 : h$ = " followed" + print "Primes below " & max & h$ & " by a tetraprime pair:" + if max <= 100000 : print "" + prim = 7 + while prim < max + if nfac[prim + dir] = 4 and nfac[prim + dir + dir] = 4 + if (prim + dir) mod 7 = 0 or (prim + dir + dir) mod 7 = 0 : cnt += 1 + if prev > 0 : d[] &= prim - prev + prev = prim + if max <= 100000 : write prim & " " + . + prim = nextprim prim + . + if max <= 100000 : print "" + print "" + print len d[] + 1 & " " & cnt + print "" + sort d[] + print d[1] & " " & d[$ div 2 + 1] & " " & d[$] + print "" +. +calc 100000 -1 +calc 100000 1 +calc 1000000 -1 +calc 1000000 1 diff --git a/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/PARI-GP/prime-numbers-whose-neighboring-pairs-are-tetraprimes.parigp b/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/PARI-GP/prime-numbers-whose-neighboring-pairs-are-tetraprimes.parigp new file mode 100644 index 0000000000..357af19cb6 --- /dev/null +++ b/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/PARI-GP/prime-numbers-whose-neighboring-pairs-are-tetraprimes.parigp @@ -0,0 +1,35 @@ +tetra(n)=factor(n)[,2]==[1,1,1,1]~ +diff(v)=vector(#v-1,i,v[i+1]-v[i]) +median(v)=v=vecsort(v); if(#v%2, v[(#v+1)/2], (v[#v/2]+v[#v/2+1])/2) \\ averages the middle two if there are an even number +listPre(lim)=my(v=List()); forprimestep(p=3,lim,4, if(tetra(p-1) && tetra(p-2), listput(v,p))); Vec(v) +listPost(lim)=my(v=List()); forprimestep(p=5,lim,4, if(tetra(p+1) && tetra(p+2), listput(v,p))); Vec(v) +pre5=listPre(1e5) \\ #1 +post5=listPost(1e5) \\ #2 +#select(p->p%7<3, pre5) \\ #3 +#select(p->p%7>4, post5) \\ #3 +vecmin(diff(pre5)) \\ #4 +vecmin(diff(post5)) \\ #4 +median(diff(pre5)) \\ #4 +median(diff(post5)) \\ #4 +vecmax(diff(pre5)) \\ #4 +vecmax(diff(post5)) \\ #4 +pre6=listPre(1e6); #pre6 \\ #5 +post6=listPost(1e6); #post6 \\ #5 +#select(p->p%7<3, pre6) \\ #5 +#select(p->p%7>4, post6) \\ #5 +vecmin(diff(pre6)) \\ #5 +vecmin(diff(post6)) \\ #5 +median(diff(pre6)) \\ #5 +median(diff(post6)) \\ #5 +vecmax(diff(pre6)) \\ #5 +vecmax(diff(post6)) \\ #5 +pre7=listPre(1e7); #pre7 +post7=listPost(1e7); #post7 +#select(p->p%7<3, pre7) +#select(p->p%7>4, post7) +vecmin(diff(pre7)) +vecmin(diff(post7)) +median(diff(pre7)) +median(diff(post7)) +vecmax(diff(pre7)) +vecmax(diff(post7)) diff --git a/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/Python/prime-numbers-whose-neighboring-pairs-are-tetraprimes.py b/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/Python/prime-numbers-whose-neighboring-pairs-are-tetraprimes.py new file mode 100644 index 0000000000..8184163f2b --- /dev/null +++ b/Task/Prime-numbers-whose-neighboring-pairs-are-tetraprimes/Python/prime-numbers-whose-neighboring-pairs-are-tetraprimes.py @@ -0,0 +1,195 @@ +import math +import time +from collections import defaultdict + +def sieve_of_eratosthenes(limit): + """Generate all primes up to the given limit using the Sieve of Eratosthenes.""" + sieve = [True] * (limit + 1) + sieve[0] = sieve[1] = False + + for i in range(2, int(math.sqrt(limit)) + 1): + if sieve[i]: + for j in range(i*i, limit + 1, i): + sieve[j] = False + + return [i for i in range(limit + 1) if sieve[i]] + +def prime_factorization(n, primes_list, primes_set): + """Return the prime factorization of n as a list of primes.""" + if n in primes_set: + return [n] + + factors = [] + for p in primes_list: + if p * p > n: # No need to check beyond sqrt(n) + break + + while n % p == 0: + factors.append(p) + n //= p + + if n == 1: + break + + # If n is not fully factorized yet, it must be a prime itself + if n > 1: + factors.append(n) + + return factors + +def is_tetraprime(n, primes_list, primes_set, prime_factors_cache): + """Check if a number is a tetraprime (product of exactly 4 distinct primes).""" + if n in prime_factors_cache: + factors = prime_factors_cache[n] + else: + factors = prime_factorization(n, primes_list, primes_set) + prime_factors_cache[n] = factors + + # A tetraprime must have exactly 4 distinct prime factors + distinct_factors = set(factors) + return len(distinct_factors) == 4 and len(factors) == 4 + +def find_primes_with_tetraprime_neighbors(primes, limit, direction="preceding"): + """Find primes whose neighboring pairs are both tetraprimes.""" + result = [] + primes_set = set(primes) + prime_factors_cache = {} + + for prime in primes: + if prime >= limit: + break + + if direction == "preceding" and prime >= 3: + if (is_tetraprime(prime-1, primes, primes_set, prime_factors_cache) and + is_tetraprime(prime-2, primes, primes_set, prime_factors_cache)): + result.append(prime) + elif direction == "following" and prime <= limit - 2: + if (is_tetraprime(prime+1, primes, primes_set, prime_factors_cache) and + is_tetraprime(prime+2, primes, primes_set, prime_factors_cache)): + result.append(prime) + + return result + +def has_prime_factor_7(n, primes_list, primes_set, prime_factors_cache): + """Check if a number has 7 as one of its prime factors.""" + if n in prime_factors_cache: + factors = prime_factors_cache[n] + else: + factors = prime_factorization(n, primes_list, primes_set) + prime_factors_cache[n] = factors + + return 7 in factors + +def count_factor_7_primes(primes_list, primes, primes_set, direction): + """Count primes whose neighboring pairs have at least one member with a prime factor of 7.""" + count = 0 + prime_factors_cache = {} + + for prime in primes_list: + if direction == "preceding": + neighbors = [prime-1, prime-2] + else: # following + neighbors = [prime+1, prime+2] + + if any(has_prime_factor_7(n, primes, primes_set, prime_factors_cache) for n in neighbors): + count += 1 + + return count + +def calculate_prime_gaps(primes_list): + """Calculate the gaps between consecutive primes in the list.""" + if not primes_list or len(primes_list) < 2: + return [] + + return [primes_list[i] - primes_list[i-1] for i in range(1, len(primes_list))] + +def calculate_gap_statistics(gaps): + """Calculate min, median, and max gap statistics.""" + if not gaps: + return None, None, None + + min_gap = min(gaps) + max_gap = max(gaps) + + # Calculate median + gaps_sorted = sorted(gaps) + n = len(gaps_sorted) + if n % 2 == 0: + median_gap = int((gaps_sorted[n//2 - 1] + gaps_sorted[n//2]) / 2) + else: + median_gap = int(gaps_sorted[n//2]) + + return min_gap, median_gap, max_gap + +def format_primes_grid(primes_list, num_columns=10): + """Format a list of primes into a grid with specified number of columns.""" + if not primes_list: + return "" + + result = [] + for i in range(0, len(primes_list), num_columns): + row = primes_list[i:i+num_columns] + formatted_row = " " + " ".join(f"{p:6d}" for p in row) + result.append(formatted_row) + + return "\n".join(result) + +def print_prime_results(primes, count_with_factor_7, direction, limit, show_primes=True): + """Print results for a set of primes with tetraprime neighbors.""" + direction_text = "preceding" if direction == "preceding" else "following" + + print(f"\nFound {len(primes)} primes under {limit:,} whose {direction_text} neighboring pair are tetraprimes") + + if show_primes and primes: + print(":") + print(format_primes_grid(primes)) + + print(f"\nof which {count_with_factor_7} have a neighboring pair one of whose factors is 7.") + + # Calculate and print gap statistics + gaps = calculate_prime_gaps(primes) + if gaps: + min_gap, median_gap, max_gap = calculate_gap_statistics(gaps) + print(f"\nMinimum gap between those {len(primes)} primes: {min_gap}") + print(f"Median gap between those {len(primes)} primes: {median_gap}") + print(f"Maximum gap between those {len(primes)} primes: {max_gap}") + +def solve_for_limit(limit): + """Solve all parts of the problem for a given limit.""" + print(f"\nSolving for primes less than {limit:,}:") + start_time = time.time() + + # Generate all primes up to the limit + primes = sieve_of_eratosthenes(limit) + primes_set = set(primes) + + # Find primes with tetraprime neighbors + preceding_primes = find_primes_with_tetraprime_neighbors(primes, limit, "preceding") + following_primes = find_primes_with_tetraprime_neighbors(primes, limit, "following") + + # Count primes with factor 7 in neighbors + preceding_factor7_count = count_factor_7_primes(preceding_primes, primes, primes_set, "preceding") + following_factor7_count = count_factor_7_primes(following_primes, primes, primes_set, "following") + + # Show results + show_individual_primes = limit <= 100000 + print_prime_results(preceding_primes, preceding_factor7_count, "preceding", limit, show_individual_primes) + print_prime_results(following_primes, following_factor7_count, "following", limit, show_individual_primes) + + elapsed_time = time.time() - start_time + print(f"\nTime taken: {elapsed_time:.2f} seconds") + +if __name__ == "__main__": + print("Starting tetraprime neighbors analysis...") + + # Run all calculations sequentially + print("\n---------- PRIMES UNDER 100,000 ----------") + solve_for_limit(100000) + + print("\n---------- PRIMES UNDER 1,000,000 ----------") + solve_for_limit(1000000) + + print("\n---------- PRIMES UNDER 10,000,000 ----------") + solve_for_limit(10000000) + + print("\nAnalysis complete!") diff --git a/Task/Primes---allocate-descendants-to-their-ancestors/00-TASK.txt b/Task/Primes---allocate-descendants-to-their-ancestors/00-TASK.txt index 21e1436ef3..22e5532ff0 100644 --- a/Task/Primes---allocate-descendants-to-their-ancestors/00-TASK.txt +++ b/Task/Primes---allocate-descendants-to-their-ancestors/00-TASK.txt @@ -30,6 +30,10 @@ Example : 7 is a prime factor and, as such, has no parent. 46 has 3 ancestors (7, 10 and 25). + +129 = 3x43 is a descendant, because 3+43 = 46. +888 = 2x2x2x3x37 also, because 2+2+2+3+37 = 46. + 46 has 557 descendants. The list layout and the output for Parent [46] : diff --git a/Task/Primes---allocate-descendants-to-their-ancestors/ALGOL-68/primes---allocate-descendants-to-their-ancestors.alg b/Task/Primes---allocate-descendants-to-their-ancestors/ALGOL-68/primes---allocate-descendants-to-their-ancestors.alg new file mode 100644 index 0000000000..9c6f096c09 --- /dev/null +++ b/Task/Primes---allocate-descendants-to-their-ancestors/ALGOL-68/primes---allocate-descendants-to-their-ancestors.alg @@ -0,0 +1,108 @@ +BEGIN # Primes - allocate descendants to their ancestors # + # - based on the EasyLang sample # + + PR read "primes.incl.a68" PR # include prime utilities # + PR read "sort.incl.a68" PR # include sort utilities # + PR read "rows.incl.a68" PR # include row (array) utilities # + + INT max number = 99; # maximum number we will consider # + INT max desc = 600 000; # maximum number of descendants handled # + INT max ancestors = 10; # maximum number of ancestors handled # + + []BOOL prime = PRIMESIEVE max number; # sieve the primes to max number # + + MODE INTEGER = LONG INT; # needs to be big enough to hold # + # descendants and ancestors # + # table of ancestors - a count[ n ] holds the number of ancestors of n # + [ 1 : max number, 1 : max ancestors ]INTEGER ancestors; + [ 1 : max number ]INT a count; + FOR n FROM 1 LWB ancestors TO 1 UPB ancestors DO + a count[ n ] := 0; + FOR a FROM 2 LWB ancestors TO 2 UPB ancestors DO + ancestors[ n, a ] := 0 + OD + OD; + + # table of descentdants, d first[ n ] holds the index of the latest # + # descendant of n, prev descendant[ x ] holds the index of the previous # + # descendant ( 0 indicates no previous descendant ) # + [ 1 : max desc ]INTEGER descendant, sorted descendants; + [ 1 : max desc ]INT prev descendant; + [ 1 : max number ]INT d first; + FOR n FROM LWB d first TO UPB d first DO d first[ n ] := 0 OD; + FOR n FROM LWB descendant TO UPB descendant DO + descendant[ n ] := sorted descendants[ n ] := prev descendant[ n ] := 0 + OD; + INT next d := 1; # next free element in descendant, prev descendant # + + # adds a as an ancestor for d # + PROC add ancestor = ( INT d, INTEGER a )VOID: + ancestors[ d, a count[ d ] +:= 1 ] := a; + + # adds d to the descendants of n # + PROC add descendant = ( INT n, INTEGER d )VOID: + BEGIN + INT n prev := d first[ n ]; + descendant[ d first[ n ] := next d ] := d; + prev descendant[ next d ] := n prev; + next d +:= 1 + END # add descendant # ; + + # find the descendants # + FOR p FROM LWB prime TO UPB prime DO + IF prime[ p ] THEN + add descendant( p, p ); + FOR s FROM LWB d first TO UPB d first - p DO + INT s pos := d first[ s ]; + WHILE s pos > 0 DO + INTEGER ps = descendant[ s pos ]; + add descendant( s + p, p * ps ); + s pos := prev descendant[ s pos ] + OD + OD + FI + OD; + + # find the ancestors and show some descendants and ancestors # + INT next to show := 10; + INT total := 0; + FOR s FROM LWB d first TO UPB d first DO + # get a sorted list of the descendants of s, exclude s if present # + INT s pos := 0; + INT d pos := d first[ s ]; + WHILE d pos /= 0 DO + IF descendant[ d pos ] /= s THEN + sorted descendants[ s pos +:= 1 ] := descendant[ d pos ] + FI; + d pos := prev descendant[ d pos ] + OD; + sorted descendants QUICKSORT ELEMENTS( 1, s pos ); + total +:= s pos; + FOR d TO s pos DO + IF sorted descendants[ d ] <= max number THEN + FOR p TO a count[ s ] DO + add ancestor( SHORTEN sorted descendants[ d ] + , ancestors[ s, p ] + ) + OD; + add ancestor( SHORTEN sorted descendants[ d ], s ) + FI + OD; + IF s = next to show THEN + print( ( "-- ", whole( s, 0 ), " --", newline ) ); + print( ( whole( acount[ s ], -6 ), " Ancestors : [" ) ); + SHOW ancestors[ s, 1 : acount[ s ] ]; + print( ( " ]", newline, whole( s pos, -6 ), " Descendants: [" ) ); + IF s pos < 10 THEN + SHOW sorted descendants[ 1 : s pos ] + ELSE + print( ( " ", whole( sorted descendants[ 1 ], 0 ) ) ); + print( ( " ", whole( sorted descendants[ 2 ], 0 ) ) ); + print( ( " ... ", whole( sorted descendants[ s pos ], 0 ) ) ) + FI; + print( ( " ]", newline, newline ) ); + next to show := IF next to show = 10 THEN 46 ELSE max number FI + FI + OD; + print( ( whole( total, 0 ), " total descendants", newline ) ) +END diff --git a/Task/Primes---allocate-descendants-to-their-ancestors/EasyLang/primes---allocate-descendants-to-their-ancestors.easy b/Task/Primes---allocate-descendants-to-their-ancestors/EasyLang/primes---allocate-descendants-to-their-ancestors.easy new file mode 100644 index 0000000000..ae1d4551d0 --- /dev/null +++ b/Task/Primes---allocate-descendants-to-their-ancestors/EasyLang/primes---allocate-descendants-to-their-ancestors.easy @@ -0,0 +1,67 @@ +fastfunc isprim num . + i = 2 + while i <= sqrt num + if num mod i = 0 : return 0 + i += 1 + . + return 1 +. +proc qsort left right &d[] . + if left < right + piv = d[left] + mid = left + for i = left + 1 to right : if d[i] < piv + mid += 1 + swap d[i] d[mid] + . + swap d[left] d[mid] + qsort left mid - 1 d[] + qsort mid + 1 right d[] + . +. +proc sort &d[] . + qsort 1 len d[] d[] +. +maxsum = 99 +len desc[][] maxsum +len ances[][] maxsum +# +prim99[] = [ 2 ] +for i = 3 step 2 to maxsum + if isprim i = 1 : prim99[] &= i +. +for p in prim99[] + desc[p][] &= p + for s = 1 to len desc[][] - p + for ps in desc[s][] + desc[s + p][] &= p * ps + . + . +. +for p in prim99[] : len desc[p][] -1 +len desc[4][] -1 +# +for s = 1 to maxsum + sort desc[s][] + total += len desc[s][] + for d = 1 to len desc[s][] + if desc[s][d] <= maxsum + for p = 1 to len ances[s][] + ances[desc[s][d]][] &= ances[s][p] + . + ances[desc[s][d]][] &= s + . + . + if s = 10 or s = 46 or s = maxsum + print "-- " & s & " --" + print len ances[s][] & " Ancestors: " & ances[s][] + write len desc[s][] & " Descendants: " + if len desc[s][] < 10 + print desc[s][] + else + print "[ " & desc[s][1] & " " & desc[s][2] & " ... " & desc[s][len desc[s][]] & " ]" + . + print "" + . +. +print total & " total descendants" diff --git a/Task/Primes---allocate-descendants-to-their-ancestors/REXX/primes---allocate-descendants-to-their-ancestors.rexx b/Task/Primes---allocate-descendants-to-their-ancestors/REXX/primes---allocate-descendants-to-their-ancestors.rexx new file mode 100644 index 0000000000..3fd300be45 --- /dev/null +++ b/Task/Primes---allocate-descendants-to-their-ancestors/REXX/primes---allocate-descendants-to-their-ancestors.rexx @@ -0,0 +1,126 @@ +-- 25 Apr 2025 +include Settings +numeric digits 20 + +call Time('r') +say 'PRIMES - ALLOCATE DESCENDANTS TO THEIR ANCESTORS' +say version +say +call Primes 100 +call InitTotals +do n = 1 to 99 + call InitVarious + call Ancestors n + call Terms n,1,0,'' + call Descendants + call Sort 'desc.' + if n < 21 | Pos(n,46 62 74 94 99) > 0 then + call ShowResults n + call SumTotals +end +call ShowTotals +say Format(Time('e'),,3) 'seconds'; say +exit + +InitTotals: +procedure expose tota. +tota. = 0 +return + +InitVarious: +procedure expose ance. term. desc. +ance. = 0; term. = 0; desc. = 0 +return + +Ancestors: +procedure expose ance. +arg xx +if xx < 5 + then return +f = Factors(xx) +if f = 1 then + return +s = 0 +do i = 1 to fact.0 + s = s+fact.i +end +ance.0 = ance.0+1; a = ance.0; ance.a = s +call Ancestors s +return + +Terms: +procedure expose term. prim. +arg xx,ix,cs,cl +if xx < 5 then + return +if cs = xx then do + if Words(cl) > 1 then do + term.0 = term.0+1; i = term.0; term.i = cl + end + return +end +do i = ix to prim.0 + p = prim.i; a = cs+p + if a <= xx then + call Terms xx,i,a,cl p +end +return + +Descendants: +procedure expose desc. term. +do i = 1 to term.0 + a = term.i; p = 1 + do j = 1 to Words(a) + p = p*Word(a,j) + end + desc.0 = desc.0+1; i = desc.0; desc.i = p +end +return + +ShowResults: +procedure expose ance. desc. +arg xx +say '['xx']' +call Charout ,ance.0 'ancestors: ' +do i = ance.0 by -1 to 1 + call Charout ,ance.i' ' +end +say +call Charout ,desc.0 'descendants: ' +if desc.0 < 7 then do + do i = 1 to desc.0 + call Charout ,desc.i' ' + end +end +else do + do i = 1 to 3 + call Charout ,desc.i' ' + end + call Charout, '... ' + do i = desc.0-2 to desc.0 + call Charout ,desc.i' ' + end +end +say; say +return + +SumTotals: +procedure expose ance. desc. tota. +tota.ance = tota.ance+ance.0 +tota.desc = tota.desc+desc.0 +return + +ShowTotals: +procedure expose tota. +say '[Totals]' +say tota.ance 'ancestors' +say tota.desc 'descendants' +say +return + +include Numbers +include Sequences +include Constants +include Functions +include Helper +include Abend diff --git a/Task/Primorial-numbers/REXX/primorial-numbers.rexx b/Task/Primorial-numbers/REXX/primorial-numbers.rexx index 9d9a7fbf57..a3ff709147 100644 --- a/Task/Primorial-numbers/REXX/primorial-numbers.rexx +++ b/Task/Primorial-numbers/REXX/primorial-numbers.rexx @@ -1,12 +1,13 @@ +-- 8 May 2025 include Settings -say 'Primorial numbers' -parse version version; say version; say +say 'PRIMORIAL NUMBERS' +say version +say call GetPrimes -9 call ShowFirst10 call GetPrimes -1e6 call UseFloat 1e6 -call UseLog 1e6 call UseInt 1e4 exit @@ -27,7 +28,7 @@ numeric digits 10 say 'Primorial(0) = 1' a = 1 do i = 1 to 9 - a = a*prim.prime.i + a = a*prim.i say 'Primorial('i') =' a end say Format(Time('e'),,3) 'seconds'; say @@ -40,7 +41,7 @@ say 'Number of digits by real arithmetic and taking exponent:' numeric digits 10 a = 1; e = 0 do i = 1 to x - a = a*prim.prime.i + a = a*prim.i f = Xpon(i) if f <> e then do say 'Primorial(10^'f') has' Xpon(a)+1 'digits' @@ -50,23 +51,6 @@ end say Format(Time('e'),,3) 'seconds'; say return -UseLog: -arg x -call Time('r') -say 'Number of digits by summing log10:' -numeric digits 10 -a = 0; e = 0 -do i = 1 to x - a = a+Log10(prim.prime.i) - f = Xpon(i) - if f <> e then do - say 'Primorial(10^'f') has' Trunc(a)+1 'digits' - e = f - end -end -say Format(Time('e'),,3) 'seconds'; say -return - UseInt: arg x call Time('r') @@ -87,7 +71,7 @@ select end a = 1; e = 0 do i = 1 to x - a = a*prim.prime.i + a = a*prim.i f = Xpon(i) if f <> e then do say 'Primorial(10^'f') has' Length(a) 'digits' @@ -99,6 +83,7 @@ return include Numbers include Functions +include Special include Sequences include Constants include Abend diff --git a/Task/Probabilistic-choice/EasyLang/probabilistic-choice.easy b/Task/Probabilistic-choice/EasyLang/probabilistic-choice.easy index cae44439f9..9c94d0b74e 100644 --- a/Task/Probabilistic-choice/EasyLang/probabilistic-choice.easy +++ b/Task/Probabilistic-choice/EasyLang/probabilistic-choice.easy @@ -18,7 +18,7 @@ for i to n . print "Name Ratio Expected" print "---------------------" -numfmt 4 6 +numfmt 6 4 for i to 8 print name$[i] & " " & act[i] / n & " " & probs[i] . diff --git a/Task/Problem-of-Apollonius/EasyLang/problem-of-apollonius.easy b/Task/Problem-of-Apollonius/EasyLang/problem-of-apollonius.easy index 72b2614f28..de27f6f500 100644 --- a/Task/Problem-of-Apollonius/EasyLang/problem-of-apollonius.easy +++ b/Task/Problem-of-Apollonius/EasyLang/problem-of-apollonius.easy @@ -1,4 +1,4 @@ -proc solve c1[] c2[] c3[] s1 s2 s3 . r[] . +proc solve c1[] c2[] c3[] s1 s2 s3 &r[] . len r[] 3 x1 = c1[1] ; y1 = c1[2] ; r1 = c1[3] x2 = c2[1] ; y2 = c2[2] ; r2 = c2[3] @@ -40,25 +40,26 @@ print r1[] solve c1[] c2[] c3[] -1 -1 -1 r2[] print r2[] # -proc circ x y r . . - text "" +proc circ x0 y0 r . for a = 0 to 360 - line x + sin a * r y + cos a * r + xp = x + yp = y + x = x0 + sin a * r + y = y0 + cos a * r + if a > 0 : gline xp yp x y . . -proc draw col c[] . . - color col +proc draw col c[] . + gcolor col circ c[1] * 10 + 30 c[2] * 10 + 30 c[3] * 10 . -background 888 -clear -linewidth 0.5 -color 000 +gbackground 888 +gclear +glinewidth 0.5 +gcolor 000 drawgrid -move 30 0 -line 30 100 -move 0 30 -line 100 30 +gline 30 0 30 100 +gline 0 30 100 30 draw 000 c1[] draw 000 c2[] draw 000 c3[] diff --git a/Task/Program-name/Zig/program-name.zig b/Task/Program-name/Zig/program-name.zig index 1edf04a3af..3e3ed90f3d 100644 --- a/Task/Program-name/Zig/program-name.zig +++ b/Task/Program-name/Zig/program-name.zig @@ -1,14 +1,9 @@ const std = @import("std"); -const debug = std.debug; -const heap = std.heap; -const process = std.process; +pub fn main() void { + var args = std.process.args(); -pub fn main() !void { - var args = process.args(); + const program_name = args.next().?; - const program_name = try args.next(heap.page_allocator) orelse unreachable; - defer heap.page_allocator.free(program_name); - - debug.warn("{}\n", .{program_name}); + std.debug.print("{s}\n", .{program_name}); } diff --git a/Task/Program-termination/OPL/program-termination.opl b/Task/Program-termination/OPL/program-termination.opl new file mode 100644 index 0000000000..68227587ea --- /dev/null +++ b/Task/Program-termination/OPL/program-termination.opl @@ -0,0 +1,3 @@ +PROC main: + IF 1 :STOP :ENDIF +ENDP diff --git a/Task/Proper-divisors/ALGOL-60/proper-divisors.alg b/Task/Proper-divisors/ALGOL-60/proper-divisors.alg new file mode 100644 index 0000000000..86600b0d28 --- /dev/null +++ b/Task/Proper-divisors/ALGOL-60/proper-divisors.alg @@ -0,0 +1,77 @@ +begin + +comment - return n mod m; +integer procedure mod(n, m); + value n, m; integer n, m; +begin + mod := n - entier(n / m) * m; +end; + +comment - count, and optionally display, proper divisors of n; +integer procedure pdc(n, display); + value n; integer n; boolean display; +begin + integer i, limit, count; + count := 1; + i := 2; + limit := n / 2; + if display then + begin + outinteger(1,n); outstring(1,": "); outinteger(1,1); + end; + for i := i while i <= limit do + begin + if mod(n, i) = 0 then + begin + if display then outinteger(1,i); + count := count + 1; + end; + i := i + 1; + if count = 1 then limit := n / i; + end; + if display then outstring(1,"\n"); + pdc := count; +end; + +integer i, junk, limit; +comment - first part of task; +outstring(1,"Proper divisors of first ten numbers\n"); +for i := 1 step 1 until 10 do + junk := pdc(i, true); comment - we don't need the return value; +outstring(1,"\n"); + +comment + Calling pdc() 20000 times to find the highest number of proper + divisors turns out to be hugely inefficient, so we take a + different approach for the second part of the task; +limit := 20000; +outstring(1,"Searching to"); outinteger(1,limit); +outstring(1,"for number with most proper divisors:\n"); + begin + integer i, j, ndiv, highdiv, highnum; + integer array divcnt[1:limit]; + comment + Create a table of divisor counts for n = 1 to limit. + This will include n itself, so for any n, the number + of proper divisors will be one less; + for i := 1 step 1 until limit do + divcnt[i] := 0; + for i := 1 step 1 until limit do + for j := i step i until limit do + divcnt[j] := divcnt[j] + 1; + comment - search the table for the highest count; + highdiv := 1; + highnum := 1; + for i := 2 step 1 until 20000 do + begin + ndiv := divcnt[i] - 1; + if ndiv > highdiv then + begin + highdiv := ndiv; + highnum := i; + end; + end; + outstring(1,"The number is"); outinteger(1,highnum); + outstring(1,"with"); outinteger(1,highdiv); + outstring(1,"divisors"); + end; diff --git a/Task/Proper-divisors/REXX/proper-divisors-2.rexx b/Task/Proper-divisors/REXX/proper-divisors-2.rexx index c65788c22e..63dadc2b7d 100644 --- a/Task/Proper-divisors/REXX/proper-divisors-2.rexx +++ b/Task/Proper-divisors/REXX/proper-divisors-2.rexx @@ -1,42 +1,62 @@ -/*REXX program finds proper divisors (and count) of integer ranges; finds the max count.*/ -parse arg bot top inc range xtra /*obtain optional arguments from the CL*/ -if bot=='' | bot=="," then bot= 1 /*Not specified? Then use the default.*/ -if top=='' | top=="," then top= 10 /* " " " " " " */ -if inc=='' | inc=="," then inc= 1 /* " " " " " " */ -if range=='' | range=="," then range= 20000 /* " " " " " " */ -w= max( length(top), length(bot), length(range)) /*determine the biggest number of these*/ -numeric digits max(9, w + 1) /*have enough digits for // operator.*/ -@.= 'and' /*a literal used to separate #s in list*/ - do n=bot to top by inc /*process the first range specified. */ - q= Pdivs(n); #= words(q) /*get proper divs; get number of Pdivs.*/ - if q=='∞' then #= q /*adjust number of Pdivisors for zero. */ - say right(n, max(20, w) ) 'has' center(#, 4) "proper divisors: " q - end /*n*/ -m= 0 /*M ≡ maximum number of Pdivs (so far).*/ - do r=1 for range; q= Pdivs(r) /*process the second range specified. */ - #= words(q); if # m then do + m = n; j = i + end +end +n = Divisors(j)-1 +say j 'has' n 'proper divisors' +say +return + +Task4: +procedure expose divi. +arg xx +say 'Some numbers with a lot of proper divisors...' +a = '1441440 21621600 6983776800 321253732800 65214507758400 6064949221531200 224403121196654400' +do w = 1 to Words(a) + n = Word(a,w) + say n 'has' Divisor(n)-1 'proper divisors' +end +say +return + +include Sequences +include Functions +include Special +include Abend diff --git a/Task/Proper-divisors/REXX/proper-divisors-3.rexx b/Task/Proper-divisors/REXX/proper-divisors-3.rexx deleted file mode 100644 index f3c25561cb..0000000000 --- a/Task/Proper-divisors/REXX/proper-divisors-3.rexx +++ /dev/null @@ -1,46 +0,0 @@ -/*REXX program finds proper divisors (and count) of integer ranges; finds the max count.*/ -parse arg bot top inc range xtra /*obtain optional arguments from the CL*/ -if bot=='' | bot=="," then bot= 1 /*Not specified? Then use the default.*/ -if top=='' | top=="," then top= 10 /* " " " " " " */ -if inc=='' | inc=="," then inc= 1 /* " " " " " " */ -if range=='' | range=="," then range= 20000 /* " " " " " " */ -w= max( length(top), length(bot), length(range)) /*determine the biggest number of these*/ -numeric digits max(9, w + 1) /*have enough digits for // operator.*/ -@.= 'and' /*a literal used to separate #s in list*/ - do n=bot to top by inc /*process the first range specified. */ - q= Pdivs(n); #= words(q) /*get proper divs; get number of Pdivs.*/ - if q=='∞' then #= q /*adjust number of Pdivisors for zero. */ - say right(n, max(20, w) ) 'has' center(#, 4) "proper divisors: " q - end /*n*/ -m= 0 /*M ≡ maximum number of Pdivs (so far).*/ - do r=1 for range; q= Pdivs(r) /*process the second range specified. */ - #= words(q); if #1; q=q%4; _= z-r-q; r=r%2; if _>=0 then do; z=_; r=r+q; end - end /*while q>1*/ /* [↑] compute the integer sqrt of X.*/ - a=1 /* [↓] use all, or only odd #s. ___ */ - do j=2 +odd by 1 +odd to r -(r*r==x) /*divide by some integers up to √ X */ - if x//j==0 then do; a=a j; b=x%j b /*if ÷, add both divisors to α & ß. */ - end - end /*j*/ /* [↑] % is the REXX integer division*/ - /* [↓] adjust for a square. ___*/ - if j*j==x then return a j b /*Was X a square? If so, add √ X */ - return a b /*return the divisors (both lists). */ diff --git a/Task/Proper-divisors/REXX/proper-divisors-4.rexx b/Task/Proper-divisors/REXX/proper-divisors-4.rexx deleted file mode 100644 index 7cab6f6b79..0000000000 --- a/Task/Proper-divisors/REXX/proper-divisors-4.rexx +++ /dev/null @@ -1,53 +0,0 @@ -/*REXX program finds proper divisors (and count) of integer ranges; finds the max count.*/ -parse arg bot top inc range xtra /*obtain optional arguments from the CL*/ -if bot=='' | bot=="," then bot= 1 /*Not specified? Then use the default.*/ -if top=='' | top=="," then top= 10 /* " " " " " " */ -if inc=='' | inc=="," then inc= 1 /* " " " " " " */ -if range=='' | range=="," then range= 20000 /* " " " " " " */ -w= max( length(top), length(bot), length(range)) /*determine the biggest number of these*/ -numeric digits max(9, w + 1) /*have enough digits for // operator.*/ -@.= 'and' /*a literal used to separate #s in list*/ - do n=bot to top by inc /*process the first range specified. */ - q= Pdivs(n); #= words(q) /*get proper divs; get number of Pdivs.*/ - if q=='∞' then #= q /*adjust number of Pdivisors for zero. */ - say right(n, max(20, w) ) 'has' center(#, 4) "proper divisors: " q - end /*n*/ -m= 0 /*M ≡ maximum number of Pdivs (so far).*/ - do r=1 for range; q= Pdivs(r) /*process the second range specified. */ - #= words(q); if #1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end - return r -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Pdivs: procedure; parse arg x,b; x= abs(x) - if x==1 then return '' /*null set.*/ - if x==0 then return '∞' /*infinity.*/ - odd= x // 2 /*oddness of X. ___ */ - r= iSqrt(x) /* obtain the integer √ X */ - a= 1 /* [↓] use all, or only odd numbers. */ - /* ___*/ - if odd then do j=3 by 2 for r%2-(r*r==x) /*divide by some integers up to √ X */ - if x//j==0 then do; a=a j; b=x%j b /*÷? Add both divisors to A & B*/ - end - end /*j*/ /* ___*/ - else do j=2 for r-1-(r*r==x) /*divide by some integers up to √ X */ - if x//j==0 then do; a=a j; b=x%j b /*÷? Add both divisors to A & B*/ - end - end /*j*/ - if r*r==x then return a j b /*Was X a square? If so, add √ X */ - return a b /*return proper divisors (both lists).*/ diff --git a/Task/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a/Rust/pseudo-random-numbers-combined-recursive-generator-mrg32k3a.rs b/Task/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a/Rust/pseudo-random-numbers-combined-recursive-generator-mrg32k3a.rs new file mode 100644 index 0000000000..215239b2cb --- /dev/null +++ b/Task/Pseudo-random-numbers-Combined-recursive-generator-MRG32k3a/Rust/pseudo-random-numbers-combined-recursive-generator-mrg32k3a.rs @@ -0,0 +1,89 @@ +fn mod_fn(x: i64, y: i64) -> i64 { + let m = x % y; + if m < 0 { + if y < 0 { + return m - y; + } else { + return m + y; + } + } + m +} + +struct RNG { + // First generator + a1: [i64; 3], + m1: i64, + x1: [i64; 3], + // Second generator + a2: [i64; 3], + m2: i64, + x2: [i64; 3], + // other + d: i64, +} + +impl RNG { + fn new() -> RNG { + RNG { + a1: [0, 1403580, -810728], + m1: (1i64 << 32) - 209, + x1: [0, 0, 0], + a2: [527612, 0, -1370589], + m2: (1i64 << 32) - 22853, + x2: [0, 0, 0], + d: (1i64 << 32) - 209 + 1, + } + } + + fn seed(&mut self, state: i64) { + self.x1 = [state, 0, 0]; + self.x2 = [state, 0, 0]; + } + + fn next_int(&mut self) -> i64 { + let x1i = mod_fn( + self.a1[0] * self.x1[0] + self.a1[1] * self.x1[1] + self.a1[2] * self.x1[2], + self.m1, + ); + let x2i = mod_fn( + self.a2[0] * self.x2[0] + self.a2[1] * self.x2[1] + self.a2[2] * self.x2[2], + self.m2, + ); + let z = mod_fn(x1i - x2i, self.m1); + + // keep last three values of the first generator + self.x1 = [x1i, self.x1[0], self.x1[1]]; + // keep last three values of the second generator + self.x2 = [x2i, self.x2[0], self.x2[1]]; + + z + 1 + } + + fn next_float(&mut self) -> f64 { + self.next_int() as f64 / self.d as f64 + } +} + +fn main() { + let mut rng = RNG::new(); + + rng.seed(1234567); + println!("{}", rng.next_int()); + println!("{}", rng.next_int()); + println!("{}", rng.next_int()); + println!("{}", rng.next_int()); + println!("{}", rng.next_int()); + println!(); + + let mut counts: [i32; 5] = [0, 0, 0, 0, 0]; + rng.seed(987654321); + for _i in 0..100000 { + let value = (rng.next_float() * 5.0).floor() as usize; + counts[value] += 1; + } + + for i in 0..counts.len() { + println!("{}: {}", i, counts[i]); + } +} diff --git a/Task/Pseudo-random-numbers-Middle-square-method/Rust/pseudo-random-numbers-middle-square-method.rs b/Task/Pseudo-random-numbers-Middle-square-method/Rust/pseudo-random-numbers-middle-square-method.rs new file mode 100644 index 0000000000..49bf646e49 --- /dev/null +++ b/Task/Pseudo-random-numbers-Middle-square-method/Rust/pseudo-random-numbers-middle-square-method.rs @@ -0,0 +1,54 @@ +use std::fmt; + +#[derive(Debug)] +struct MiddleSquare { + state: u64, + div: u64, + modulo: u64, +} + +impl MiddleSquare { + fn new(start: u64, length: u64) -> Result { + if length % 2 != 0 { + return Err("length must be even"); + } + + let mut div = 1; + let mut modulo = 1; + + for _ in 0..(length / 2) { + div *= 10; + } + + for _ in 0..length { + modulo *= 10; + } + + Ok(MiddleSquare { + state: start % modulo, + div, + modulo, + }) + } + + fn next(&mut self) -> u64 { + self.state = (self.state * self.state / self.div) % self.modulo; + self.state + } +} + +impl fmt::Display for MiddleSquare { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "MiddleSquare {{ state: {}, div: {}, modulo: {} }}", self.state, self.div, self.modulo) + } +} + +fn main() -> Result<(), &'static str> { + let mut msq = MiddleSquare::new(675248, 6)?; + + for _ in 0..5 { + println!("{}", msq.next()); + } + + Ok(()) +} diff --git a/Task/Pseudo-random-numbers-Splitmix64/Rust/pseudo-random-numbers-splitmix64.rs b/Task/Pseudo-random-numbers-Splitmix64/Rust/pseudo-random-numbers-splitmix64.rs new file mode 100644 index 0000000000..0e9a34b514 --- /dev/null +++ b/Task/Pseudo-random-numbers-Splitmix64/Rust/pseudo-random-numbers-splitmix64.rs @@ -0,0 +1,57 @@ +struct Splitmix64 { + state: u64, + two_power_64: f64, +} + +impl Splitmix64 { + fn new() -> Self { + Splitmix64 { + state: 0, + two_power_64: (2.0_f64).powi(64), + } + } + + fn with_seed(seed: u64) -> Self { + Splitmix64 { + state: seed, + two_power_64: (2.0_f64).powi(64), + } + } + + fn seed(&mut self, seed: u64) { + self.state = seed; + } + + fn next_int(&mut self) -> u64 { + let mut z = self.state.wrapping_add(0x9e3779b97f4a7c15); + self.state = z; + z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9); + z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb); + z ^ (z >> 31) + } + + fn next_float(&mut self) -> f64 { + self.next_int() as f64 / self.two_power_64 + } +} + +fn main() { + let mut random = Splitmix64::new(); + random.seed(1234567); + for _i in 0..5 { + println!("{}", random.next_int()); + } + println!(); + + let mut rand = Splitmix64::with_seed(987654321); + let mut counts = vec![0_u32; 5]; + for _i in 0..100_000 { + let value = (rand.next_float() * 5.0).floor() as u32; + counts[value as usize] += 1; + } + + for i in 0..5 { + print!("{}: {} ", i, counts[i as usize]); + } + println!(); +} diff --git a/Task/Pythagoras-tree/ALGOL-68/pythagoras-tree.alg b/Task/Pythagoras-tree/ALGOL-68/pythagoras-tree.alg new file mode 100644 index 0000000000..24cb697aa9 --- /dev/null +++ b/Task/Pythagoras-tree/ALGOL-68/pythagoras-tree.alg @@ -0,0 +1,95 @@ +BEGIN # draw a pythagoras tree, using SVG # + + MODE POS = REAL; # MODE holding a coordinate # + + # operators for formatting # + OP BYTETOHEX = ( INT v )CHAR: + REPR IF v < 10 THEN ABS "0" + v ELSE ABS "A" + ( v - 10 ) FI; + OP TOHEX = ( INT v in )STRING: + IF v in = 0 + THEN "0" + ELSE INT v := vin; + STRING result := ""; + WHILE v > 0 DO + BYTETOHEX ( v MOD 16 ) +=: result; + v OVERAB 16 + OD; + result + FI # TOHEX # ; + OP FMT = ( INT v )STRING: whole( v, 0 ); + PRIO FMT = 9; + OP FMT = ( REAL v, INT dp )STRING: + IF v = ENTIER v OR dp = 0 + THEN whole( v, 0 ) + ELSE STRING result = fixed( v, - dp * 16, ABS dp ); + INT v pos := LWB result; + WHILE result[ v pos ] = " " DO v pos +:= 1 OD; + result[ v pos : ] + FI # FMT # ; + + # draws a polygon, points must have an even number of elements # + PROC polygon = ( []POS points, INT fill, stroke, REAL line width )VOID: + BEGIN + print( ( " ", newline ) ) + END # polygon # ; + PROC square = ( POS x1, y1, x2, y2, x3, y3, x4, y4 + , INT fill, stroke + , REAL line width + ) VOID: polygon( ( x1, y1, x2, y2, x3, y3, x4, y4 ), fill, stroke, line width ); + PROC triangle = ( POS x1, y1, x2, y2, x3, y3 + , INT fill, stroke + , REAL line width + ) VOID: polygon( ( x1, y1, x2, y2, x3, y3 ), fill, stroke, line width ); + + PROC draw pythagoras tree = ( INT height + , POS x1, y1, x2, y2 + , INT depth, max depth + , REAL line width + ) VOID: + IF depth < max depth THEN + POS dx = x2 - x1; + POS dy = y1 - y2; + POS x3 = x2 + dy; + POS y3 = y2 + dx; + POS x4 = x1 + dy; + POS y4 = y1 + dx; + POS x5 = x4 + 0.5 * ( dx + dy ); + POS y5 = y4 + 0.5 * ( dx - dy ); + INT r = 255 - ROUND ( 255 * ( 0.01 + ( depth / 10 ) ) ); + INT g = 255 - ROUND ( 255 * ( 0.01 + ( depth / 20 ) ) ); + INT b = g OVER 3; + INT fill = ( ( ( r * 256 ) + g ) * 256 ) + b; + INT stroke = ABS 16r 444444; + # inveret the y-axis, so y=0 is at the bottom # + POS i1 = height - y1, i2 = height - y2, i3 = height - y3; + POS i4 = height - y4, i5 = height - y5; + square( x1, i1, x2, i2, x3, i3, x4, i4, fill, stroke, line width ); + triangle( x3, i3, x4, i4, x5, i5, fill, stroke, line width ); + draw pythagoras tree( height, x4, y4, x5, y5, depth + 1, max depth, line width ); + draw pythagoras tree( height, x5, y5, x3, y3, depth + 1, max depth, line width ) + FI # draw pythagoras tree # ; + + PROC pythagoras tree = ( INT width, height + , POS x1, y1, x2, y2 + , INT max depth + , REAL line width + ) VOID: + BEGIN + print( ( "", newline ) ); + draw pythagoras tree( height, x1, y1, x2, y2, 0, max depth, line width ); + print( ( "", newline ) ) + END # pythagoras tree #; + + pythagoras tree( 120, 90, 51, 10, 69, 10, 10, 0.03 ) + +END diff --git a/Task/Pythagoras-tree/EasyLang/pythagoras-tree.easy b/Task/Pythagoras-tree/EasyLang/pythagoras-tree.easy index bcba9c01e1..17eec9353f 100644 --- a/Task/Pythagoras-tree/EasyLang/pythagoras-tree.easy +++ b/Task/Pythagoras-tree/EasyLang/pythagoras-tree.easy @@ -1,4 +1,4 @@ -proc tree x1 y1 x2 y2 depth . . +proc tree x1 y1 x2 y2 depth . if depth < 8 dx = x2 - x1 dy = y1 - y2 @@ -8,9 +8,9 @@ proc tree x1 y1 x2 y2 depth . . y4 = y1 + dx x5 = x4 + 0.5 * (dx + dy) y5 = y4 + 0.5 * (dx - dy) - color3 0.3 0.2 + depth / 18 0.1 - polygon [ x1 y1 x2 y2 x3 y3 x4 y4 ] - polygon [ x3 y3 x4 y4 x5 y5 ] + gcolor3 0.3 0.2 + depth / 18 0.1 + gpolygon [ x1 y1 x2 y2 x3 y3 x4 y4 ] + gpolygon [ x3 y3 x4 y4 x5 y5 ] tree x4 y4 x5 y5 depth + 1 tree x5 y5 x3 y3 depth + 1 . diff --git a/Task/Pythagoras-tree/Maple/pythagoras-tree.maple b/Task/Pythagoras-tree/Maple/pythagoras-tree.maple new file mode 100644 index 0000000000..12c71e74bc --- /dev/null +++ b/Task/Pythagoras-tree/Maple/pythagoras-tree.maple @@ -0,0 +1,23 @@ +pythtree := proc(ax, ay, bx, By, P, colors, depth) + local dx, dy, x3, y3, x4, y4, x5, y5; + if depth <= 0 then return; end if; + dx:=bx-ax; dy:=ay-By; + x3:=bx-dy; y3:=By-dx; + x4:=ax-dy; y4:=ay-dx; + x5:=x4+(dx-dy)/2; y5:=y4-(dx+dy)/2; + + P ,= plots:-polygonplot([ax,bx,x3,x4,ax],-[ay,By,y3,y4,ay],color=colors[depth]); + P ,= plots:-polygonplot([x4,x5,x3],-[y4,y5,y3],color=colors[depth]); + + pythtree(x4, y4, x5, y5, P, colors, depth - 1); + pythtree(x5, y5, x3, y3, P, colors, depth - 1); +end proc: + +pythagorastree := proc(x1, y1, x2, y2, size, maxdep) + local P := Array(1..0); + local colors := ColorTools:-Gradient("Green".."yellow",number=maxdep): + pythtree(x1, y1, x2, y2, P, colors, maxdep); + plots:-display(convert(P,list),axes=none); +end proc: + +pythagorastree(275.,500.,375.,500.,640., 9); diff --git a/Task/Pythagorean-triples/EasyLang/pythagorean-triples.easy b/Task/Pythagorean-triples/EasyLang/pythagorean-triples.easy index 1d8b36eaeb..4064a9bc74 100644 --- a/Task/Pythagorean-triples/EasyLang/pythagorean-triples.easy +++ b/Task/Pythagorean-triples/EasyLang/pythagorean-triples.easy @@ -1,5 +1,5 @@ global total prim maxperi . -proc newtri s0 s1 s2 . . +proc newtri s0 s1 s2 . p = s0 + s1 + s2 if p <= maxperi prim += 1 diff --git a/Task/QR-decomposition/Rust/qr-decomposition.rs b/Task/QR-decomposition/Rust/qr-decomposition.rs new file mode 100644 index 0000000000..eb906dbf14 --- /dev/null +++ b/Task/QR-decomposition/Rust/qr-decomposition.rs @@ -0,0 +1,591 @@ +use std::fmt; +use std::ops::{Add, Mul}; // Optional: for operator overloading later if desired + +// --- Error Type --- +#[derive(Debug, PartialEq)] +pub enum MatrixError { + IncompatibleDimensions(String), + InvalidOperation(String), + OutOfBounds(String), +} + +impl fmt::Display for MatrixError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MatrixError::IncompatibleDimensions(msg) => write!(f, "Incompatible matrix dimensions: {}", msg), + MatrixError::InvalidOperation(msg) => write!(f, "Invalid matrix operation: {}", msg), + MatrixError::OutOfBounds(msg) => write!(f, "Index out of bounds: {}", msg), + } + } +} + +// Define a Result type alias for convenience +type MatrixResult = Result; + +// --- Matrix Struct --- +#[derive(Debug, Clone)] // Added Debug and Clone +pub struct Matrix { + rows: usize, + cols: usize, + data: Vec>, +} + +impl Matrix { + // --- Constructors --- + + /// Creates a matrix from existing 2D vector data. + /// Validates that all inner vectors have the same length. + pub fn from_data(data: Vec>) -> MatrixResult { + if data.is_empty() { + // Handle empty case: 0x0 matrix + return Ok(Matrix { rows: 0, cols: 0, data }); + } + let rows = data.len(); + let cols = data[0].len(); + // Validate dimensions + if !data.iter().all(|row| row.len() == cols) { + return Err(MatrixError::IncompatibleDimensions( + "All rows must have the same number of columns".to_string(), + )); + } + Ok(Matrix { rows, cols, data }) + } + + /// Creates a new matrix with specified dimensions, initialized to zeros. + pub fn zeros(rows: usize, cols: usize) -> Self { + let data = vec![vec![0.0; cols]; rows]; + Matrix { rows, cols, data } + } + + // --- Accessors --- + + pub fn rows(&self) -> usize { + self.rows + } + + pub fn cols(&self) -> usize { + self.cols + } + + /// Gets the value at a specific row and column. Returns None if out of bounds. + pub fn get(&self, row: usize, col: usize) -> Option { + self.data.get(row)?.get(col).copied() + } + + /// Gets the value at a specific row and column. Returns Error if out of bounds. + pub fn get_entry(&self, row: usize, col: usize) -> MatrixResult { + self.data + .get(row) + .and_then(|r| r.get(col)) + .copied() + .ok_or_else(|| MatrixError::OutOfBounds(format!("Accessing ({}, {}) in {}x{} matrix", row, col, self.rows, self.cols))) + } + + + /// Sets the value at a specific row and column. Returns Error if out of bounds. + pub fn set_entry(&mut self, row: usize, col: usize, value: f64) -> MatrixResult<()> { + self.data + .get_mut(row) + .and_then(|r| r.get_mut(col)) + .map(|entry| *entry = value) + .ok_or_else(|| MatrixError::OutOfBounds(format!("Setting ({}, {}) in {}x{} matrix", row, col, self.rows, self.cols))) + } + + + // --- Basic Matrix Operations --- + + /// Adds another matrix to this matrix. + pub fn add(&self, other: &Matrix) -> MatrixResult { + if self.rows != other.rows || self.cols != other.cols { + return Err(MatrixError::IncompatibleDimensions(format!( + "Cannot add {}x{} matrix to {}x{} matrix", + self.rows, self.cols, other.rows, other.cols + ))); + } + + let mut result_data = self.data.clone(); // Start with a copy + for i in 0..self.rows { + for j in 0..self.cols { + result_data[i][j] += other.data[i][j]; + } + } + Ok(Matrix { + rows: self.rows, + cols: self.cols, + data: result_data, + }) + } + + /// Multiplies this matrix by another matrix. + pub fn multiply(&self, other: &Matrix) -> MatrixResult { + if self.cols != other.rows { + return Err(MatrixError::IncompatibleDimensions(format!( + "Cannot multiply {}x{} matrix by {}x{} matrix", + self.rows, self.cols, other.rows, other.cols + ))); + } + + let mut result = Matrix::zeros(self.rows, other.cols); + for i in 0..self.rows { + for j in 0..other.cols { + let mut sum = 0.0; + for k in 0..self.cols { // Note: loop limit is self.cols (or other.rows) + // Using direct access after checks for potentially better performance + // but relying on bounds being correct due to initial check. + // Safe access: sum += self.get_entry(i, k)? * other.get_entry(k, j)?; + sum += self.data[i][k] * other.data[k][j]; + } + result.data[i][j] = sum; + // Safe set: result.set_entry(i, j, sum)?; + } + } + Ok(result) + } + + /// Returns the transpose of this matrix. + pub fn transpose(&self) -> Matrix { + let mut result = Matrix::zeros(self.cols, self.rows); + for i in 0..self.rows { + for j in 0..self.cols { + // Direct access okay here as bounds are derived from self + result.data[j][i] = self.data[i][j]; + // Safe set: result.set_entry(j, i, self.get_entry(i, j).unwrap()).unwrap(); // unwrap safe + } + } + result + } + + // --- Specific Operations (used in Householder) --- + + /// Creates a matrix where elements below/right of `index` are copied, + /// and the top-left `index x index` part is an identity matrix. + /// Note: In Rust, indices start from 0. The C++ code seems to imply + /// copying starts *at* index `k`. Let's match that behavior. + pub fn minor(&self, index: usize) -> MatrixResult { + if index > self.rows || index > self.cols { + return Err(MatrixError::OutOfBounds(format!("Index {} out of bounds for minor operation on {}x{} matrix", index, self.rows, self.cols))); + } + + let mut result = Matrix::zeros(self.rows, self.cols); + // Set identity part + for i in 0..index { + result.set_entry(i, i, 1.0)?; + } + + // Copy the submatrix part + for i in index..self.rows { + for j in index..self.cols { + result.set_entry(i, j, self.get_entry(i, j)?)?; + } + } + Ok(result) + } + + /// Extracts a column as a new column vector (Nx1 matrix). + pub fn column(&self, index: usize) -> MatrixResult { + if index >= self.cols { + return Err(MatrixError::OutOfBounds(format!("Column index {} out of bounds for {}x{} matrix", index, self.rows, self.cols))); + } + let mut result = Matrix::zeros(self.rows, 1); + for i in 0..self.rows { + result.set_entry(i, 0, self.get_entry(i, index)?)?; + } + Ok(result) + } + + /// Multiplies a *column vector* matrix by a scalar. + pub fn scalar_multiply(&self, value: f64) -> MatrixResult { + if self.cols != 1 { + return Err(MatrixError::InvalidOperation(format!( + "Scalar multiply requires a column vector (Nx1), but matrix is {}x{}", + self.rows, self.cols + ))); + } + let mut result = Matrix::zeros(self.rows, 1); + for i in 0..self.rows { + result.data[i][0] = self.data[i][0] * value; + // Safe: result.set_entry(i, 0, self.get_entry(i, 0)? * value)?; + } + Ok(result) + } + + /// Normalizes a *column vector* matrix to produce a unit vector. + pub fn unit(&self) -> MatrixResult { + if self.cols != 1 { + return Err(MatrixError::InvalidOperation(format!( + "Unit vector requires a column vector (Nx1), but matrix is {}x{}", + self.rows, self.cols + ))); + } + let mag = self.magnitude()?; + if mag == 0.0 { + // Avoid division by zero, return zero vector or error? + // C++ code didn't check this, would result in NaN/Inf. Let's return error. + return Err(MatrixError::InvalidOperation("Cannot normalize a zero vector".to_string())); + } + + let mut result = Matrix::zeros(self.rows, 1); + for i in 0..self.rows { + result.data[i][0] = self.data[i][0] / mag; + // Safe: result.set_entry(i, 0, self.get_entry(i, 0)? / mag)?; + } + Ok(result) + } + + /// Calculates the L2 norm (magnitude) of a *column vector* matrix. + pub fn magnitude(&self) -> MatrixResult { + if self.cols != 1 { + return Err(MatrixError::InvalidOperation(format!( + "Magnitude requires a column vector (Nx1), but matrix is {}x{}", + self.rows, self.cols + ))); + } + let mut norm_sq = 0.0; + for i in 0..self.rows { + let val = self.data[i][0]; // Direct access okay after check + // Safe: let val = self.get_entry(i, 0)?; + norm_sq += val * val; + } + Ok(norm_sq.sqrt()) + } + + /// Returns the number of rows for a *column vector* matrix. (Equivalent to `rows()`). + /// Kept for closer C++ API parity, but `rows()` is more general. + pub fn size(&self) -> MatrixResult { + if self.cols != 1 { + return Err(MatrixError::InvalidOperation(format!( + "Size operation requires a column vector (Nx1), but matrix is {}x{}", + self.rows, self.cols + ))); + } + Ok(self.rows) + } + + // --- Display --- + // Implemented via `fmt::Display` trait below +} + +// --- Display Trait Implementation --- +impl fmt::Display for Matrix { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for i in 0..self.rows { + for j in 0..self.cols { + // Format similar to C++ setw(9), fixed, setprecision(4) + write!(f, "{:>9.4}", self.data[i][j])?; + } + writeln!(f)?; // Newline after each row + } + Ok(()) // No extra newline like C++ display function + } +} + +// --- Helper Functions (translated from C++) --- + +type MatrixPair = (Matrix, Matrix); // R, Q + +/// Creates a Householder reflection matrix H = I - 2*v*v^T +/// Expects `vector` to be a column vector (Nx1). +/// Note: The C++ code assumes `vector` is already a unit vector based on usage in `householder`. +fn householder_factor(vector: &Matrix) -> MatrixResult { + if vector.cols() != 1 { + return Err(MatrixError::InvalidOperation( + "householder_factor requires a column vector".to_string() + )); + } + let size = vector.rows(); + let mut result = Matrix::zeros(size, size); + + // Calculate -2 * v * v^T + for i in 0..size { + for j in 0..size { + // Using get_entry for safety, though direct access might work if performance critical + let vi = vector.get_entry(i, 0)?; + let vj = vector.get_entry(j, 0)?; + result.set_entry(i, j, -2.0 * vi * vj)?; + } + } + + // Add identity matrix part (I - 2*v*v^T) + for i in 0..size { + let current_diag = result.get_entry(i, i)?; + result.set_entry(i, i, current_diag + 1.0)?; + } + + Ok(result) +} + +/// Performs QR decomposition using Householder reflections. +/// Returns (R, Q) where A = Q*R. +fn householder(matrix: &Matrix) -> MatrixResult { + let rows = matrix.rows(); + let cols = matrix.cols(); + let mut versions_of_q: Vec = Vec::new(); + let mut z = matrix.clone(); // Start with a copy of the original matrix + + let limit = std::cmp::min(cols, rows.saturating_sub(1)); // k < cols && k < rows - 1 + + for k in 0..limit { + // The C++ minor(k) creates a matrix with identity in top-left kxk + // and the rest copied from z. + let z1 = z.minor(k)?; // This seems intended to operate on submatrices implicitly + + // Extract the k-th column from the 'minor' matrix starting from row k + // In C++, minor(k) zeros upper part, so column(k) effectively takes from row k down. + // We need to replicate this specific sub-vector extraction logic. + + // --- Corrected Subvector Extraction --- + // Create a vector x of size (rows - k) x 1 from column k of z, starting at row k. + let sub_vec_rows = rows - k; + let mut vector_x = Matrix::zeros(sub_vec_rows, 1); + for i in 0..sub_vec_rows { + vector_x.set_entry(i, 0, z1.get_entry(k + i, k)?)?; // Use z1 as per C++ code + } + // --- + + let mut magnitude_x = vector_x.magnitude()?; + + // Sign adjustment based on the diagonal element z[k][k] + // Use the *original* z matrix's diagonal element for the sign check. + if z.get_entry(k, k)? > 0.0 { + magnitude_x = -magnitude_x; + } + + // Create e_k vector (standard basis vector, scaled) + // This corresponds to the first element of the sub_vector space. + let mut vector_e = Matrix::zeros(sub_vec_rows, 1); + if sub_vec_rows > 0 { + vector_e.set_entry(0, 0, 1.0)?; // e_k in the subspace is (1, 0, 0...) + } + + + // Calculate Householder vector v = (x + sign(x_k)*||x||*e_k) / ||...|| + // C++: vectorE = vectorE.scalarMultiply(magnitudeX).add(vectorX).unit(); + let v_unnormalized = vector_e.scalar_multiply(magnitude_x)?.add(&vector_x)?; + let vector_v = v_unnormalized.unit()?; // This is the normalized Householder vector v + + + // Construct the full-size Householder reflector Q_k + // The reflection calculated using vector_v (size m-k) needs to be embedded + // into an m x m matrix: Q_k = diag(I_k, H') where H' is from vector_v. + let mut qk = Matrix::zeros(rows, rows); + // Identity part + for i in 0..k { + qk.set_entry(i,i, 1.0)?; + } + // Householder reflection part (H') for the submatrix + let h_prime = householder_factor(&vector_v)?; + for i in 0..sub_vec_rows { + for j in 0..sub_vec_rows { + qk.set_entry(k+i, k+j, h_prime.get_entry(i, j)?)?; + } + } + + + versions_of_q.push(qk.clone()); // Store Q_k + z = qk.multiply(&z)?; // Update z: z = Q_k * z + } + + // Calculate final Q = Q_{limit-1} * ... * Q_1 * Q_0 + // Note: The C++ code seems to have Q = Q_k ... Q_0. Let's verify. + // Standard definition is A = QR => Q^T A = R => R = Q_k ... Q_0 A + // And Q = (Q_k ... Q_0)^T = Q_0^T ... Q_k^T = Q_0 ... Q_k (since Q_i are symmetric) + // So the C++ multiplication order seems correct. + + if versions_of_q.is_empty() { + // Handle case where no reflections were needed (e.g., 1xN matrix) + // Q should be identity, R should be the original matrix + let mut identity_q = Matrix::zeros(rows, rows); + for i in 0..rows { + identity_q.set_entry(i,i, 1.0)?; + } + return Ok((matrix.clone(), identity_q)); // R=A, Q=I + } + + let mut final_q = versions_of_q[0].clone(); + for i in 1..versions_of_q.len() { + // This order Q = Q_i * Q might be reversed? + // Let's follow C++: Q = Q[i].multiply(Q); + // If Q = Q_{k-1} ... Q_0, then multiplying Q_i * Q is Q_i * Q_{i-1} * ... * Q_0 + // This matches the required product order. + final_q = versions_of_q[i].multiply(&final_q)?; + } + + // Calculate R = Q * A (where Q here is Q_k...Q_0) + let r_matrix = final_q.multiply(matrix)?; + + // The actual Q in A=QR is the transpose of the accumulated reflections product. + // Q = (Q_k...Q_0)^T = Q_0...Q_k + // The C++ code calculates Q = Q_k...Q_0 and then transposes it at the end. + let q_matrix = final_q.transpose(); + + // The C++ returns (R, Q). Let's match that order. + Ok((r_matrix, q_matrix)) +} + + +/// Solves Rx = b where R is an upper triangular matrix using back-substitution. +/// `r` is the upper triangular matrix (NxN). +/// `b` is the right-hand side column vector (Nx1). +/// Returns the solution column vector `x` (Nx1). +fn solve_upper_triangular(r: &Matrix, b: &Matrix) -> MatrixResult { + if r.rows() != b.rows() || b.cols() != 1 { + return Err(MatrixError::IncompatibleDimensions(format!( + "R ({0}x{0}) and b ({1}x{2}) dimensions mismatch for solving Rx=b", + r.rows(), b.rows(), b.cols() + ))); + } + + let n = r.cols(); + let mut result = Matrix::zeros(n, 1); + + // Iterate backwards from the last row (n-1) up to 0 + for k in (0..n).rev() { + let mut total = 0.0; + // Calculate sum(R[k,j] * x[j]) for j from k+1 to n-1 + for j in (k + 1)..n { + total += r.get_entry(k, j)? * result.get_entry(j, 0)?; + } + + // Check for zero on diagonal (singular matrix) + let r_kk = r.get_entry(k, k)?; + if r_kk.abs() < 1e-10 { // Use tolerance for floating point + return Err(MatrixError::InvalidOperation("Matrix R is singular or near-singular.".to_string())); + } + + // Calculate x[k] = (b[k] - total) / R[k,k] + let val = (b.get_entry(k, 0)? - total) / r_kk; + result.set_entry(k, 0, val)?; + } + + Ok(result) +} + + +/// Solves the least squares problem Ax = b using QR decomposition. +/// `vandermonde` corresponds to matrix A. +/// `b` is the right-hand side vector. +fn least_squares(vandermonde: &Matrix, b: &Matrix) -> MatrixResult { + // Perform QR decomposition: A = QR + let (r_matrix, q_matrix) = householder(vandermonde)?; + + // We need to solve Rx = Q^T * b + // Our householder returns (R, Q), so Q^T is Q.transpose() + let q_transpose = q_matrix.transpose(); + let q_transpose_b = q_transpose.multiply(b)?; + + // The system might be Ax=b where A is MxN, M > N. + // QR decomposition gives A = QR where Q is MxM orthogonal, R is MxN upper trapezoidal. + // Q^T A = R => Q^T (Ax) = Q^T b => R x = Q^T b + // R = [ R' ] where R' is NxN upper triangular + // [ 0 ] + // Q^T b = [ c1 ] where c1 is Nx1 + // [ c2 ] + // We solve R' x = c1. + + let n = vandermonde.cols(); // Number of columns in A = number of variables in x + if r_matrix.rows() < n { + return Err(MatrixError::InvalidOperation("R matrix has fewer rows than columns needed for solving.".to_string())); + } + + // Extract the top NxN part of R (R') + let mut r_prime = Matrix::zeros(n, n); + for i in 0..n { + for j in i..n { // Upper triangular part + r_prime.set_entry(i, j, r_matrix.get_entry(i, j)?)?; + } + } + + // Extract the top N rows of Q^T * b (c1) + let mut c1 = Matrix::zeros(n, 1); + if q_transpose_b.rows() < n { + return Err(MatrixError::InvalidOperation("Q^T*b vector has fewer rows than needed for solving.".to_string())); + } + for i in 0..n { + c1.set_entry(i, 0, q_transpose_b.get_entry(i, 0)?)?; + } + + + // Solve the upper triangular system R' x = c1 + solve_upper_triangular(&r_prime, &c1) +} + +/// Fits a polynomial of a given degree to data points (x, y). +/// `x` is a 1xN row vector of x-coordinates. +/// `y` is a 1xN row vector of y-coordinates. +/// Returns the polynomial coefficients as a column vector. +fn fit_polynomial(x: &Matrix, y: &Matrix, polynomial_degree: usize) -> MatrixResult { + // Validate input dimensions + if x.rows() != 1 || y.rows() != 1 || x.cols() != y.cols() { + return Err(MatrixError::IncompatibleDimensions( + "x and y must be 1xN matrices with the same N".to_string() + )); + } + let num_points = x.cols(); + let num_coeffs = polynomial_degree + 1; + + // Create the Vandermonde matrix (MxN where M=num_points, N=num_coeffs) + let mut vandermonde = Matrix::zeros(num_points, num_coeffs); + for i in 0..num_points { // Iterate through data points (rows of Vandermonde) + let x_val = x.get_entry(0, i)?; + for j in 0..num_coeffs { // Iterate through powers (columns of Vandermonde) + vandermonde.set_entry(i, j, x_val.powi(j as i32))?; // V[i, j] = x_i ^ j + } + } + + // The least squares function expects b as a column vector. + // Our y is currently a row vector. Transpose it. + let y_col = y.transpose(); + + // Solve the least squares problem Vc = y + least_squares(&vandermonde, &y_col) +} + + +// --- Main Function (example usage) --- +fn main() -> MatrixResult<()> { + let data = vec![ + vec![12.0, -51.0, 4.0], + vec![6.0, 167.0, -68.0], + vec![-4.0, 24.0, -41.0], + vec![-1.0, 1.0, 0.0], + vec![2.0, 0.0, 3.0], + ]; + + // Task 1: QR Decomposition + println!("--- Task 1: QR Decomposition ---"); + let a = Matrix::from_data(data)?; + println!("Initial matrix A:"); + println!("{}", a); + + let (r_matrix, q_matrix) = householder(&a)?; // Returns (R, Q) + + println!("Matrix Q:"); + println!("{}", q_matrix); + println!("Matrix R:"); + println!("{}", r_matrix); + + let result = q_matrix.multiply(&r_matrix)?; + println!("Matrix Q * R:"); + println!("{}", result); + + // Task 2: Polynomial Fitting + println!("--- Task 2: Polynomial Fitting ---"); + let x = Matrix::from_data(vec![vec![ + 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, + ]])?; + let y = Matrix::from_data(vec![vec![ + 1.0, 6.0, 17.0, 34.0, 57.0, 86.0, 121.0, 162.0, 209.0, 262.0, 321.0, + ]])?; + + let poly_coeffs = fit_polynomial(&x, &y, 2)?; // Fit a quadratic polynomial (degree 2) + println!("Result of fitting polynomial (coefficients c0, c1, c2):"); + println!("{}", poly_coeffs); + + // Example: Check coefficients (should be close to c0=1, c1=2, c2=3 for y = 1 + 2x + 3x^2) + // Note: The calculated coefficients might be: + // [ 1.0000 ] + // [ 2.0000 ] + // [ 3.0000 ] + + Ok(()) +} diff --git a/Task/Quaternion-type/REXX/quaternion-type.rexx b/Task/Quaternion-type/REXX/quaternion-type.rexx index fe4674ecb4..6d6eb480da 100644 --- a/Task/Quaternion-type/REXX/quaternion-type.rexx +++ b/Task/Quaternion-type/REXX/quaternion-type.rexx @@ -1,41 +1,42 @@ -/*REXX program performs some operations on quaternion type numbers and displays results*/ - q = 1 2 3 4 ; q1 = 2 3 4 5 - r = 7 ; q2 = 3 4 5 6 -call qShow q , 'q' -call qShow q1 , 'q1' -call qShow q2 , 'q2' -call qShow r , 'r' -call qShow qNorm(q) , 'norm q' , "task 1:" -call qShow qNeg(q) , 'negative q' , "task 2:" -call qShow qConj(q) , 'conjugate q' , "task 3:" -call qShow qAdd( r, q ) , 'addition r+q' , "task 4:" -call qShow qAdd(q1, q2 ) , 'addition q1+q2' , "task 5:" -call qShow qMul( q, r ) , 'multiplication q*r' , "task 6:" -call qShow qMul(q1, q2 ) , 'multiplication q1*q2' , "task 7:" -call qShow qMul(q2, q1 ) , 'multiplication q2*q1' , "task 8:" -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -qConj: procedure; parse arg x; call qXY; return x.1 (-x.2) (-x.3) (-x.4) -qNeg: procedure; parse arg x; call qXY; return -x.1 (-x.2) (-x.3) (-x.4) -qNorm: procedure; parse arg x; call qXY; return sqrt(x.1**2 +x.2**2 +x.3**2 +x.4**2) -qAdd: procedure; parse arg x,y; call qXY 2; return x.1+y.1 x.2+y.2 x.3+y.3 x.4+y.4 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -qMul: procedure; parse arg x,y; call qXY y - return x.1*y.1 -x.2*y.2 -x.3*y.3 -x.4*y.4 x.1*y.2 +x.2*y.1 +x.3*y.4 -x.4*y.3 , - x.1*y.3 -x.2*y.4 +x.3*y.1 +x.4*y.2 x.1*y.4 +x.2*y.3 -x.3*y.2 +x.4*y.1 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -qShow: procedure; parse arg x; call qXY; $= - do m=1 for 4; _= x.m; if _==0 then iterate; if _>=0 then _= '+'_ - if m\==1 then _= _ || substr('∙ijk', m, 1); $= strip($ || _, , "+") - end /*m*/ - say left(arg(3), 9) right(arg(2), 20) ' ──► ' $; return $ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -qXY: do n=1 for 4; x.n= word( word(x, n) 0, 1)/1; end /*n*/ - if arg()==1 then do m=1 for 4; y.m= word( word(y, m) 0, 1)/1; end /*m*/; return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sqrt: procedure; parse arg x; if x=0 then return 0; d= digits(); i=; m.=9; h=d+6 - numeric digits; numeric form; if x<0 then parse value -x 'i' with x i - parse value format(x, 2, 1, , 0) 'E0' with g "E" _ .; g= g *.5'e'_ % 2 - do j=0 while h>9; m.j=h; h= h % 2 + 1; end /*j*/ - do k=j+5 to 0 by -1; numeric digits m.k; g= (g + x/g)* .5; end /*k*/ - numeric digits d; return (g/1)i /*make complex if X<0 */ +-- 19 May 2025 +include Settings + +say 'QUATERNION TYPE' +say version +say +i = '0 1'; j = '0 0 1'; k = '0 0 0 1' +q = '1 2 3 4'; q1 = '2 3 4 5'; q2 = '3 4 5 6'; r = 7 +say 'VALUES' +say 'i =' Hlst2Form(i) +say 'j =' Hlst2Form(j) +say 'k =' Hlst2Form(k) +say 'q =' Hlst2Form(q) +say 'q1 =' Hlst2Form(q1) +say 'q2 =' Hlst2Form(q2) +say 'r =' Hlst2Form(r) +say +say 'BASICS' +say 'i*i =' Hlst2Form(Hsquare(i)) +say 'j*j =' Hlst2Form(Hsquare(j)) +say 'k*k =' Hlst2Form(Hsquare(k)) +say 'i*j*k =' Hlst2Form(Hmul(i,j,k)) +say '||q|| =' Std(Hnorm(q)) +say '-q =' Hlst2Form(Hneg(q)) +say 'q* =' Hlst2Form(Hconj(q)) +say 'q+r =' Hlst2Form(Hadd(q,r)) +say 'r+q =' Hlst2Form(Hadd(r,q)) +say 'q1+q2 =' Hlst2Form(Hadd(q1,q2)) +say 'q2+q1 =' Hlst2Form(Hadd(q2,q1)) +say 'q*r =' Hlst2Form(Hmul(q,r)) +say 'r*q =' Hlst2Form(Hmul(r,q)) +say 'q1*q2 =' Hlst2Form(Hmul(q1,q2)) +say 'q2*q1 =' Hlst2Form(Hmul(q2,q1)) +say +say 'BONUS' +say 'q/r =' Hlst2Form(Hdiv(q,r)) +say '1/q =' Hlst2Form(Hinv(q)) +exit + +include Quaternion +include Functions +include Abend diff --git a/Task/Queue-Definition/EasyLang/queue-definition.easy b/Task/Queue-Definition/EasyLang/queue-definition.easy index f59c254ed9..a05a51a1fe 100644 --- a/Task/Queue-Definition/EasyLang/queue-definition.easy +++ b/Task/Queue-Definition/EasyLang/queue-definition.easy @@ -1,7 +1,7 @@ prefix qu_ global q[] head tail . # -proc enq n . . +proc enq n . if tail = 0 head = 1 else diff --git a/Task/Quickselect-algorithm/EasyLang/quickselect-algorithm.easy b/Task/Quickselect-algorithm/EasyLang/quickselect-algorithm.easy index 79f18b94cf..f4cdb174f6 100644 --- a/Task/Quickselect-algorithm/EasyLang/quickselect-algorithm.easy +++ b/Task/Quickselect-algorithm/EasyLang/quickselect-algorithm.easy @@ -1,4 +1,4 @@ -proc qselect k . list[] res . +func qselect &list[] k . # subr partition mid = left @@ -22,10 +22,9 @@ proc qselect k . list[] res . left = right . . - res = list[k] + return list[k] . d[] = [ 9 8 7 6 5 0 1 2 3 4 ] for i = 1 to len d[] - qselect i d[] r - print r + print qselect d[] i . diff --git a/Task/Quickselect-algorithm/Zig/quickselect-algorithm.zig b/Task/Quickselect-algorithm/Zig/quickselect-algorithm.zig new file mode 100644 index 0000000000..9ded83c244 --- /dev/null +++ b/Task/Quickselect-algorithm/Zig/quickselect-algorithm.zig @@ -0,0 +1,69 @@ +const std = @import("std"); + +fn partition(comptime T: type, a: []T, left: usize, right: usize, pivot: usize) usize { + std.mem.swap(T, &a[pivot], &a[right]); + var store_index = left; + var i = left; + while (i < right) : (i += 1) { + if (a[i] < a[right]) { + std.mem.swap(T, &a[store_index], &a[i]); + store_index += 1; + } + } + std.mem.swap(T, &a[right], &a[store_index]); + return store_index; +} + +fn pivotIndex(left: usize, right: usize) usize { + return left + (right - left) / 2; +} + +fn select(comptime T: type, a: []T, left_init: usize, right_init: usize, n: usize) void { + var left = left_init; + var right = right_init; + + while (true) { + if (left == right) { + break; + } + + var pivot = pivotIndex(left, right); + pivot = partition(T, a, left, right, pivot); + + if (n == pivot) { + break; + } else if (n < pivot) { + right = pivot - 1; + } else { + left = pivot + 1; + } + } +} + +// Rearranges the elements of 'a' such that the element at index 'n' is +// the same as it would be if the array were sorted, smaller elements are +// to the left of it and larger elements are to its right. +fn nthElement(comptime T: type, a: []T, n: usize) void { + select(T, a, 0, a.len - 1, n); +} + +pub fn main() !void { + const allocator = std.heap.page_allocator; + const a = [_]i32{ 9, 8, 7, 6, 5, 0, 1, 2, 3, 4 }; + + var n: usize = 0; + while (n < a.len) : (n += 1) { + var b = try allocator.alloc(i32, a.len); + defer allocator.free(b); + + // Copy elements one by one instead of using mem.copy + for (0..a.len) |i| { + b[i] = a[i]; + } + + nthElement(i32, b, n); + + const stdout = std.io.getStdOut().writer(); + try stdout.print("n = {}, nth element = {}\n", .{ n + 1, b[n] }); + } +} diff --git a/Task/Quine/Rust/quine-1.rs b/Task/Quine/Rust/quine-1.rs index 8e71d160ec..102ef358ba 100644 --- a/Task/Quine/Rust/quine-1.rs +++ b/Task/Quine/Rust/quine-1.rs @@ -1,7 +1,3 @@ fn main() { - let x = "fn main() {\n let x = "; - let y = "print!(\"{}{:?};\n let y = {:?};\n {}\", x, x, y, y)\n}\n"; - print!("{}{:?}; - let y = {:?}; - {}", x, x, y, y) + print!("{}", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/", file!()))); } diff --git a/Task/Quine/Rust/quine-2.rs b/Task/Quine/Rust/quine-2.rs index 88df728796..5d3dff053c 100644 --- a/Task/Quine/Rust/quine-2.rs +++ b/Task/Quine/Rust/quine-2.rs @@ -1,59 +1,4 @@ -fn main() -{ - let q = 34u8; - let p = 44u8; - let l = [ - "fn main()", - "{", - " let q = 34u8;", - " let p = 44u8;", - " let l = [", - " ", - " ];", - " let mut i = 0;", - " while i < 5", - " {", - " println(l[i]);", - " i+=1;", - " }", - " i = 0;", - " while i < l.len()", - " {", - " print(l[5]);", - " print((q as char).to_str());", - " print(l[i]);", - " print((q as char).to_str());", - " println((p as char).to_str());", - " i+=1;", - " }", - " i = 6;", - " while i < l.len()", - " {", - " println(l[i]);", - " i+=1;", - " }", - "}", - ]; - let mut i = 0; - while i < 5 - { - println(l[i]); - i+=1; - } - i = 0; - while i < l.len() - { - print(l[5]); - print((q as char).to_str()); - print(l[i]); - print((q as char).to_str()); - println((p as char).to_str()); - i+=1; - } - i = 6; - while i < l.len() - { - println(l[i]); - i+=1; - } +fn main() { + macro_rules! script {() => {"fn main() {{\n\tmacro_rules! script {{() => {{{:?}}}}}\n\tprintln!(script!(), script!());\n}}"}} + println!(script!(), script!()); } diff --git a/Task/Quine/Rust/quine-3.rs b/Task/Quine/Rust/quine-3.rs index 56e8dac1dc..8e71d160ec 100644 --- a/Task/Quine/Rust/quine-3.rs +++ b/Task/Quine/Rust/quine-3.rs @@ -1,42 +1,7 @@ - fn main(){let q:&[u8]=&[ - 32,00,00,00,00,00,00,00,61,27,80,82, - 73,78,84,76,78,01,08,02,91,93,70,78,00,77,65,73,78,08, - 09,91,91,76,69,84,00,81,26,06,59,85,24,61,29,06,59,02,12,00,51,84, - 82,73,78,71,26,26,70,82,79,77,63,85,84,70,24,08,86,69,67,01,59,66,07,00, - 07,27,00,21,20,61,09,14,85,78,87,82,65,80,08,09,09,27,76,69,84,00,82,29,08,81, - 14,76,69,78,08,09,65,83,00,70,22,20,15,83,84,68,26,26,70,22,20,32,00,00,00,00,00,00,00,00, - 00,26,26,67,79,78,83,84,83,26,26,48,41,09,14,83,81,82,84,08,09,65,83,00,73,19,18,11,20,27,76,69, - 84,00,77,85,84,00,66,26,00,54,69,67,28,08,73,19,18,12,00,73,19,18,09,00,30,29,00,54,69,67,26,26, - 78,69,87,08,09,27,00,15,10,00,00,00,79,79,69,82,00,00,10,15,00,76,69,84,00,77,85,84,00,88,29,82,13,17, - 27,00,76,69,84,00,77,85,84,00,89,29,16,27,32,00,00,00,00,00,00,00,00,00,00,76,69,84,00,77,85,84,00,75,29,17, - 27,76,69,84,00,77,85,84,00,74,29,17,27,76,69,84,00,77,85,84,00,69,29,75,00,13,08,82,28,28,17,09,27,87,72,73,76,69, - 00,88,30,29,89,91,66,14,80,85,83,72,08,08,82,11,88,12,82,11,89,09,09,27,66,14,80,85,83,72,08,08,82,11,89,12,82,11, - 88,09,09,27,00,66,14,80,85,83,72,08,08,82,13,89,12,82,11,88,09,32,00,00,00,00,00,00,00,00,00,00,00,00,00,09,27,66,14,80, - 85,83,72,08,08,82,13,88,12,00,82,11,89,09,09,27,66,14,80,85,83,72,08,08,82,13,88,12,82,13,89,09,09,27,66,14,80,85,83,72, - 08,08,82,13,89,12,82,13,88,09,09,27,00,66,14,80,85,83,72,08,08,82,11,89,12,82,13,88,09,09,27,66,14,80,85,83,72,08,08,82, - 11,88,12,82,13,89,09,09,27,00,73,70,00,69,28,29,16,91,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,89,11,29,17,27,69,11, - 29,74,27,74,11,29,18,27,93,73,70,00,69,30,16,00,91,88,13,29,17,27,75,11,29,18,27,69,11,29,75,13,08,82,28,28,17,09,27,93,93,76, - 69,84,00,77,85,84,00,84,29,81,14,73,84,69,82,08,09,27,07,79,26,70,79,82,00,89,00,73,78,00,17,14,14,82,10,18,00,91,00,76,69,84, - 00,76,26,00,54,69,67,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,28,73,19,18,30,00,29,00,66,14,73,84,69,82,08, - 09,14,70,73,76,84,69,82,08,92,88,92,00,88,14,17,29,29,89,09,14,77,65,80,08,92,88,92,00,88,14,16,09,14,67,79,76,76,69,67,84,08, - 09,27,00,76,69,84,00,88,00,29,00,76,14,73,84,69,82,08,09,14,67,76,79,78,69,68,08,09,14,70,79,76,68,08,16,12,32,00,00,00,00,00, - 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,73,19,18,26,26,77,65,88,09,27,00,76,69,84,00,78,00,29,76,14,73,84,69,82,08,09, - 14,67,76,79,78,69,68,08,09,14,70,79,76,68,08,25,25,25,12,00,73,19,18,26,26,77,73,78,09,27,76,69,84,00,77,29,88,13,78,27,00,70, - 79,82,00,63,00,73,78,00,16,14,14,78,00,91,00,80,82,73,78,84,01,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, - 00,00,00,00,08,02,00,00,00,02,09,27,93,70,79,82,00,63,00,73,78,00,16,14,14,77,91,00,73,70,00,76,69,84,00,51,79,77,69,08,86,09, - 00,29,00,84,14,78,69,88,84,08,09,00,91,80,82,73,78,84,01,08,02,91,26,16,18,93,12,02,12,86,09,27,93,00,69,76,83,69,91,00,66,82, - 69,65,75,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,79,27,00,93,93,00,80,82,73, - 78,84,01,08,02,60,78,02,09,27,00,93,00,70,79,82,00,78,00,73,78,00,81,14,73,84,69,82,08,09,00,91,00,80,82,73,78,84,01,08,02,91, - 93,02,12,00,08,73,70,00,10,78,29,29,19,18,91,17,16,93,00,69,76,83,69,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, - 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,91,10,78,11,19,18,93,09,00,65,83,00,67,72,65,82,09,27,93,80,82,73, - 78,84,01,08,02,60,78,02,09,27,93,00,15,15,00,71,73,84,72,85,66,14,67,79,77,15,75,73,82,74,65,86,65,83,67,82,73,80,84, - ];println!("{}fn main(){{let q:&[u8]=&[", String::from_utf8(vec![b' '; 54]).unwrap());let r=(q.len()as f64/std::f64 - ::consts::PI).sqrt()as i32+4;let mut b: Vec<(i32, i32) >= Vec::new(); /* ooer */ let mut x=r-1; let mut y=0; - let mut k=1;let mut j=1;let mut e=k -(r<<1);while x>=y{b.push((r+x,r+y));b.push((r+y,r+x)); b.push((r-y,r+x) - );b.push((r-x, r+y));b.push((r-x,r-y));b.push((r-y,r-x)); b.push((r+y,r-x));b.push((r+x,r-y)); if e<=0{ - y+=1;e+=j;j+=2;}if e>0 {x-=1;k+=2;e+=k-(r<<1);}}let mut t=q.iter();'o:for y in 1..r*2 { let l: Vec - = b.iter().filter(|x| x.1==y).map(|x| x.0).collect(); let x = l.iter().cloned().fold(0, - i32::max); let n =l.iter().cloned().fold(999, i32::min);let m=x-n; for _ in 0..n { print! - (" ");}for _ in 0..m{ if let Some(v) = t.next() {print!("{:02},",v);} else{ break - 'o; }} print!("\n"); } for n in q.iter() { print!("{}", (if *n==32{10} else - {*n+32}) as char);}print!("\n");} // github.com/kirjavascript +fn main() { + let x = "fn main() {\n let x = "; + let y = "print!(\"{}{:?};\n let y = {:?};\n {}\", x, x, y, y)\n}\n"; + print!("{}{:?}; + let y = {:?}; + {}", x, x, y, y) +} diff --git a/Task/Quine/Rust/quine-4.rs b/Task/Quine/Rust/quine-4.rs index 5d3dff053c..88df728796 100644 --- a/Task/Quine/Rust/quine-4.rs +++ b/Task/Quine/Rust/quine-4.rs @@ -1,4 +1,59 @@ -fn main() { - macro_rules! script {() => {"fn main() {{\n\tmacro_rules! script {{() => {{{:?}}}}}\n\tprintln!(script!(), script!());\n}}"}} - println!(script!(), script!()); +fn main() +{ + let q = 34u8; + let p = 44u8; + let l = [ + "fn main()", + "{", + " let q = 34u8;", + " let p = 44u8;", + " let l = [", + " ", + " ];", + " let mut i = 0;", + " while i < 5", + " {", + " println(l[i]);", + " i+=1;", + " }", + " i = 0;", + " while i < l.len()", + " {", + " print(l[5]);", + " print((q as char).to_str());", + " print(l[i]);", + " print((q as char).to_str());", + " println((p as char).to_str());", + " i+=1;", + " }", + " i = 6;", + " while i < l.len()", + " {", + " println(l[i]);", + " i+=1;", + " }", + "}", + ]; + let mut i = 0; + while i < 5 + { + println(l[i]); + i+=1; + } + i = 0; + while i < l.len() + { + print(l[5]); + print((q as char).to_str()); + print(l[i]); + print((q as char).to_str()); + println((p as char).to_str()); + i+=1; + } + i = 6; + while i < l.len() + { + println(l[i]); + i+=1; + } } diff --git a/Task/Quine/Rust/quine-5.rs b/Task/Quine/Rust/quine-5.rs new file mode 100644 index 0000000000..56e8dac1dc --- /dev/null +++ b/Task/Quine/Rust/quine-5.rs @@ -0,0 +1,42 @@ + fn main(){let q:&[u8]=&[ + 32,00,00,00,00,00,00,00,61,27,80,82, + 73,78,84,76,78,01,08,02,91,93,70,78,00,77,65,73,78,08, + 09,91,91,76,69,84,00,81,26,06,59,85,24,61,29,06,59,02,12,00,51,84, + 82,73,78,71,26,26,70,82,79,77,63,85,84,70,24,08,86,69,67,01,59,66,07,00, + 07,27,00,21,20,61,09,14,85,78,87,82,65,80,08,09,09,27,76,69,84,00,82,29,08,81, + 14,76,69,78,08,09,65,83,00,70,22,20,15,83,84,68,26,26,70,22,20,32,00,00,00,00,00,00,00,00, + 00,26,26,67,79,78,83,84,83,26,26,48,41,09,14,83,81,82,84,08,09,65,83,00,73,19,18,11,20,27,76,69, + 84,00,77,85,84,00,66,26,00,54,69,67,28,08,73,19,18,12,00,73,19,18,09,00,30,29,00,54,69,67,26,26, + 78,69,87,08,09,27,00,15,10,00,00,00,79,79,69,82,00,00,10,15,00,76,69,84,00,77,85,84,00,88,29,82,13,17, + 27,00,76,69,84,00,77,85,84,00,89,29,16,27,32,00,00,00,00,00,00,00,00,00,00,76,69,84,00,77,85,84,00,75,29,17, + 27,76,69,84,00,77,85,84,00,74,29,17,27,76,69,84,00,77,85,84,00,69,29,75,00,13,08,82,28,28,17,09,27,87,72,73,76,69, + 00,88,30,29,89,91,66,14,80,85,83,72,08,08,82,11,88,12,82,11,89,09,09,27,66,14,80,85,83,72,08,08,82,11,89,12,82,11, + 88,09,09,27,00,66,14,80,85,83,72,08,08,82,13,89,12,82,11,88,09,32,00,00,00,00,00,00,00,00,00,00,00,00,00,09,27,66,14,80, + 85,83,72,08,08,82,13,88,12,00,82,11,89,09,09,27,66,14,80,85,83,72,08,08,82,13,88,12,82,13,89,09,09,27,66,14,80,85,83,72, + 08,08,82,13,89,12,82,13,88,09,09,27,00,66,14,80,85,83,72,08,08,82,11,89,12,82,13,88,09,09,27,66,14,80,85,83,72,08,08,82, + 11,88,12,82,13,89,09,09,27,00,73,70,00,69,28,29,16,91,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,89,11,29,17,27,69,11, + 29,74,27,74,11,29,18,27,93,73,70,00,69,30,16,00,91,88,13,29,17,27,75,11,29,18,27,69,11,29,75,13,08,82,28,28,17,09,27,93,93,76, + 69,84,00,77,85,84,00,84,29,81,14,73,84,69,82,08,09,27,07,79,26,70,79,82,00,89,00,73,78,00,17,14,14,82,10,18,00,91,00,76,69,84, + 00,76,26,00,54,69,67,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,28,73,19,18,30,00,29,00,66,14,73,84,69,82,08, + 09,14,70,73,76,84,69,82,08,92,88,92,00,88,14,17,29,29,89,09,14,77,65,80,08,92,88,92,00,88,14,16,09,14,67,79,76,76,69,67,84,08, + 09,27,00,76,69,84,00,88,00,29,00,76,14,73,84,69,82,08,09,14,67,76,79,78,69,68,08,09,14,70,79,76,68,08,16,12,32,00,00,00,00,00, + 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,73,19,18,26,26,77,65,88,09,27,00,76,69,84,00,78,00,29,76,14,73,84,69,82,08,09, + 14,67,76,79,78,69,68,08,09,14,70,79,76,68,08,25,25,25,12,00,73,19,18,26,26,77,73,78,09,27,76,69,84,00,77,29,88,13,78,27,00,70, + 79,82,00,63,00,73,78,00,16,14,14,78,00,91,00,80,82,73,78,84,01,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, + 00,00,00,00,08,02,00,00,00,02,09,27,93,70,79,82,00,63,00,73,78,00,16,14,14,77,91,00,73,70,00,76,69,84,00,51,79,77,69,08,86,09, + 00,29,00,84,14,78,69,88,84,08,09,00,91,80,82,73,78,84,01,08,02,91,26,16,18,93,12,02,12,86,09,27,93,00,69,76,83,69,91,00,66,82, + 69,65,75,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,07,79,27,00,93,93,00,80,82,73, + 78,84,01,08,02,60,78,02,09,27,00,93,00,70,79,82,00,78,00,73,78,00,81,14,73,84,69,82,08,09,00,91,00,80,82,73,78,84,01,08,02,91, + 93,02,12,00,08,73,70,00,10,78,29,29,19,18,91,17,16,93,00,69,76,83,69,32,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, + 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,91,10,78,11,19,18,93,09,00,65,83,00,67,72,65,82,09,27,93,80,82,73, + 78,84,01,08,02,60,78,02,09,27,93,00,15,15,00,71,73,84,72,85,66,14,67,79,77,15,75,73,82,74,65,86,65,83,67,82,73,80,84, + ];println!("{}fn main(){{let q:&[u8]=&[", String::from_utf8(vec![b' '; 54]).unwrap());let r=(q.len()as f64/std::f64 + ::consts::PI).sqrt()as i32+4;let mut b: Vec<(i32, i32) >= Vec::new(); /* ooer */ let mut x=r-1; let mut y=0; + let mut k=1;let mut j=1;let mut e=k -(r<<1);while x>=y{b.push((r+x,r+y));b.push((r+y,r+x)); b.push((r-y,r+x) + );b.push((r-x, r+y));b.push((r-x,r-y));b.push((r-y,r-x)); b.push((r+y,r-x));b.push((r+x,r-y)); if e<=0{ + y+=1;e+=j;j+=2;}if e>0 {x-=1;k+=2;e+=k-(r<<1);}}let mut t=q.iter();'o:for y in 1..r*2 { let l: Vec + = b.iter().filter(|x| x.1==y).map(|x| x.0).collect(); let x = l.iter().cloned().fold(0, + i32::max); let n =l.iter().cloned().fold(999, i32::min);let m=x-n; for _ in 0..n { print! + (" ");}for _ in 0..m{ if let Some(v) = t.next() {print!("{:02},",v);} else{ break + 'o; }} print!("\n"); } for n in q.iter() { print!("{}", (if *n==32{10} else + {*n+32}) as char);}print!("\n");} // github.com/kirjavascript diff --git a/Task/Quine/V-(Vlang)/quine.v b/Task/Quine/V-(Vlang)/quine.v new file mode 100644 index 0000000000..edc87d53c7 --- /dev/null +++ b/Task/Quine/V-(Vlang)/quine.v @@ -0,0 +1,3 @@ +fn main() { + print($embed_file(@FILE).to_string()) +} diff --git a/Task/Quine/Zig/quine.zig b/Task/Quine/Zig/quine.zig new file mode 100644 index 0000000000..5383d7837a --- /dev/null +++ b/Task/Quine/Zig/quine.zig @@ -0,0 +1,6 @@ +const std = @import("std"); + +pub fn main() !void { + const content = @embedFile(@src().file); + try std.io.getStdOut().writer().print("{s}", .{content}); +} diff --git a/Task/Radical-of-an-integer/EasyLang/radical-of-an-integer.easy b/Task/Radical-of-an-integer/EasyLang/radical-of-an-integer.easy index 6902e0dcf0..01254f329e 100644 --- a/Task/Radical-of-an-integer/EasyLang/radical-of-an-integer.easy +++ b/Task/Radical-of-an-integer/EasyLang/radical-of-an-integer.easy @@ -9,9 +9,7 @@ fastfunc radnf num . . d += 1 . - if d <= num - nf += 1 - . + if d <= num : nf += 1 return nf . func rad num . @@ -26,22 +24,20 @@ func rad num . . d += 1 . - if d <= num - r *= num - . + if d <= num : r *= num return r . -proc show50 . . +proc show50 . write "First 50 radicals:" for n = 1 to 50 write " " & rad n . print "" . -proc show n . . +proc show n . print "radical(" & n & ") = " & rad n . -proc dist . . +proc dist . len dist[] 7 for n = 2 to 1000000 dist[radnf n] += 1 diff --git a/Task/Radical-of-an-integer/REXX/radical-of-an-integer-2.rexx b/Task/Radical-of-an-integer/REXX/radical-of-an-integer-2.rexx index f3d3b14ceb..9ebed865c0 100644 --- a/Task/Radical-of-an-integer/REXX/radical-of-an-integer-2.rexx +++ b/Task/Radical-of-an-integer/REXX/radical-of-an-integer-2.rexx @@ -1,11 +1,14 @@ +-- 8 May 2025 include Settings -say version; say 'Radical of an integer'; say +say 'RADICAL OF AN INTEGER' +say version +say arg n if n = '' then n = 1000000 numeric digits 100 -say 'Radicals for 1..50:' +say 'Radicals for 1..50...' ol = '' do i = 1 to 50 ol = ol||Right(Radical(i),5) @@ -14,13 +17,13 @@ do i = 1 to 50 end end say -say 'Radicals for:' +say 'Radicals for...' say '99999 =' Radical(99999) say '499999 =' Radical(499999) say '999999 =' Radical(999999) say -m = n/10; r = Isqrt(n); radi. = 0 say 'Getting distribution list...' +m = n/10; r = Isqrt(n); radi. = 0 call Time('r') do i = 1 to n call Radical(i) @@ -32,7 +35,7 @@ do i = 1 to n end end say -say 'Distribution for first' n 'radicals over Number of Factors:' +say 'Distribution for first' n 'radicals over Number of Factors...' do i = 0 to 10 if radi.i > 0 then say Right(i,2)':' Right(radi.i,6) @@ -47,7 +50,7 @@ say 'Getting powers of Primes up to' r'...' call Time('r') pw = 0 do i = 1 - p1 = prim.Prime.i + p1 = prim.i if p1 > r then leave p2 = p1 @@ -66,20 +69,8 @@ say ' -----' say 'Total ' Format(pr+pw,6) exit -Radical: -/* Radical = product of unique prime factors */ -procedure expose ufac. -arg x -/* Get unique factors */ -n = Ufactors(x) -/* Calculate product */ -y = 1 -do i = 1 to n - y = y*ufac.factor.i -end -return y - include Functions +include Special include Numbers include Sequences include Abend diff --git a/Task/Radical-of-an-integer/SETL/radical-of-an-integer.setl b/Task/Radical-of-an-integer/SETL/radical-of-an-integer.setl new file mode 100644 index 0000000000..51f074c1f0 --- /dev/null +++ b/Task/Radical-of-an-integer/SETL/radical-of-an-integer.setl @@ -0,0 +1,43 @@ +program radicals_of_an_integer; + init factab := distinct_factor_table(1000000); + + print("Radicals of the first 50 integers:"); + loop for n in [1..50] do + nprint(lpad(str radical n, 5)); + if n mod 10=0 then print; end if; + end loop; + + print; + loop for n in [99999, 499999, 999999] do + print("Radical of " + lpad(str n, 6) + ": " + lpad(str radical n, 6)); + end loop; + + print; + print("Distribution of factor counts:"); + + distr := {}; + loop for f = factab(n) do + distr(#f) +:= 1; + end loop; + loop for amount = distr(n) do + print(str n + ": " + lpad(str amount, 6)); + end loop; + + op radical(n); + return 1 */ factab(n); + end op; + + proc distinct_factor_table(n); + factab := [{}] * n; + + loop init i := 2; while i <= n step i +:= 1; do + if factab(i) = {} then + loop init c := i; while c <= n step c +:= i; do + factab(c) with:= i; + end loop; + end if; + end loop; + + return factab; + end proc; +end program; diff --git a/Task/Ramanujan-primes-twins/EasyLang/ramanujan-primes-twins.easy b/Task/Ramanujan-primes-twins/EasyLang/ramanujan-primes-twins.easy index fd1878b281..bc2b3055f5 100644 --- a/Task/Ramanujan-primes-twins/EasyLang/ramanujan-primes-twins.easy +++ b/Task/Ramanujan-primes-twins/EasyLang/ramanujan-primes-twins.easy @@ -1,5 +1,5 @@ global cnt[] . -proc primcnt limit . . +proc primcnt limit . cnt[] = [ 0 1 1 ] for i = 4 step 2 to limit cnt[] &= 0 diff --git a/Task/Ramanujan-primes-twins/REXX/ramanujan-primes-twins.rexx b/Task/Ramanujan-primes-twins/REXX/ramanujan-primes-twins.rexx new file mode 100644 index 0000000000..f4f86b651f --- /dev/null +++ b/Task/Ramanujan-primes-twins/REXX/ramanujan-primes-twins.rexx @@ -0,0 +1,43 @@ +-- 12 Apr 2025 +include Settings +numeric digits 10 + +call Time('r') +say 'RAMANUJAN TWIN PRIMES' +say version +say +call Primes Floor(4*6e5*Ln(4*6e5)) +call Ramanujans +call Twins +say prim.0 'primes processed' +say rama.0 'Ramanujan primes processed' +say twin.0 'Ramanujan twin primes primes found' +say Format(Time('e'),,3) 'seconds' +exit + +Ramanujans: +procedure expose prim. rama. +rama. = 0; j = 1; rama.1 = 2 +do i = 2 to prim.0 + a = prim.i; b = a/2; c = prim.j + do while c < b + j = j+1; c = prim.j + end + d = i-j+1; rama.d = a; rama.0 = Max(d,rama.0) +end +return 0 + +Twins: +procedure expose rama. twin. +twin. = 0 +do i = 2 to 1e6 + i1 = i-1 + if rama.i-rama.i1 = 2 then + twin.0 = twin.0+1 +end +return + +include Sequences +include Functions +include Constants +include Abend diff --git a/Task/Ramanujans-constant/REXX/ramanujans-constant.rexx b/Task/Ramanujans-constant/REXX/ramanujans-constant.rexx index 67a32ac25f..7639f2025b 100644 --- a/Task/Ramanujans-constant/REXX/ramanujans-constant.rexx +++ b/Task/Ramanujans-constant/REXX/ramanujans-constant.rexx @@ -1,35 +1,33 @@ -/*REXX pgm displays Ramanujan's constant to at least 100 decimal digits of precision. */ -d= min( length(pi()), length(e()) ) - length(.) /*calculate max #decimal digs supported*/ -parse arg digs sDigs . 1 . . $ /*obtain optional arguments from the CL*/ -if digs=='' | digs=="," then digs= d /*Not specified? Then use the default.*/ -if sDigs=='' | sDigs=="," then sDigs= d % 2 /* " " " " " " */ -if $='' | $="," then $= 19 43 67 163 /* " " " " " " */ - digs= min( digs, d) /*the minimum decimal digs for calc. */ -sDigs= min(sDigs, d) /* " " " " display.*/ -numeric digits digs /*inform REXX how many dec digs to use.*/ -say "The value of Ramanujan's constant calculated with " d ' decimal digits of precision.' -say "shown with " sDigs ' decimal digits past the decimal point:' +include Settings + +say 'RAMANUJAN''S CONSTANT - 6 Mar 2025' +say version say - do j=1 for words($); #= word($, j) /*process each of the Heegner numbers. */ - say 'When using the Heegner number: ' # /*display which Heegner # is being used*/ - z= exp(pi * sqrt(#) ) /*perform some heavy lifting here. */ - say format(z, 25, sDigs); say /*display a limited amount of dec digs.*/ - end /*j*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -pi: pi= 3.1415926535897932384626433832795028841971693993751058209749445923078164062862, - || 089986280348253421170679821480865132823066470938446095505822317253594081284, - || 8111745028410270193852110555964462294895493038196; return pi -/*──────────────────────────────────────────────────────────────────────────────────────*/ -e: e = 2.7182818284590452353602874713526624977572470936999595749669676277240766303535, - || 475945713821785251664274274663919320030599218174135966290435729003342952605, - || 9563073813232862794349076323382988075319525101901; return e -/*──────────────────────────────────────────────────────────────────────────────────────*/ -exp: procedure; parse arg x; ix= x%1; if abs(x-ix)>.5 then ix= ix + sign(x); x= x-ix - z=1; _=1; w=z; do j=1; _= _*x/j; z=(z+_)/1; if z==w then leave; w=z; end - if z\==0 then z= z * e() ** ix; return z/1 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); h=d+6; numeric digits - numeric form; m.=9; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g*.5'e'_%2 - do j=0 while h>9; m.j=h; h=h % 2 + 1; end /*j*/ - do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g) * .5; end /*k*/; return g +call Formula +call Heegner +exit + +Formula: +call time('r') +say 'Accurate to 100 digits' +numeric digits 100 +say Exp(Pi()*Sqrt(163)) +say Format(Time('e'),,3) 'seconds' +say +return + +Heegner: +call time('r') +say 'Heegner numbers with differences' +numeric digits 33 +h = '19 43 67 163' +do i = 1 to Words(h) + w = Word(h,i); a = Exp(Pi()*Sqrt(w)); b = Round(a,0) + say Right(w,3) Left(a,34) Right(Std(Round(a-b,12)),15) +end +say Format(Time('e'),,3) 'seconds' +return + +include Constants +include Functions +include Abend diff --git a/Task/Ramer-Douglas-Peucker-line-simplification/EasyLang/ramer-douglas-peucker-line-simplification.easy b/Task/Ramer-Douglas-Peucker-line-simplification/EasyLang/ramer-douglas-peucker-line-simplification.easy index a4cc307ca2..0593144c79 100644 --- a/Task/Ramer-Douglas-Peucker-line-simplification/EasyLang/ramer-douglas-peucker-line-simplification.easy +++ b/Task/Ramer-Douglas-Peucker-line-simplification/EasyLang/ramer-douglas-peucker-line-simplification.easy @@ -4,7 +4,7 @@ func perpdist px py p1x p1y p2x p2y . d = sqrt (dx * dx + dy * dy) return abs (px * dy - py * dx + p2x * p1y - p2y * p1x) / d . -proc peucker eps . ptx[] pty[] outx[] outy[] . +proc peucker eps &ptx[] &pty[] &outx[] &outy[] . n = len ptx[] idx = 1 for i = 2 to n - 1 @@ -35,7 +35,7 @@ proc peucker eps . ptx[] pty[] outx[] outy[] . outy[] = [ pty[1] pty[n] ] . . -proc prpts px[] py[] . . +proc prpts px[] py[] . for i to len px[] write "(" & px[i] & " " & py[i] & ") " . diff --git a/Task/Ramer-Douglas-Peucker-line-simplification/Lua/ramer-douglas-peucker-line-simplification.lua b/Task/Ramer-Douglas-Peucker-line-simplification/Lua/ramer-douglas-peucker-line-simplification.lua new file mode 100644 index 0000000000..d860037711 --- /dev/null +++ b/Task/Ramer-Douglas-Peucker-line-simplification/Lua/ramer-douglas-peucker-line-simplification.lua @@ -0,0 +1,92 @@ +local Point = {} +Point.__index = Point + +function Point.new(first, second) + return setmetatable({first=first, second=second}, Point) +end + +local function hypot(...) + local sum = 0 + + for i = 1, select("#", ...) do + local arg = select(i, ...) + sum = sum + arg * arg + end + + return math.sqrt(sum) +end + +local function perpendicularDistance(point, lineStart, lineEnd) + local dx = lineEnd.first - lineStart.first + local dy = lineEnd.second - lineStart.second + + local mag = hypot(dx, dy) + if mag > 0 then + dx = dx / mag + dy = dy / mag + end + + local pvx = point.first - lineStart.first + local pvy = point.second - lineStart.second + + local pvDot = dx * pvx + dy * pvy + + local ax = pvx - pvDot * dx + local ay = pvy - pvDot * dy + + return hypot(ax, ay) +end + +local function simplify(points, epsilon) + local n = #points + if n < 2 then + error("Not enough points to simplify; needs at least 2 points, received " .. n .. " instead") + end + + local dmax = 0 + local index = 1 + + for i = 2, n - 1 do + local d = perpendicularDistance(points[i], points[1], points[n]) + if d > dmax then + index = i + dmax = d + end + end + + if dmax > epsilon then + local recursiveResults = {first={}, second={}} + recursiveResults.first = simplify({table.unpack(points, 1, index)}, epsilon) + recursiveResults.second = simplify({table.unpack(points, index, n)}, epsilon) + local result = {} + + for i = 1, #recursiveResults.first - 1 do + table.insert(result, recursiveResults.first[i]) + end + for i = 1, #recursiveResults.second do + table.insert(result, recursiveResults.second[i]) + end + return result + else + return {points[1], points[n]} + end +end + +local points = { + Point.new(0.0, 0.0), + Point.new(1.0, 0.1), + Point.new(2.0, -0.1), + Point.new(3.0, 5.0), + Point.new(4.0, 6.0), + Point.new(5.0, 7.0), + Point.new(6.0, 8.1), + Point.new(7.0, 9.0), + Point.new(8.0, 9.0), + Point.new(9.0, 9.0) +} + +local result = simplify(points, 1.0) +print("Points remaining after simplification:") +for i, v in ipairs(result) do + print("(" .. v.first .. ", " .. v.second .. ")") +end diff --git a/Task/Ramer-Douglas-Peucker-line-simplification/Modula-2/ramer-douglas-peucker-line-simplification.mod2 b/Task/Ramer-Douglas-Peucker-line-simplification/Modula-2/ramer-douglas-peucker-line-simplification.mod2 new file mode 100644 index 0000000000..c4366eb7d9 --- /dev/null +++ b/Task/Ramer-Douglas-Peucker-line-simplification/Modula-2/ramer-douglas-peucker-line-simplification.mod2 @@ -0,0 +1,100 @@ +MODULE RDPAlgorithm; +(* Ramer-Douglas-Peucker line simplification *) + +FROM STextIO IMPORT + WriteString, WriteLn; +FROM SRealIO IMPORT + WriteFixed; +FROM RealMath IMPORT + sqrt; + +CONST + Len = 10; + +TYPE + TPoint = RECORD + X, Y: LONGREAL; + END; + TPoints = ARRAY [0 .. Len - 1] OF TPoint; + +CONST + PointsIn = TPoints{TPoint{0., 0.}, TPoint{1., 0.1}, TPoint{2., -0.1}, TPoint{3., 5.}, TPoint{4., 6.}, + TPoint{5., 7.}, TPoint{6., 8.1}, TPoint{7., 9.}, TPoint{8., 9.}, TPoint{9., 9.}}; + +VAR + PointsOut: TPoints; + N : CARDINAL; + +PROCEDURE WritePoints(Points: TPoints; N: CARDINAL); +VAR + I: CARDINAL; +BEGIN + WriteString('('); + WriteFixed(Points[0].X, 2, 1); + WriteString(', '); + WriteFixed(Points[0].Y, 2, 1); + WriteString(')'); + FOR I := 1 TO N - 1 DO + WriteString(' ('); + WriteFixed(Points[I].X, 2, 1); + WriteString(', '); + WriteFixed(Points[I].Y, 2, 1); + WriteString(')'); + END; + WriteLn; +END WritePoints; + +(* Returns the distance from point P to the line between P1 and P2 *) +PROCEDURE PerpDist(P, P1, P2: TPoint): LONGREAL; +VAR + DX, DY, D: LONGREAL; +BEGIN + DX := P2.X - P1.X; + DY := P2.Y - P1.Y; + D := sqrt(DX * DX + DY * DY); + RETURN ABS(P.X * DY - P.Y * DX + P2.X * P1.Y - P2.Y * P1.X) / D; +END PerpDist; + +(* Simplify an array of points using the Ramer-Douglas-Peucker algorithm. *) +(* Returns the number of output points. *) +PROCEDURE RDP(Src: TPoints; SrcFrom, SrcLen: CARDINAL; Eps: LONGREAL; + VAR OUT Dest: TPoints; DestFrom, DestLen: CARDINAL): CARDINAL; +VAR + Dist, MaxDist : LONGREAL; + N1, N2, I, MaxDistI, SrcTo: CARDINAL; + Src1Len, Src2Len, Src2From: CARDINAL; +BEGIN + MaxDist := 0.; + MaxDistI := SrcFrom; + SrcTo := SrcFrom + SrcLen - 1; + FOR I := SrcFrom + 1 TO SrcTo - 1 DO + Dist := PerpDist(Src[I], Src[SrcFrom], Src[SrcTo]); + IF Dist >= MaxDist THEN + MaxDist := Dist; + MaxDistI := I + END; + END; + Src2From := MaxDistI; + Src1Len := MaxDistI - SrcFrom + 1; + Src2Len := SrcLen - Src1Len + 1; + IF MaxDist > Eps THEN + N1 := RDP(Src, SrcFrom, Src1Len, Eps, Dest, DestFrom, DestLen); + IF DestLen >= N1 - 1 THEN + N2 := RDP(Src, Src2From, Src2Len, Eps, Dest, DestFrom + N1 - 1, DestLen - N1 + 1) + ELSE + N2 := RDP(Src, Src2From, Src2Len, Eps, Dest, DestFrom, 0) + END; + RETURN N1 + N2 - 1; + ELSE + IF DestLen > 1 THEN + Dest[DestFrom] := Src[SrcFrom]; + Dest[DestFrom + 1] := Src[SrcTo]; + END; + RETURN 2; + END; +END RDP; + +BEGIN + N := RDP(PointsIn, 0, Len, 1.0, PointsOut, 0, Len); + WritePoints(PointsOut, N) +END RDPAlgorithm. diff --git a/Task/Random-Latin-squares/EasyLang/random-latin-squares.easy b/Task/Random-Latin-squares/EasyLang/random-latin-squares.easy index a74a0a47cd..80109447fc 100644 --- a/Task/Random-Latin-squares/EasyLang/random-latin-squares.easy +++ b/Task/Random-Latin-squares/EasyLang/random-latin-squares.easy @@ -1,36 +1,28 @@ -proc shuffle . a[] . +proc shuffle &a[] . for i = len a[] downto 2 r = random i swap a[r] a[i] . . -proc prsquare . lat[][] . +proc prsquare &lat[][] . n = len lat[][] for i to n - for j to n - write lat[i][j] & " " - . + for j to n : write lat[i][j] & " " print "" . print "" . -proc square n . . +proc square n . for i to n lat[][] &= [ ] - for j to n - lat[i][] &= j - . + for j to n : lat[i][] &= j . shuffle lat[1][] for i = 2 to n - 1 repeat shuffle lat[i][] - for k to i - 1 - for j to n - if lat[k][j] = lat[i][j] - break 2 - . - . + for k to i - 1 : for j to n + if lat[k][j] = lat[i][j] : break 2 . until k = i . @@ -38,9 +30,7 @@ proc square n . . len used0[] n for j to n used[] = used0[] - for i to n - 1 - used[lat[i][j]] = 1 - . + for i to n - 1 : used[lat[i][j]] = 1 for k to n if used[k] = 0 lat[n][j] = k diff --git a/Task/Random-number-generator-device-/C/random-number-generator-device--5.c b/Task/Random-number-generator-device-/C/random-number-generator-device--5.c deleted file mode 100644 index e0a8d73ace..0000000000 --- a/Task/Random-number-generator-device-/C/random-number-generator-device--5.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -/* - (C) 2020 J.G.A. Debaere, all rights reserved 2020/10/29 - - Put into Public Domain for individuals only - - Tested with NIST, Diehard, Diehard 3.31 - - gcc -lm ./jpsrand_f.c -o ./jpsrand_f.o - - dieharder -a -f /tmp/tmp.bin - - I consider it TRNG, - - using Time, Hardddisk and Memory as the hardware component - - No warranty of any kind, "AS IS" - - Last time I tested ( 2021/07/07 ) with dieharder: - - rgb_bitdist | 8| 100000| 100|0.99716738| WEAK - rgb_lagged_sum | 3| 1000000| 100|0.99661184| WEAK - - Out of 114 tests, rest PASSED - - Obviously, it changes per run :) - -*/ - -unsigned int jps_rand() -{ - /* (C) 2020 J.G.A. Debaere, all rights reserved */ - - #include - - #include - - struct timeval current_time ; - - DIR *folder ; - - struct dirent *en ; - - folder = opendir ( "." ) ; - - while ( ( folder ) && ( en = readdir ( folder ) ) != NULL ) - - asm ( "nop" ) ; - - closedir ( folder ) ; - - gettimeofday( ¤t_time, NULL ) ; - - unsigned int t = ( current_time.tv_sec * current_time.tv_usec / 17.17 ) ; - - return t ; -} - -int main() -{ - FILE * f1; - - f1 = fopen("/tmp/tmp.bin", "wb"); - - - unsigned int t = ( unsigned int ) jps_rand() ; - - for ( unsigned int k = 0; k < 40000000 ; k++ ) - { - t = jps_rand () ; - - fwrite ( &t, sizeof( unsigned int ), 1, f1 ) ; - } - - fflush(f1); - - fclose(f1); - - return 0; -} diff --git a/Task/Random-number-generator-device-/REXX/random-number-generator-device--1.rexx b/Task/Random-number-generator-device-/REXX/random-number-generator-device--1.rexx deleted file mode 100644 index e21429f519..0000000000 --- a/Task/Random-number-generator-device-/REXX/random-number-generator-device--1.rexx +++ /dev/null @@ -1,5 +0,0 @@ -/*REXX program generates and displays a random 32-bit number using the RANDOM BIF.*/ -numeric digits 10 /*ensure REXX has enough decimal digits*/ -_=2**16 /*a handy─dandy constant to have around*/ -r#= random(0, _-1) * _ + random(0, _-1) /*generate an unsigned 32-bit random #.*/ -say r# /*stick a fork in it, we're all done. */ diff --git a/Task/Random-number-generator-device-/REXX/random-number-generator-device--2.rexx b/Task/Random-number-generator-device-/REXX/random-number-generator-device--2.rexx deleted file mode 100644 index bac32fcf77..0000000000 --- a/Task/Random-number-generator-device-/REXX/random-number-generator-device--2.rexx +++ /dev/null @@ -1,14 +0,0 @@ -left=0 -rite=0 -lo=hex(left)hex(rite) -Say 'low ' c2x(lo) -left=random(0,2**16-1) -rite=random(0,2**16-1) -rand=hex(left)hex(rite) -Say 'random' c2x(rand) -left=2**16-1 -rite=2**16-1 -hi=hex(left)hex(rite) -Say 'high ' c2x(hi) -Exit -hex: Return d2c(arg(1),2) diff --git a/Task/Random-number-generator-device-/REXX/random-number-generator-device-.rexx b/Task/Random-number-generator-device-/REXX/random-number-generator-device-.rexx new file mode 100644 index 0000000000..b0e65ac572 --- /dev/null +++ b/Task/Random-number-generator-device-/REXX/random-number-generator-device-.rexx @@ -0,0 +1,38 @@ +-- 8 May 2025 +include Settings +numeric digits 12 + +say 'RANDOM NUMBER GENERATOR (DEVICE)' +say version +say +call ShowSeed +call Examples +call Timer +exit + +ShowSeed: +procedure +say 'Datetime =' Date('s')||Time('l') +say 'Extract =' ' AABBCCDD EE FF GHI' +d = Date('s') +a = SubStr(d,3,2); b = SubStr(d,5,2); c = SubStr(d,7,2) +t = Time('l') +d = SubStr(t,1,2); e = SubStr(t,4,2); f = SubStr(t,7,2) +g = SubStr(t,10,1); h = SubStr(t,11,1); i = SubStr(t,12,1) +say 'Seed =' h||f||d||b||a||c||e||g||i '= HFFDDBBAACCEEGI' +say +return + +Examples: +procedure expose glob. +say 'Randu() = ' Right(Randu(),14) 'Real, uniform distributed over (0,1)' +say 'Randu(100) = ' Right(Randu(100),14) 'Integer, between 0 and 100' +say 'Randu(-10,10) = ' Right(Randu(-10,10),14) 'Integer, between -10 and 10' +say 'Randn() = ' Right(Randn(),14) 'Real, normal distributed, average 0 and deviation 1' +say +return + +include Functions +include Constants +include Helper +include Abend diff --git a/Task/Random-number-generator-included-/REXX/random-number-generator-included--3.rexx b/Task/Random-number-generator-included-/REXX/random-number-generator-included--3.rexx index eaa4405d0f..46ed58973d 100644 --- a/Task/Random-number-generator-included-/REXX/random-number-generator-included--3.rexx +++ b/Task/Random-number-generator-included-/REXX/random-number-generator-included--3.rexx @@ -3,6 +3,8 @@ * Please add the output from other REXXes * 10.09.2013 Walter Pachl added REXX/TSO * 01.08.2014 Walter Pachl show what ooRexx supports +* 03.05.2025 Zeddicus added REXX/2 +* 08.05.2025 Zeddicus added ooRexx 5.1 **********************************************************************/ Parse Version v Call random ,,44 diff --git a/Task/Random-numbers/EasyLang/random-numbers.easy b/Task/Random-numbers/EasyLang/random-numbers.easy index e37e3b167d..04a06a4a79 100644 --- a/Task/Random-numbers/EasyLang/random-numbers.easy +++ b/Task/Random-numbers/EasyLang/random-numbers.easy @@ -1,4 +1,4 @@ -numfmt 5 0 +numfmt 0 5 e = 2.7182818284590452354 for i = 1 to 1000 a[] &= 1 + 0.5 * sqrt (-2 * log10 randomf / log10 e) * cos (360 * randomf) diff --git a/Task/Random-numbers/REXX/random-numbers.rexx b/Task/Random-numbers/REXX/random-numbers.rexx index e36ea6b97b..cfd8734f63 100644 --- a/Task/Random-numbers/REXX/random-numbers.rexx +++ b/Task/Random-numbers/REXX/random-numbers.rexx @@ -1,45 +1,87 @@ -/*REXX pgm generates 1,000 normally distributed numbers: mean=1, standard deviation=½.*/ -numeric digits 20 /*the default decimal digit precision=9*/ -parse arg n seed . /*allow specification of N and the seed*/ -if n=='' | n=="," then n=1000 /*N: is the size of the array. */ -if datatype(seed,'W') then call random ,,seed /*SEED: for repeatable random numbers. */ -newMean=1 /*the desired new mean (arithmetic avg)*/ -sd=1/2 /*the desired new standard deviation. */ - do g=1 for n /*generate N uniform random #'s (0,1].*/ - #.g = random(1, 1e5) / 1e5 /*REXX's RANDOM BIF generates integers.*/ - end /*g*/ /* [↑] random integers ──► fractions. */ -say ' old mean=' mean() -say 'old standard deviation=' stdDev() -call pi; pi2=pi * 2 /*define pi and also 2 * pi. */ +-- 8 May 2025 +include Settings + +say 'RANDOM NUMBERS' +say version say - do j=1 to n-1 by 2; m=j+1 /*step through the iterations by two. */ - _=sd * sqrt(ln(#.j) * -2) /*calculate the used-twice expression.*/ - #.j=_ * cos(pi2 * #.m) + newMean /*utilize the Box─Muller method. */ - #.m=_ * sin(pi2 * #.m) + newMean /*random number must be: (0,1] */ - end /*j*/ -say ' new mean=' mean() -say 'new standard deviation=' stdDev() -exit /*stick a fork in it, we're all done. */ -/*───────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/ -mean: _=0; do k=1 for n; _=_ + #.k; end; return _/n -stdDev: _avg=mean(); _=0; do k=1 for n; _=_ + (#.k - _avg)**2; end; return sqrt(_/n) -e: e =2.7182818284590452353602874713526624977572470936999595749669676277240766303535; return e /*digs overkill*/ -pi: pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862; return pi /* " " */ -r2r: return arg(1) // (pi() * 2) /*normalize ang*/ -sin: procedure; parse arg x;x=r2r(x);numeric fuzz min(5,digits()-3);if abs(x)=pi then return 0;return .sincos(x,x,1) -.sincos:parse arg z,_,i; x=x*x; p=z; do k=2 by 2; _=-_*x/(k*(k+i)); z=z+_; if z=p then leave; p=z; end; return z -/*───────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/ -ln: procedure; parse arg x,f; call e; ig= x>1.5; is=1 - 2 * (ig\==1); ii=0; xx=x - do while ig&xx>1.5|\ig&xx<.5;_=e;do k=-1;iz=xx*_**-is;if k>=0&(ig&iz<1|\ig&iz>.5) then leave;_=_*_;izz=iz;end - xx=izz;ii=ii+is*2**k;end;x=x*e**-ii-1;z=0;_=-1;p=z;do k=1;_=-_*x;z=z+_/k;if z=p then leave;p=z;end; return z+ii -/*───────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/ -cos: procedure; parse arg x; x=r2r(x); a=abs(x); hpi=pi * .5 - numeric fuzz min(6, digits() - 3); if a=pi then return -1 - if a=hpi | a=hpi*3 then return 0; if a=pi/3 then return .5 - if a=pi * 2/3 then return -.5; return .sinCos(1,1,-1) -/*───────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/ -sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); numeric digits; h=d+6 - numeric form; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g * .5'e'_ %2 - m.=9; do j=0 while h>9; m.j=h; h=h%2 + 1; end /*j*/ - do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/ - numeric digits d; return g/1 +call GetUniform 1e3 +call ShowFirst +call ShowStats +call ShowExact +call GetNormal 1e3 +call ShowFirst +call ShowStats +call GetUniform 1e6 +call ShowStats +call GetNormal 1e6 +call ShowStats +call Timer +exit + +GetUniform: +procedure expose glob. work. +arg xx +say 'Get' xx 'uniform distributed Random numbers...' +work. = 0 +do n = 1 to xx + work.n = Randu() +end +work.0 = xx +say 'Done' +say +return + +GetNormal: +procedure expose glob. work. +arg xx +say 'Get' xx 'normal(1,1/2) distributed Random numbers...' +work. = 0 +do n = 1 to xx + work.n = Randn(1,0.5) +end +work.0 = xx +say 'Done' +say +return + +ShowFirst: +procedure expose work. +say 'First 5 items...' +do i = 1 to 5 + call CharOut ,work.i/1' ' +end +say; say +return + +ShowStats: +procedure expose work. +say 'Statistics for' work.0 'items...' +sum = 0 +do n = 1 to work.0 + sum = sum+work.n +end +avg = sum/work.0 +sum = 0 +do n = 1 to work.0 + sum = sum+(work.n-avg)**2 +end +varia = sum/work.0; stdev = SqRt(varia)/1 +say 'Average ' Std(avg) +say 'Deviation' Std(stdev) +say 'Variance ' Std(varia) +say +return + +ShowExact: +procedure expose work. +say 'Exact statistics for infinite items...' +say 'Average ' 1/2 '(1/2)' +say 'Deviation' Std(SqRt(1/12)) '(SqRt(1/12))' +say 'Variance ' 1/12 '(1/12)' +say +return + +include Functions +include Constants +include Helper +include Abend diff --git a/Task/Random-sentence-from-book/ALGOL-68/random-sentence-from-book-1.alg b/Task/Random-sentence-from-book/ALGOL-68/random-sentence-from-book-1.alg index ddfb46e79b..ec203f1daa 100644 --- a/Task/Random-sentence-from-book/ALGOL-68/random-sentence-from-book-1.alg +++ b/Task/Random-sentence-from-book/ALGOL-68/random-sentence-from-book-1.alg @@ -58,7 +58,7 @@ OD; # delimiter for separating suffixes - must not appear in the text # CHAR suffix delimiter = REPR 1; # ^A # -STRING punctuation = """'@,/;:(){}[]*&^%$£"; +STRING punctuation = """'@,/;:(){}[]*&^%$"; # NB: exclude " " # IF FILE input file; open( input file, file name, stand in channel ) /= 0 @@ -239,8 +239,9 @@ ELSE finished := TRUE; # if the line ends with ",;:", remove it # INT line end := UPB line; - IF CHAR c = line[ line end ]; c = "," OR c = ";" OR c = ":" THEN - line end -:= 1 + IF CHAR end ch = line[ line end ]; + end ch = "," OR end ch = ";" OR end ch = ":" + THEN line end -:= 1 FI; # remove trailing spaces # WHILE line[ line end ] = " " AND line end > LWB line DO line end -:= 1 OD; diff --git a/Task/Range-consolidation/EasyLang/range-consolidation.easy b/Task/Range-consolidation/EasyLang/range-consolidation.easy index bbc21cb955..00151dbf97 100644 --- a/Task/Range-consolidation/EasyLang/range-consolidation.easy +++ b/Task/Range-consolidation/EasyLang/range-consolidation.easy @@ -1,18 +1,12 @@ -proc sort . d[][] . +proc sort &d[][] . n = len d[][] - for i = 1 to n - 1 - for j = i + 1 to n - if d[j][1] < d[i][1] - swap d[j][] d[i][] - . - . + for i = 1 to n - 1 : for j = i + 1 to n + if d[j][1] < d[i][1] : swap d[j][] d[i][] . . func[][] consolidate a[][] . for i to len a[][] - if a[i][1] > a[i][2] - swap a[i][1] a[i][2] - . + if a[i][1] > a[i][2] : swap a[i][1] a[i][2] . sort a[][] r[][] &= a[1][] diff --git a/Task/Rare-numbers/Rust/rare-numbers.rs b/Task/Rare-numbers/Rust/rare-numbers.rs index 5ab3a63054..8bcb1555ac 100644 --- a/Task/Rare-numbers/Rust/rare-numbers.rs +++ b/Task/Rare-numbers/Rust/rare-numbers.rs @@ -222,27 +222,22 @@ fn advanced(digit: u8) -> Vec { // create a cartesian product for all potential diff numbers // for the first use the very short one, for all other the complete 19 element let diff_list_iter = (0_u8..(d / 2)) - .map(|i| match i { - 0 => diffs1.iter(), - _ => all_diffs.iter(), - }) - .multi_cartesian_product() - // remove invalid first diff/second diff combinations - custom iterator would be probably better - .filter(|x| { - if x.len() == 1 { - return true; - } - match (*x[0], *x[1]) { - (a, b) if (a == 0 && b != 0) => false, - (a, b) if (a == 1 && ![-7, -5, -3, -1, 1, 3, 5, 7].contains(&b)) => false, - (a, b) if (a == 4 && ![-8, -6, -4, -2, 0, 2, 4, 6, 8].contains(&b)) => false, - (a, b) if (a == 5 && ![7, -3].contains(&b)) => false, - (a, b) if (a == 6 && ![-9, -7, -5, -3, -1, 1, 3, 5, 7, 9].contains(&b)) => { - false - } - _ => true, - } - }); + .map(|i| match i { + 0 => diffs1.iter(), + _ => all_diffs.iter(), + }) + .multi_cartesian_product() + // remove invalid first diff/second diff combinations - custom iterator would be probably better + .filter(|x| { + match x[..] { + [&a, &b] if a == 0 && b != 0 => false, + [&a, b] if a == 1 && ![-7, -5, -3, -1, 1, 3, 5, 7].contains(b) => false, + [&a, b] if a == 4 && ![-8, -6, -4, -2, 0, 2, 4, 6, 8].contains(b) => false, + [&a, b] if a == 5 && ![7, -3].contains(b) => false, + [&a, b] if a == 6 && ![-9, -7, -5, -3, -1, 1, 3, 5, 7, 9].contains(b) => false, + _ => true, + } + }); #[cfg(debug_assertions)] { diff --git a/Task/Rate-counter/EasyLang/rate-counter.easy b/Task/Rate-counter/EasyLang/rate-counter.easy index 2123abcfcc..560ba46e1c 100644 --- a/Task/Rate-counter/EasyLang/rate-counter.easy +++ b/Task/Rate-counter/EasyLang/rate-counter.easy @@ -1,15 +1,15 @@ -color 700 -d = 0.2 -t0 = systime -on animate - clear - rad += d - move 50 50 - circle rad - if rad > 50 or rad < 0 - d = -d +fastfunc isprim num . + if num mod 2 = 0 and num > 2 : return 0 + i = 3 + while i <= sqrt num + if num mod i = 0 : return 0 + i += 2 . - t = systime - print 1000 * (t - t0) & " ms" - t0 = t + return 1 +. +for i to 5 + t0 = systime + h = isprim 9005099254741061 + h = h + print (systime - t0) * 1000 & " ms" . diff --git a/Task/Read-a-configuration-file/XPL0/read-a-configuration-file.xpl0 b/Task/Read-a-configuration-file/XPL0/read-a-configuration-file.xpl0 new file mode 100644 index 0000000000..4da6db65d6 --- /dev/null +++ b/Task/Read-a-configuration-file/XPL0/read-a-configuration-file.xpl0 @@ -0,0 +1,56 @@ +string 0; \use zero-terminated strings +proc StrIn(Str); \Read alphanumeric string from input file +char Str; +int I, C; +[I:= 0; +loop [C:= ChIn(3); + if C<$20 or C=^, then quit; + Str(I):= C; I:= I+1; + ]; +Str(I):= 0; +]; + +char FullName(100), FavoriteFruit(100), OtherFamily(2, 100); +int NeedsPeeling, SeedsRemoved; +int C; +[NeedsPeeling:= false; SeedsRemoved:= false; +FullName(0):= 0; FavoriteFruit(0):= 0; +OtherFamily(0, 0):= 0; OtherFamily(1, 0):= 0; + +FSet(FOpen("configfile.txt", 0), ^i); +OpenI(3); +C:= ChIn(3); +while C # $1A \EOF\ do + [if C = $0A \LF\ then + [C:= ChIn(3); + if C = ^N then NeedsPeeling:= true; + if C = ^O then + [repeat C:= ChIn(3) until C <= $20; + StrIn(@OtherFamily(0, 0)); + C:= ChIn(3); + StrIn(@OtherFamily(1, 0)); + ]; + if C = ^F then + [C:= ChIn(3); + if C = ^U then + [repeat C:= ChIn(3) until C <= $20; + StrIn(FullName); + ]; + if C = ^A then + [repeat C:= ChIn(3) until C <= $20; + StrIn(FavoriteFruit); + ]; + ]; + ] + else C:= ChIn(3); + ]; +Text(0, "Full name: "); Text(0, FullName); CrLf(0); +Text(0, "Favorite fruit: "); Text(0, FavoriteFruit); CrLf(0); +Text(0, "Needs peeling: "); Text(0, if NeedsPeeling then "true" else "false"); +CrLf(0); +Text(0, "Seeds removed: "); Text(0, if SeedsRemoved then "true" else "false"); +CrLf(0); +Text(0, "Other family: "); Text(0, @OtherFamily(0, 0)); +Text(0, ", "); Text(0, @OtherFamily(1, 0)); +CrLf(0); +] diff --git a/Task/Read-entire-file/OoRexx/read-entire-file-1.rexx b/Task/Read-entire-file/OoRexx/read-entire-file-1.rexx index 52d0d081be..e179d2ba96 100644 --- a/Task/Read-entire-file/OoRexx/read-entire-file-1.rexx +++ b/Task/Read-entire-file/OoRexx/read-entire-file-1.rexx @@ -1,3 +1,8 @@ -file = 'c:\test.txt' -myStream = .stream~new(file) -myString = myStream~charIn(,myStream~chars) +o=.stream~new('f:\readall.rex') +a=o~arrayin +Do x over a + say x + End +Do i=1 To a~items + Say i a[i] + End diff --git a/Task/Read-entire-file/OoRexx/read-entire-file-2.rexx b/Task/Read-entire-file/OoRexx/read-entire-file-2.rexx index e20079bcee..52d0d081be 100644 --- a/Task/Read-entire-file/OoRexx/read-entire-file-2.rexx +++ b/Task/Read-entire-file/OoRexx/read-entire-file-2.rexx @@ -1,7 +1,3 @@ file = 'c:\test.txt' myStream = .stream~new(file) -if mystream~open('read') = 'READY:' -then do - myString = myStream~charIn(,myStream~chars) - myStream~close -end +myString = myStream~charIn(,myStream~chars) diff --git a/Task/Read-entire-file/OoRexx/read-entire-file-3.rexx b/Task/Read-entire-file/OoRexx/read-entire-file-3.rexx index 0c745d4375..e20079bcee 100644 --- a/Task/Read-entire-file/OoRexx/read-entire-file-3.rexx +++ b/Task/Read-entire-file/OoRexx/read-entire-file-3.rexx @@ -1,9 +1,7 @@ -address hostemu 'execio * diskr "./st.in" (finis stem in.' -Say in.0 'lines in file st.in' -v='' -Do i=1 To in.0 - Say i '>'in.i'<' - v=v||in.i - End -say 'v='v -::requires "hostemu" LIBRARY +file = 'c:\test.txt' +myStream = .stream~new(file) +if mystream~open('read') = 'READY:' +then do + myString = myStream~charIn(,myStream~chars) + myStream~close +end diff --git a/Task/Read-entire-file/OoRexx/read-entire-file-4.rexx b/Task/Read-entire-file/OoRexx/read-entire-file-4.rexx new file mode 100644 index 0000000000..0c745d4375 --- /dev/null +++ b/Task/Read-entire-file/OoRexx/read-entire-file-4.rexx @@ -0,0 +1,9 @@ +address hostemu 'execio * diskr "./st.in" (finis stem in.' +Say in.0 'lines in file st.in' +v='' +Do i=1 To in.0 + Say i '>'in.i'<' + v=v||in.i + End +say 'v='v +::requires "hostemu" LIBRARY diff --git a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-3.rexx b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-3.rexx index 38feb02eeb..abb4b2d2f1 100644 --- a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-3.rexx +++ b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-3.rexx @@ -1 +1,27 @@ -ceiling: procedure; parse arg x; t=trunc(x); return t+(x>0)*(x\=t) +numeric digits ddd /*sets the current precision to DDD */ +numeric fuzz fff /*arithmetic comparisons with FFF fuzzy*/ +numeric form kkk /*exponential: scientific | engineering*/ + +low=min(a,b,c,d,e,f,g, ...) /*finds the min of specified arguments.*/ +big=min(a,b,c,d,e,f,g, ...) /*finds the max of specified arguments.*/ + +rrr=random(low,high) /*gets a random integer from LOW-->HIGH*/ +arr=random(low,high,seed) /* ... with a seed (to make repeatable)*/ + +mzp=sign(x) /*finds the sign of x (-1, 0, +1). */ + + fs=format(x) /*formats X with the current DIGITS() */ + fb=format(x,bbb) /* BBB digs before decimal*/ + fa=format(x,bbb,aaa) /* AAA digs after decimal*/ + fa=format(x,,0) /* rounds X to an integer.*/ + fe=format(x,,eee) /* exponent has eee places. */ + ft=format(x,,eee,ttt) /*if x exceeds TTT digits, force exp. */ + +hh=b2x(bbb) /*converts binary/bits to hexadecimal. */ +dd=c2d(ccc) /*converts character to decimal. */ +hh=c2x(ccc) /*converts character to hexadecimal. */ +cc=d2c(ddd) /*converts decimal to character. */ +hh=d2x(ddd) /*converts decimal to hexadecimal. */ +bb=x2b(hhh) /*converts hexadecimal to binary (bits)*/ +cc=x2c(hhh) /*converts hexadecimal to character. */ +dd=x2d(hhh) /*converts hexadecimal to decimal. */ diff --git a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-4.rexx b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-4.rexx index 794b93d5b4..c1c062a192 100644 --- a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-4.rexx +++ b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-4.rexx @@ -1 +1,21 @@ -floor: procedure; parse arg x; t=trunc(x); return t-(x<0)-(x\=t) +include Settings + +say 'REAL CONSTANTS AND FUNCTIONS - 2 Mar 2025' +say version +say +numeric digits 16 +say 'e =' e()+0 +say 'pi =' pi()+0 +say 'square root 7 =' sqrt(7)+0 +say 'log 7 base e =' log(7)+0 +say 'log 7 base 10 =' log10(7)+0 +say 'log 7 base 2 =' logxy(7,2)+0 +say 'exponential 7 =' exp(7)+0 +say '1/2^3/4 =' power(1/2,3/4)+0 +say 'floor 4/3 =' floor(4/3) +say 'ceiling 4/3 =' ceil(4/3) +exit + +include Functions +include Constants +include Abend diff --git a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-5.rexx b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-5.rexx deleted file mode 100644 index 60530b123b..0000000000 --- a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-5.rexx +++ /dev/null @@ -1,27 +0,0 @@ -/*──────────────────────────────────SQRT subroutine───────────────────────────*/ -sqrt: procedure; parse arg x; if x=0 then return 0 /*handle 0 case.*/ -if \datatype(x,'N') then return '[n/a]' /*Not Applicable ───if not numeric.*/ -i=; if x<0 then do; x=-x; i='i'; end /*handle complex numbers if X is < 0.*/ -d=digits() /*get the current numeric precision. */ -m.=9 /*technique uses just enough digits. */ -h=d+6 /*use extra decimal digits for accuracy*/ -numeric digits 9 /*use "small" precision at first. */ -numeric form /*force scientific form of the number. */ -if fuzz()\==0 then numeric fuzz 0 /*just in case invoker has a FUZZ set.*/ -parse value format(x,2,1,,0) 'E0' with g 'E' _ . /*get the X's exponent.*/ - g=(g * .5) || 'e' || (_ % 2) /*1st guesstimate for the square root. */ - /* g= g * .5 'e' (_ % 2) */ /*a shorter & concise version of above.*/ - /*Note: to insure enough accuracy for */ - /* the result, the precision during */ - /* the SQRT calculations is increased */ - /* by two extra decimal digits. */ - do j=0 while h>9; m.j=h; h=h%2+1 /*compute the sizes (digs) of precision*/ - end /*j*/ /* [↑] precisions are stored in M. */ - /*now, we start to do the heavy lifting*/ - do k=j+5 to 0 by -1 /*compute the √ with increasing digs.*/ - numeric digits m.k /*each iteration, increase the digits. */ - g=(g+x/g) * .5 /*perform the nitty-gritty calculations*/ - end /*k*/ /* [↑] * .5 is faster than / 2 */ - /* [↓] normalize √ ──► original digits*/ -numeric digits d /* [↓] make answer complex if X < 0. */ -return (g/1)i /*normalize, and add possible I suffix.*/ diff --git a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-6.rexx b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-6.rexx deleted file mode 100644 index 1ac457905c..0000000000 --- a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-6.rexx +++ /dev/null @@ -1,26 +0,0 @@ - ╔════════════════════════════════════════════════════════════════════╗ -╔═╝ __ ╚═╗ -║ √ ║ -║ ║ -║ While the above REXX code seems like it's doing a lot of extra work, ║ -║ it saves a substantial amount of processing time when the precision ║ -║ (DIGITs) is a lot greater than the default (default is nine digits). ║ -║ ║ -║ Indeed, when computing square roots in the hundreds (even thousands) ║ -║ of digits, this technique reduces the amount of CPU processing time ║ -║ by keeping the length of the computations to a minimum (due to a large ║ -║ precision), while the accuracy at the beginning isn't important for ║ -║ calculating the (first) guesstimate (the running square root guess). ║ -║ ║ -║ Each iteration of K (approximately) doubles the number of digits, ║ -║ but takes almost four times longer to compute (actually, around 3.8). ║ -║ ║ -║ The REXX code could be streamlined (pruned) by removing the ║ -║ The NUMERIC FUZZ 0 statement can be removed if it is known ║ -║ that it is already set to zero. (which is the default). ║ -║ ║ -║ Also, the NUMERIC FORM statement can be removed if it is known ║ -║ that the form is SCIENTIFIC (which is the default). ║ -║ __ ║ -╚═╗ √ ╔═╝ - ╚════════════════════════════════════════════════════════════════════╝ diff --git a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-7.rexx b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-7.rexx deleted file mode 100644 index 6d3d413b63..0000000000 --- a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-7.rexx +++ /dev/null @@ -1,14 +0,0 @@ -/*──────────────────────────────────SQRT subroutine─────────────────────*/ -sqrt: procedure; arg x /*a simplistic SQRT subroutine.*/ -if x=0 then return 0 /*handle special case of zero. */ -d=digits() /*get the current precision (dig)*/ -numeric digits d+2 /*ensure extra precision (2 digs)*/ -g=x/4 /*try get a so-so 1st guesstimate*/ -old=0 /*set OLD guess to zero. */ - do forever /*keep at it 'til G (guess)=old.*/ - g=(g+x/g) / 2 /*do the nitty-gritty calculation*/ - if g=old then leave /*if G is the same as old, quit. */ - old=g /*save OLD for next iteration. */ - end /*forever*/ /* [↑] ···'til we run out of digs*/ -numeric digits d /*restore the original precision.*/ -return g/1 /*normalize to old precision (d).*/ diff --git a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-8.rexx b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-8.rexx deleted file mode 100644 index abb4b2d2f1..0000000000 --- a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-8.rexx +++ /dev/null @@ -1,27 +0,0 @@ -numeric digits ddd /*sets the current precision to DDD */ -numeric fuzz fff /*arithmetic comparisons with FFF fuzzy*/ -numeric form kkk /*exponential: scientific | engineering*/ - -low=min(a,b,c,d,e,f,g, ...) /*finds the min of specified arguments.*/ -big=min(a,b,c,d,e,f,g, ...) /*finds the max of specified arguments.*/ - -rrr=random(low,high) /*gets a random integer from LOW-->HIGH*/ -arr=random(low,high,seed) /* ... with a seed (to make repeatable)*/ - -mzp=sign(x) /*finds the sign of x (-1, 0, +1). */ - - fs=format(x) /*formats X with the current DIGITS() */ - fb=format(x,bbb) /* BBB digs before decimal*/ - fa=format(x,bbb,aaa) /* AAA digs after decimal*/ - fa=format(x,,0) /* rounds X to an integer.*/ - fe=format(x,,eee) /* exponent has eee places. */ - ft=format(x,,eee,ttt) /*if x exceeds TTT digits, force exp. */ - -hh=b2x(bbb) /*converts binary/bits to hexadecimal. */ -dd=c2d(ccc) /*converts character to decimal. */ -hh=c2x(ccc) /*converts character to hexadecimal. */ -cc=d2c(ddd) /*converts decimal to character. */ -hh=d2x(ddd) /*converts decimal to hexadecimal. */ -bb=x2b(hhh) /*converts hexadecimal to binary (bits)*/ -cc=x2c(hhh) /*converts hexadecimal to character. */ -dd=x2d(hhh) /*converts hexadecimal to decimal. */ diff --git a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-9.rexx b/Task/Real-constants-and-functions/REXX/real-constants-and-functions-9.rexx deleted file mode 100644 index 7fc4460e78..0000000000 --- a/Task/Real-constants-and-functions/REXX/real-constants-and-functions-9.rexx +++ /dev/null @@ -1,19 +0,0 @@ -include Settings - -say version; say 'Real constants and functions'; say -numeric digits 16 -say 'e =' e()+0 -say 'pi =' pi()+0 -say 'square root 7 =' sqrt(7)+0 -say 'log 7 base e =' log(7)+0 -say 'log 7 base 10 =' log10(7)+0 -say 'log 7 base 2 =' logxy(7,2)+0 -say 'exponential 7 =' exp(7)+0 -say '1/2^3/4 =' power(1/2,3/4)+0 -say 'floor 4/3 =' floor(4/3) -say 'ceiling 4/3 =' ceil(4/3) -exit - -include Functions -include Constants -include Abend diff --git a/Task/Reduced-row-echelon-form/EasyLang/reduced-row-echelon-form.easy b/Task/Reduced-row-echelon-form/EasyLang/reduced-row-echelon-form.easy index a3ff68820f..1a33b89a0a 100644 --- a/Task/Reduced-row-echelon-form/EasyLang/reduced-row-echelon-form.easy +++ b/Task/Reduced-row-echelon-form/EasyLang/reduced-row-echelon-form.easy @@ -1,33 +1,25 @@ -proc rref . m[][] . +proc rref &m[][] . nrow = len m[][] ncol = len m[1][] lead = 1 for r to nrow - if lead > ncol - return - . + if lead > ncol : return i = r while m[i][lead] = 0 i += 1 if i > nrow i = r lead += 1 - if lead > ncol - return - . + if lead > ncol : return . . swap m[i][] m[r][] m = m[r][lead] - for k to ncol - m[r][k] /= m - . + for k to ncol : m[r][k] /= m for i to nrow if i <> r m = m[i][lead] - for k to ncol - m[i][k] -= m * m[r][k] - . + for k to ncol : m[i][k] -= m * m[r][k] . . lead += 1 diff --git a/Task/Reflection-Get-source/C-sharp/reflection-get-source.cs b/Task/Reflection-Get-source/C-sharp/reflection-get-source.cs new file mode 100644 index 0000000000..c83560b942 --- /dev/null +++ b/Task/Reflection-Get-source/C-sharp/reflection-get-source.cs @@ -0,0 +1 @@ +Console.WriteLine(new System.Diagnostics.StackTrace(true).GetFrame(0)); diff --git a/Task/Rendezvous/Rust/rendezvous.rs b/Task/Rendezvous/Rust/rendezvous.rs new file mode 100644 index 0000000000..1d6a34d05c --- /dev/null +++ b/Task/Rendezvous/Rust/rendezvous.rs @@ -0,0 +1,207 @@ +use std::error::Error; +use std::fmt; +use std::sync::{Arc, Mutex, Condvar}; +use std::thread; +use std::time::Duration; // Only for potential debug sleeps, not strictly needed for logic + +// --- Custom Error Type --- +#[derive(Debug)] +struct OutOfInkError; + +impl fmt::Display for OutOfInkError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Printer out of ink") + } +} + +impl Error for OutOfInkError {} + +// --- Printer Struct --- +#[derive(Debug, Clone, PartialEq)] // Add traits for comparison, debugging, and cloning +struct Printer { + name: String, + client_ink_level: u32, +} + +impl Printer { + fn new(name: &str, ink_level: u32) -> Self { + Printer { + name: name.to_string(), + client_ink_level: ink_level, + } + } +} + +// --- Shared State Struct --- +// Group all shared mutable data together +struct SharedState { + printer: Printer, + primary_printer_config: Printer, // Keep original config separate + reserve_printer_config: Printer, // Keep original config separate + goose_working: bool, + humpty_working: bool, + turn: u32, +} + +// --- Display Function --- +// Takes a mutable reference to the shared state +// Returns Result to indicate success or OutOfInkError +fn display(state: &mut SharedState, text: &str) -> Result<(), OutOfInkError> { + // Check if primary is out and switch to reserve if needed + if state.printer == state.primary_printer_config && state.printer.client_ink_level == 0 { + println!(" Switching to Reserve printer"); + state.printer = state.reserve_printer_config.clone(); // Use cloned config + } + + // Attempt to print + if state.printer.client_ink_level > 0 { + state.printer.client_ink_level -= 1; + println!("({}) {}", state.printer.name, text); + Ok(()) + } else { + println!(" Printer out of ink"); + Err(OutOfInkError) + } +} + +// --- Messenger Logic --- +// Takes Arc clones for shared data +fn messenger( + message: Vec, + my_turn: u32, + turn_count: u32, + state_sync: Arc<(Mutex, Condvar)>, // Tuple of Mutex and Condvar + worker_name: String, // For identifying which worker finished +) { + let (lock, cvar) = &*state_sync; // Destructure the tuple + let mut index: usize = 0; + + // Loop as long as *any* worker is potentially active + // We re-check specific worker status inside the lock + loop { + // Acquire the lock. The MutexGuard 'state' is automatically released when it goes out of scope + let mut state = lock.lock().expect("Mutex lock failed"); + + // Wait while it's not our turn AND at least one worker is still supposed to be working + // The wait_while unlocks the mutex and re-acquires it upon waking up + state = cvar.wait_while(state, |s| { + // Predicate: Keep waiting if... + s.turn % turn_count != my_turn // it's not our turn + && (s.goose_working || s.humpty_working) // AND someone is still working (prevents deadlock if other thread finishes) + }).expect("Condition variable wait failed"); + + + // Check if *all* work is done *after* waking up or if we didn't need to wait + if !state.goose_working && !state.humpty_working { + // println!("{} sees both workers finished, exiting.", worker_name); // Debug + break; // Exit the loop + } + + // Check if *this specific worker* should still be working + let should_be_working = if my_turn == 0 { state.goose_working } else { state.humpty_working }; + + if !should_be_working { + // This worker finished its text or an error occurred previously. + // It needs to potentially wake up the *other* worker if it's waiting. + // println!("{} sees it shouldn't be working, notifying and breaking.", worker_name); // Debug + // We still increment the turn and notify to potentially unblock the other thread + // if it's waiting for its turn number, even if it will also exit soon. + state.turn += 1; + cvar.notify_one(); + break; // Exit the loop + } + + + // --- Perform Work --- + if index < message.len() { + match display(&mut state, &message[index]) { + Ok(()) => { + index += 1; + } + Err(_) => { + // Out of ink! Stop both workers. + println!(" Error detected by {}, stopping all work.", worker_name); + state.goose_working = false; + state.humpty_working = false; + // No break here yet, let the loop condition handle exit naturally after notification + } + } + } else { + // This worker finished its message + // println!("{} finished text.", worker_name); // Debug + if my_turn == 0 { + state.goose_working = false; + } else { + state.humpty_working = false; + } + } + + // Increment turn and notify the *next* worker + state.turn += 1; + //println!("{} finished turn, new turn {}. Notifying.", worker_name, state.turn); // Debug + cvar.notify_one(); + + // MutexGuard 'state' is dropped here, releasing the lock + } + //println!("{} thread finished.", worker_name); // Debug +} + + +fn main() { + let goose_text: Vec = [ + "Old Mother Goose,", + "When she wanted to wander,", + "Would ride through the air,", + "On a very fine gander.", + "Jack's mother came in,", + "And caught the goose soon,", + "And mounting its back,", + "Flew up to the moon.", + ] + .iter() + .map(|s| s.to_string()) + .collect(); + + let humpty_text: Vec = [ + "Humpty Dumpty sat on a wall.", + "Humpty Dumpty had a great fall.", + "All the king's horses and all the king's men,", + "Couldn't put Humpty together again.", + ] + .iter() + .map(|s| s.to_string()) + .collect(); + + // --- Initial State Setup --- + let primary = Printer::new("Primary", 5); + let reserve = Printer::new("Reserve", 5); + + let initial_state = SharedState { + printer: primary.clone(), // Start with primary + primary_printer_config: primary, // Store config + reserve_printer_config: reserve, // Store config + goose_working: true, + humpty_working: true, + turn: 0, + }; + + // Wrap state and condvar in Arc for shared ownership + let state_sync = Arc::new((Mutex::new(initial_state), Condvar::new())); + + // --- Spawn Threads --- + let state_sync_goose = Arc::clone(&state_sync); + let goose_thread = thread::spawn(move || { + messenger(goose_text, 0, 2, state_sync_goose, "Goose".to_string()); + }); + + let state_sync_humpty = Arc::clone(&state_sync); + let humpty_thread = thread::spawn(move || { + messenger(humpty_text, 1, 2, state_sync_humpty, "Humpty".to_string()); + }); + + // --- Wait for Threads to Finish --- + goose_thread.join().expect("Goose thread panicked"); + humpty_thread.join().expect("Humpty thread panicked"); + + println!("Both threads finished."); +} diff --git a/Task/Repeat-a-string/Excel/repeat-a-string.excel b/Task/Repeat-a-string/Excel/repeat-a-string.excel new file mode 100644 index 0000000000..5164862aac --- /dev/null +++ b/Task/Repeat-a-string/Excel/repeat-a-string.excel @@ -0,0 +1 @@ +=REPT("ha", 5) diff --git a/Task/Resistor-mesh/Rust/resistor-mesh.rs b/Task/Resistor-mesh/Rust/resistor-mesh.rs new file mode 100644 index 0000000000..2f02a22c66 --- /dev/null +++ b/Task/Resistor-mesh/Rust/resistor-mesh.rs @@ -0,0 +1,133 @@ +use std::fmt; + +#[derive(Clone, Copy)] +struct Node { + v: f64, + fixed: i32, +} + +impl Node { + fn new() -> Self { + Node { v: 0.0, fixed: 0 } + } + + fn new_with_values(v: f64, fixed: i32) -> Self { + Node { v, fixed } + } + + fn get_v(&self) -> f64 { + self.v + } + + fn set_v(&mut self, nv: f64) { + self.v = nv; + } + + fn get_fixed(&self) -> i32 { + self.fixed + } + + fn set_fixed(&mut self, nf: i32) { + self.fixed = nf; + } +} + +impl fmt::Display for Node { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Node {{ v: {}, fixed: {} }}", self.v, self.fixed) + } +} + +fn set_boundary(m: &mut Vec>) { + m[1][1].set_v(1.0); + m[1][1].set_fixed(1); + + m[6][7].set_v(-1.0); + m[6][7].set_fixed(-1); +} + +fn calculate_difference( + m: &Vec>, + d: &mut Vec>, + w: usize, + h: usize, +) -> f64 { + let mut total = 0.0; + for i in 0..h { + for j in 0..w { + let mut v = 0.0; + let mut n = 0; + if i > 0 { + v += m[i - 1][j].get_v(); + n += 1; + } + if j > 0 { + v += m[i][j - 1].get_v(); + n += 1; + } + if i + 1 < h { + v += m[i + 1][j].get_v(); + n += 1; + } + if j + 1 < w { + v += m[i][j + 1].get_v(); + n += 1; + } + let val = m[i][j].get_v() - v / n as f64; + d[i][j].set_v(val); + if m[i][j].get_fixed() == 0 { + total += val * val; + } + } + } + total +} + +fn iter(m: &mut Vec>, w: usize, h: usize) -> f64 { + let mut d: Vec> = vec![vec![Node::new(); w]; h]; + + let mut curr: [f64; 3] = [0.0, 0.0, 0.0]; + let mut diff = 1e10; + + while diff > 1e-24 { + set_boundary(m); + diff = calculate_difference(m, &mut d, w, h); + for i in 0..h { + for j in 0..w { + let current_v = m[i][j].get_v(); + let diff_v = d[i][j].get_v(); + m[i][j].set_v(current_v - diff_v); + } + } + } + + for i in 0..h { + for j in 0..w { + let mut k = 0; + if i != 0 { + k += 1; + } + if j != 0 { + k += 1; + } + if i < h - 1 { + k += 1; + } + if j < w - 1 { + k += 1; + } + curr[(m[i][j].get_fixed() + 1) as usize] += d[i][j].get_v() * k as f64; + } + } + + (curr[2] - curr[0]) / 2.0 +} + +const S: usize = 10; + +fn main() { + let mut mesh: Vec> = vec![vec![Node::new(); S]; S]; + + let r = 2.0 / iter(&mut mesh, S, S); + println!("R = {:.15}", r); +} diff --git a/Task/Return-multiple-values/EasyLang/return-multiple-values.easy b/Task/Return-multiple-values/EasyLang/return-multiple-values.easy index 7888ec771b..c91c232b27 100644 --- a/Task/Return-multiple-values/EasyLang/return-multiple-values.easy +++ b/Task/Return-multiple-values/EasyLang/return-multiple-values.easy @@ -1,4 +1,4 @@ -proc addSubtract a b . sum diff . +proc addSubtract a b &sum &diff . sum = a + b diff = a - b . diff --git a/Task/Reverse-a-string/Common-Lisp/reverse-a-string.lisp b/Task/Reverse-a-string/Common-Lisp/reverse-a-string-1.lisp similarity index 100% rename from Task/Reverse-a-string/Common-Lisp/reverse-a-string.lisp rename to Task/Reverse-a-string/Common-Lisp/reverse-a-string-1.lisp diff --git a/Task/Reverse-a-string/Common-Lisp/reverse-a-string-2.lisp b/Task/Reverse-a-string/Common-Lisp/reverse-a-string-2.lisp new file mode 100644 index 0000000000..7f2e6b2aaf --- /dev/null +++ b/Task/Reverse-a-string/Common-Lisp/reverse-a-string-2.lisp @@ -0,0 +1,15 @@ +(defun reverse-string (value) + "Reverse the string `value`. Handle wide characters with care." + (labels ((combining-char-p (c) + (eql :nsm (sb-unicode:bidi-class c))) + (%reverse (chars group acc) + (cond ((endp chars) + (coerce (append (nreverse group) acc) 'string)) + ((combining-char-p (first chars)) + (%reverse (rest chars) + (cons (first chars) group) + acc)) + (t (%reverse (rest chars) + (list (first chars)) + (append (nreverse group) acc)))))) + (%reverse (coerce value 'list) nil nil))) diff --git a/Task/Reverse-a-string/Excel/reverse-a-string.excel b/Task/Reverse-a-string/Excel/reverse-a-string.excel new file mode 100644 index 0000000000..cbeda522c8 --- /dev/null +++ b/Task/Reverse-a-string/Excel/reverse-a-string.excel @@ -0,0 +1 @@ +=LET(l,LEN(A1),CONCAT(MID(A1,l-SEQUENCE(l)+1,1))) diff --git a/Task/Roman-numerals-Decode/Objeck/roman-numerals-decode.objeck b/Task/Roman-numerals-Decode/Objeck/roman-numerals-decode.objeck new file mode 100644 index 0000000000..f5f93ce275 --- /dev/null +++ b/Task/Roman-numerals-Decode/Objeck/roman-numerals-decode.objeck @@ -0,0 +1,38 @@ +class Roman { + function : DecodeSingle(letter : Char) ~ Int { + select(letter) { + label 'M': { return 1000; } + label 'D': { return 500; } + label 'C': { return 100; } + label 'L': { return 50; } + label 'X': { return 10; } + label 'V': { return 5; } + label 'I': { return 1; } + other: { return 0; } + }; + } + + function : Decode(roman : String) ~ Int { + result := 0; + uRoman := roman->ToUpper(); # label-insensitive + for(i := 0;i < uRoman->Size()-1; i++;) {# loop over all but the last character + # if this character has a lower value than the next character + if (DecodeSingle(uRoman->Get(i)) < DecodeSingle(uRoman->Get(i+1))) { + # subtract it + result -= DecodeSingle(uRoman->Get(i)); + } else { + # add it + result += DecodeSingle(uRoman->Get(i)); + } + } + # Decode the last character, which is always added + result += DecodeSingle(uRoman->Get(uRoman->Size()-1)); + return result; + } + + function : Main(args : String[]) ~ Nil { + Decode("MCMXC")->PrintLine(); # 1990 + Decode("MMVIII")->PrintLine(); # 2008 + Decode("MDCLXVI")->PrintLine(); # 1666 + } +} diff --git a/Task/Roots-of-a-function/EasyLang/roots-of-a-function.easy b/Task/Roots-of-a-function/EasyLang/roots-of-a-function.easy index 511c41b2b1..7c73b64b86 100644 --- a/Task/Roots-of-a-function/EasyLang/roots-of-a-function.easy +++ b/Task/Roots-of-a-function/EasyLang/roots-of-a-function.easy @@ -1,8 +1,8 @@ func f x . return x * x * x - 3 * x * x + 2 * x . -numfmt 6 0 -proc findroot start stop step . . +numfmt 0 6 +proc findroot start stop step . x = start while x <= stop val = f x @@ -15,12 +15,23 @@ proc findroot start stop step . . x += step . . -proc drawfunc start stop . . - linewidth 0.3 +xp = 0 / 0 +yp = 0 +proc lineto x y . + x = x * 10 + 50 + y = y * 10 + 50 + if xp = xp : gline xp yp x y + xp = x + yp = y +. +proc drawfunc start stop . + glinewidth 0.3 + gline 0 50 100 50 + gline 50 0 50 100 drawgrid x = start while x <= stop - line x * 10 + 50 f x * 10 + 50 + lineto x f x x += 0.1 . . diff --git a/Task/Roots-of-unity/EasyLang/roots-of-unity.easy b/Task/Roots-of-unity/EasyLang/roots-of-unity.easy index e55c525ab5..d636e38a16 100644 --- a/Task/Roots-of-unity/EasyLang/roots-of-unity.easy +++ b/Task/Roots-of-unity/EasyLang/roots-of-unity.easy @@ -1,13 +1,11 @@ -numfmt 4 0 +numfmt 0 4 for n = 2 to 5 write n & ": " for root = 0 to n - 1 real = cos (360 * root / n) imag = sin (360 * root / n) write real & " " & imag & "i" - if root <> n - 1 - write ", " - . + if root <> n - 1 : write ", " . print "" . diff --git a/Task/Rosetta-Code-Find-unimplemented-tasks/Objeck/rosetta-code-find-unimplemented-tasks.objeck b/Task/Rosetta-Code-Find-unimplemented-tasks/Objeck/rosetta-code-find-unimplemented-tasks.objeck new file mode 100644 index 0000000000..d0494f5a19 --- /dev/null +++ b/Task/Rosetta-Code-Find-unimplemented-tasks/Objeck/rosetta-code-find-unimplemented-tasks.objeck @@ -0,0 +1,109 @@ +use Web.HTTP, Collection, Data.JSON, System.IO.Filesystem; + +class UnimplTasks { + function : Main(args : String[]) ~ Nil { + if(args->Size() <> 1) { + ">>> Usage: filename.csv <<<"->ErrorLine(); + Runtime->Exit(1); + }; + file_out_name := args[0]; + + all_tasks := GetAllTasks(); + lang_tasks := GetTasksByLang("Objeck"); + + unimpl_tasks := Vector->New(); + each(all_task in all_tasks) { + all_task_str := all_task->GetString(); + + found := false; + for(i := 0; <>found & i < lang_tasks->Size(); i += 1;) { + lang_task := lang_tasks->Get(i); + lang_task_str := lang_task->GetString(); + found := all_task_str->Equals(lang_task_str); + }; + + if(<>found) { + unimpl_tasks->AddBack(all_task); + } + }; + + file_out := FileWriter->New(file_out_name); + file_out->WriteString("description,url\r\n"); + task_base_url_str := "https://rosettacode.org/wiki/"; + each(unimpl_task in unimpl_tasks) { + task_desc := unimpl_task->GetString(); + task_str := task_desc->ReplaceAll(' ', '_'); + + task_str := task_str->ReplaceAll(",", "%2C"); + task_str := task_str->ReplaceAll("\\\"", "\""); + + task_desc := task_desc->ReplaceAll(",", "-"); + task_desc := task_desc->ReplaceAll("\\\"", "\""); + + task_url_str := task_base_url_str + task_str; + + file_out->WriteString("{$task_desc},{$task_url_str}\r\n"); + }; + file_out->Close(); + + + lang_tasks_size := lang_tasks->Size(); + all_tasks_size := all_tasks->Size(); + diff_comp := lang_tasks_size->ToFloat() / all_tasks_size->ToFloat(); + + String->SetFloatPrecision(3); + prec_comp := (diff_comp * 100.0)->ToString(); + prec_comp += "%"; + "Rosetta Code\n{$lang_tasks_size} of {$all_tasks_size} tasks completed, {$prec_comp}%\nfile={$file_out_name}"->PrintLine(); + } + + function : GetTasksByLang(lang : String) ~ Vector { + tasks := Vector->New(); + base_url_str := "https://rosettacode.org/w/api.php?action=query&cmlimit=500&cmtitle=Category:{$lang}&format=json&list=categorymembers"; + + next_url_str := AddTasks(base_url_str, tasks); + while(next_url_str <> Nil) { + next_url_str := base_url_str + "&cmcontinue=" + next_url_str; + next_url_str := AddTasks(next_url_str, tasks); + }; + + return tasks; + } + + function : GetAllTasks() ~ Vector { + tasks := Vector->New(); + base_url_str := "https://rosettacode.org/w/api.php?action=query&cmlimit=500&cmtitle=Category:Programming_Tasks&format=json&list=categorymembers"; + + next_url_str := AddTasks(base_url_str, tasks); + do { + if(next_url_str <> Nil) { + next_url_str := base_url_str + "&cmcontinue=" + next_url_str; + next_url_str := AddTasks(next_url_str, tasks); + }; + } + while(next_url_str <> Nil); + + return tasks; + } + + function : AddTasks(query_url : String, tasks : Vector) ~ String { + response := HttpsClient->QuickGet(Url->New(query_url), "application/json"); + + if(response <> Nil) { + response_json := JsonParser->TextToElement(response->GetContent()->ToString()); + if(response_json <> Nil) { + members_json := response_json->Get("query")->Get("categorymembers"); + each(member_json in members_json) { + tasks->AddBack(member_json->Get("title")); + } + + next_url_json := response_json->Get("continue"); + if(next_url_json <> Nil) { + return next_url_json->Get("cmcontinue")->GetString(); + }; + }; + }; + + return Nil; + } +} diff --git a/Task/Rosetta-Code-Fix-code-tags/FreeBASIC/rosetta-code-fix-code-tags.basic b/Task/Rosetta-Code-Fix-code-tags/FreeBASIC/rosetta-code-fix-code-tags.basic new file mode 100644 index 0000000000..c59a8977db --- /dev/null +++ b/Task/Rosetta-Code-Fix-code-tags/FreeBASIC/rosetta-code-fix-code-tags.basic @@ -0,0 +1,66 @@ +Function ReplaceAll(Byval source As String, Byval find As String, Byval replace As String) As String + Dim As String result = source + Dim As Integer posic = Instr(result, find) + Dim As Integer offset = 1 + While posic > 0 + result = Left(result, posic - 1) & replace & Mid(result, posic + Len(find)) + offset = posic + Len(replace) + posic = Instr(offset, result, find) + Wend + Return result +End Function + +Function ProcessSource(source As String) As String + Dim As String result = source + Dim As String sh = "syntaxhighlight" + Dim As String linea, newContent + Dim As Integer nlPos + + ' Process line by line + While Len(result) > 0 + nlPos = Instr(result, Chr(10)) + If nlPos = 0 Then + linea = result + result = "" + Else + linea = Left(result, nlPos - 1) + result = Mid(result, nlPos + 1) + End If + + ' Check for ") + If closePos > 0 Then + Dim As String lang = Trim(Mid(linea, 6, closePos - 6)) + If lang = "" Then lang = "text" + linea = "<" & sh & " lang=""" & lang & """>" & Mid(linea, closePos + 1) + End If + End If + + newContent &= linea & Chr(10) + Wend + + ' Replace plain with + newContent = ReplaceAll(newContent, "", "<" & sh & " lang=""text"">") + ' Replace closing tags + newContent = ReplaceAll(newContent, "", "") + + Return newContent +End Function + +' Main program +Dim As String filename = "input.txt" +Dim As Integer ff = Freefile +Dim As String linea, content + +If Open(filename For Input As #ff) = 0 Then + While Not Eof(ff) + Line Input #ff, linea + content &= linea & Chr(10) + Wend + Close #ff + + Print ProcessSource(content) +End If + +Sleep diff --git a/Task/Rosetta-Code-Rank-languages-by-popularity/FreeBASIC/rosetta-code-rank-languages-by-popularity.basic b/Task/Rosetta-Code-Rank-languages-by-popularity/FreeBASIC/rosetta-code-rank-languages-by-popularity.basic new file mode 100644 index 0000000000..89c67f525c --- /dev/null +++ b/Task/Rosetta-Code-Rank-languages-by-popularity/FreeBASIC/rosetta-code-rank-languages-by-popularity.basic @@ -0,0 +1,88 @@ +#include "windows.bi" +#include "win/wininet.bi" + +Type Category + lenguaje As String + numEntrada As Integer +End Type + +Function DownloadString(url As String) As String + Const BUFFER_SIZE As Integer = 8192 + Dim As HINTERNET hInternet, hConnect + Dim As String resultado + Dim As ZString Ptr buffer = Allocate(BUFFER_SIZE) + Dim As DWORD bytesRead + + hInternet = InternetOpen("FreeBASIC", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0) + If hInternet = 0 Then Return "" + + hConnect = InternetOpenUrl(hInternet, Strptr(url), NULL, 0, INTERNET_FLAG_RELOAD, 0) + If hConnect = 0 Then + InternetCloseHandle(hConnect) + Return "" + End If + + Do + If InternetReadFile(hConnect, buffer, BUFFER_SIZE - 1, @bytesRead) = 0 Then Exit Do + If bytesRead = 0 Then Exit Do + resultado &= Left(*buffer, bytesRead) + Loop + + InternetCloseHandle(hConnect) + InternetCloseHandle(hInternet) + Deallocate(buffer) + + Return resultado +End Function + +Sub PrintTopCategories(url As String) + Dim As String content = DownloadString(url) + Dim As Integer startPos, endPos, numEntrada + Dim As String categoria, memberStr + Dim As Category categorias(999) + Dim As Integer cnt = 0 + Dim As Integer i, j + + startPos = Instr(content, "") + 1 + endPos = Instr(startPos, content, "") + categoria = Mid(content, startPos, endPos - startPos) + + startPos = Instr(endPos, content, "(") + 1 + endPos = Instr(startPos, content, " member") + memberStr = Mid(content, startPos, endPos - startPos) + + numEntrada = 0 + For i = 1 To Len(memberStr) + If Mid(memberStr, i, 1) <> "," Then + numEntrada = numEntrada * 10 + Val(Mid(memberStr, i, 1)) + End If + Next i + + If Left(categoria, 5) <> "Pages" Then + categorias(cnt).lenguaje = categoria + categorias(cnt).numEntrada = numEntrada + cnt += 1 + End If + + startPos = Instr(endPos, content, " 'M') then - ch = ascii(rank(ch) - 13); - else - ch = ascii(rank(ch) + 13); - end; + if (ch >= 'a' & ch <= 'm') | (ch >= 'A' & ch <= 'M') + then ch = ascii(rank(ch) + 13); + else if (ch >= 'n' & ch <= 'z') | (ch >= 'N' & ch <= 'Z') + then ch = ascii(rank(ch) - 13); substr(s,i,1) = ch; end; return (s); end rot13; -toupper: - procedure (ch) returns (char(1)); - dcl ch char(1); - dcl cout char(1); - if ((ch >= 'a') & (ch <= 'z')) then - cout = ascii(rank(ch) - 32); - else - cout = ch; - return (cout); - end toupper; - -isalpha: - procedure (ch) returns (bit(1)); - dcl ch char(1); - if (((ch >= 'A') & (ch <= 'Z')) | - ((ch >= 'a') & (ch <= 'z'))) then - return (true); - else - return (false); - end isalpha; - - end rot13_test; diff --git a/Task/Run-length-encoding/8080-Assembly/run-length-encoding.8080 b/Task/Run-length-encoding/8080-Assembly/run-length-encoding.8080 new file mode 100644 index 0000000000..da3d4f0baa --- /dev/null +++ b/Task/Run-length-encoding/8080-Assembly/run-length-encoding.8080 @@ -0,0 +1,92 @@ + org 100h + jmp demo + + ; Encode 0-terminated string at HL, store at DE +encode: mov a,m + ana a + jz edone + mvi b,1 +escan: inx h + cmp m + jnz ewrite + inr b + jnz escan + dcr b +ewrite: xchg + mov m,b + inx h + mov m,a + inx h + xchg + jmp encode +edone: stax d + ret + + ; Decode 0-terminated string at HL, store at DE +decode: mov a,m + ana a + jz edone + mov b,a + inx h + mov a,m +dwrite: stax d + inx d + dcr b + jnz dwrite + inx h + jmp decode + + ; Show two examples +demo: lxi h,exampl + call show + lxi h,examp2 +show: push h + call puts ; Show start string + lxi h,nl + call puts + pop h + lxi d,buf1 ; Encode string + call encode + lxi h,buf1 ; Show encoded result (as hexadecimal) + call puthex + lxi h,nl + call puts + lxi h,buf1 ; Decode string + lxi d,buf2 + push d + call decode + pop h + call puts ; Show decoded string + lxi h,nl + jmp puts + +nl: db 13,10,0 +exampl: db 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWW' + db 'WWWWWWWWWWWWWWBWWWWWWWWWWWWWW',0 + + ; Test case with more than 255 repeated items +examp2: db 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + db 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + db 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + db 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + db 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + db 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + db 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + db 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + db 'XXXXXXX',0 + + ; Print 0-terminated string at HL +puts: mov a,m! ora a! rz + push h! mvi c,2! mov e,a! call 5! pop h! inx h! jmp puts + + ; Print 0-terminated string at HL as hex +puthex: mov a,m! ora a! rz + push h! call hexout! pop h! inx h! jmp puthex + + ; Print A as hexadecimal +hexout: push psw! rar! rar! rar! rar! call hexlo! pop psw +hexlo: ani 0Fh! cpi 10! jc hexp! adi 7 +hexp: adi '0'! mvi c,2! mov e,a! jmp 5 + +buf1 equ $ +buf2 equ buf1+256 diff --git a/Task/Run-length-encoding/Crystal/run-length-encoding.cr b/Task/Run-length-encoding/Crystal/run-length-encoding.cr new file mode 100644 index 0000000000..fa86ef5a3d --- /dev/null +++ b/Task/Run-length-encoding/Crystal/run-length-encoding.cr @@ -0,0 +1,19 @@ +def rlencode (s) + result = Array({Char, Int32}).new + s.scan(/(.)\1*/) do |m| + result << { m[1][0], m[0].size } + end + result +end + +def rldecode (enc) + String.build do |s| + enc.each do |char, length| + s << char.to_s * length + end + end +end + +enc = rlencode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW") +p enc +puts rldecode(enc) diff --git a/Task/Run-length-encoding/MACRO-11/run-length-encoding.macro11 b/Task/Run-length-encoding/MACRO-11/run-length-encoding.macro11 new file mode 100644 index 0000000000..2ed4a2f8e3 --- /dev/null +++ b/Task/Run-length-encoding/MACRO-11/run-length-encoding.macro11 @@ -0,0 +1,106 @@ + .TITLE RLE + .MCALL .TTYOUT,.EXIT +RLE:: JMP DEMO + + ; ENCODE 0-TERMINATED STRING AT (R0), STORE AT (R1) +ENCODE: MOVB (R0),R2 + BEQ 3$ + MOVB #1,R3 +1$: INC R0 + CMPB (R0),R2 + BNE 2$ + INCB R3 + BNE 1$ + DECB R3 +2$: MOVB R3,(R1)+ + MOVB R2,(R1)+ + BR ENCODE +3$: CLRB (R1) + RTS PC + + ; DECODE 0-TERMINATED STRING AT (R0), STORE AT (R1) +DECODE: MOVB (R0)+,R2 + BEQ 2$ + MOVB (R0)+,R3 + BIC #^C377,R2 +1$: MOVB R3,(R1)+ + SOB R2,1$ + BR DECODE +2$: CLRB (R1) + RTS PC + + ; TESTS +DEMO: MOV #TEST1,R5 + JSR PC,1$ + MOV #TEST2,R5 + JSR PC,1$ + .EXIT +1$: MOV R5,R1 + JSR PC,PRINT + MOV #NL,R1 + JSR PC,PRINT + MOV R5,R0 + MOV #BUFR1,R1 + JSR PC,ENCODE + MOV #BUFR1,R1 + JSR PC,PRHEXS + MOV #NL,R1 + JSR PC,PRINT + MOV #BUFR1,R0 + MOV #BUFR2,R1 + JSR PC,DECODE + MOV #BUFR2,R1 + JSR PC,PRINT + MOV #NL,R1 + JSR PC,PRINT + RTS PC + +NL: .BYTE 15,12,0 + +TEST1: .ASCII /WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWW/ + .ASCIZ /WWWWWWWWWWWWWWBWWWWWWWWWWWWWW/ + +TEST2: .ASCII /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ + .ASCII /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ + .ASCII /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ + .ASCII /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ + .ASCII /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ + .ASCII /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ + .ASCII /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ + .ASCII /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ + .ASCIZ /XXXXXXX/ + + .EVEN + + ; PRINT STRING AT R1 +PRINT: MOVB (R1)+,R0 + .TTYOUT + BNE PRINT + RTS PC + + ; PRINT HEX BYTE R0 +PRHEXB: MOV R0,-(SP) + ROR R0 + ROR R0 + ROR R0 + ROR R0 + JSR PC,1$ + MOV (SP)+,R0 +1$: BIC #^C17,R0 + CMP R0,#^D10 + BLO 2$ + ADD #7,R0 +2$: ADD #'0,R0 + .TTYOUT + RTS PC + + ; PRINT HEX STRING R1 +PRHEXS: MOVB (R1)+,R0 + BEQ 1$ + JSR PC,PRHEXB + BR PRHEXS +1$: RTS PC + +BUFR1: .BLKB 400 +BUFR2: .BLKB 400 + .END RLE diff --git a/Task/Run-length-encoding/Miranda/run-length-encoding.miranda b/Task/Run-length-encoding/Miranda/run-length-encoding.miranda new file mode 100644 index 0000000000..4d3a554df9 --- /dev/null +++ b/Task/Run-length-encoding/Miranda/run-length-encoding.miranda @@ -0,0 +1,18 @@ +main :: [sys_message] +main = [Stdout (lay [inp, show enc, dec])] + where inp = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW" + enc = rlencode inp + dec = rldecode enc + +rlencode :: [*]->[(num,*)] +rlencode xs = [(#p, hd p) | p <- chunk xs] + +rldecode :: [(num,*)]->[*] +rldecode xs = concat [take n (repeat x) | (n,x) <- xs] + +chunk :: [*]->[[*]] +chunk = f [] + where f acc [] = [acc] + f [] (a:as) = f [a] as + f (a:acc) (a:as) = f (a:a:acc) as + f acc (a:as) = acc:f [a] as diff --git a/Task/Run-length-encoding/Refal/run-length-encoding.refal b/Task/Run-length-encoding/Refal/run-length-encoding.refal new file mode 100644 index 0000000000..6174153b19 --- /dev/null +++ b/Task/Run-length-encoding/Refal/run-length-encoding.refal @@ -0,0 +1,44 @@ +$ENTRY Go { + , >: e.In + , >: e.Enc + = >; +}; + +Example { + = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW'; +}; + +RLEncode { + e.X = >; +}; + +RLDecode { + e.X = >; +}; + +Count { + e.X, : s.L s.C e.Y = s.L s.C; +}; + +Repeat { + 0 s.C = ; + s.N s.C = s.C s.C>; +}; + +Each { + (e.F) = ; + (e.F) (e.X) e.Y = () ; +}; + +Chunk { + = ; + (e.I) = (e.I); + (e.I t.I) t.I e.X = ; + (e.I) t.J e.X = (e.I) ; + t.I e.X = ; +}; + +Concat { + = ; + (e.X) e.Y = e.X ; +}; diff --git a/Task/Runge-Kutta-method/00-TASK.txt b/Task/Runge-Kutta-method/00-TASK.txt index eafc75a430..a961c26a39 100644 --- a/Task/Runge-Kutta-method/00-TASK.txt +++ b/Task/Runge-Kutta-method/00-TASK.txt @@ -1,5 +1,5 @@ Given the example Differential equation: -:y'(t) = t \times \sqrt {y(t)} +:y'(t) = t \cdot \sqrt {y(t)} With initial condition: :t_0 = 0 and y_0 = y(t_0) = y(0) = 1 This equation has an exact solution: @@ -14,10 +14,10 @@ Demonstrate the commonly used explicit   [[wp:Runge–Kutta_methods#Common_ ;Method summary Starting with a given y_n and t_n calculate: -:\delta y_1 = \delta t\times y'(t_n, y_n)\quad -:\delta y_2 = \delta t\times y'(t_n + \tfrac{1}{2}\delta t , y_n + \tfrac{1}{2}\delta y_1) -:\delta y_3 = \delta t\times y'(t_n + \tfrac{1}{2}\delta t , y_n + \tfrac{1}{2}\delta y_2) -:\delta y_4 = \delta t\times y'(t_n + \delta t , y_n + \delta y_3)\quad +:\delta y_1 = \delta t\cdot y'(t_n, y_n)\quad +:\delta y_2 = \delta t\cdot y'(t_n + \tfrac{1}{2}\delta t , y_n + \tfrac{1}{2}\delta y_1) +:\delta y_3 = \delta t\cdot y'(t_n + \tfrac{1}{2}\delta t , y_n + \tfrac{1}{2}\delta y_2) +:\delta y_4 = \delta t\cdot y'(t_n + \delta t , y_n + \delta y_3)\quad then: :y_{n+1} = y_n + \tfrac{1}{6} (\delta y_1 + 2\delta y_2 + 2\delta y_3 + \delta y_4) :t_{n+1} = t_n + \delta t\quad diff --git a/Task/Runge-Kutta-method/EasyLang/runge-kutta-method.easy b/Task/Runge-Kutta-method/EasyLang/runge-kutta-method.easy index 4b0cc9de38..89fb62f249 100644 --- a/Task/Runge-Kutta-method/EasyLang/runge-kutta-method.easy +++ b/Task/Runge-Kutta-method/EasyLang/runge-kutta-method.easy @@ -1,4 +1,4 @@ -numfmt 6 0 +numfmt 0 6 y = 1 for i = 0 to 100 t = i / 10 diff --git a/Task/Runge-Kutta-method/Odin/runge-kutta-method.odin b/Task/Runge-Kutta-method/Odin/runge-kutta-method.odin new file mode 100644 index 0000000000..bc3b88a13d --- /dev/null +++ b/Task/Runge-Kutta-method/Odin/runge-kutta-method.odin @@ -0,0 +1,37 @@ +package runge_kutta + +import "core:fmt" +import "core:math" + +func :: proc(x: f32, y: f32) -> f32 { + return x * math.sqrt(y) +} + +main :: proc() { + STEPS :: 100 + sols: [STEPS + 1]f32 + + x0, y0, h := f32(0.0), f32(1.0), f32(0.1) + xn, yn := x0, y0 + + sols[0] = y0 + factor := f32(1.0 / 6.0) + + for &sol in sols[1:] { + dy1 := h * func(xn,yn) + dy2 := h * func(xn + 0.5 * h, yn + 0.5 * dy1) + dy3 := h * func(xn + 0.5 * h, yn + 0.5 * dy2) + dy4 := h * func(xn + h, yn + dy3) + sol = yn + factor * (dy1 + 2 * dy2 + 2 * dy3 + dy4) + yn = sol + xn = xn + h + } + + for i in 1..>> (32 - bits))) | 0; // | 0 ensures result is 32-bit signed int + } + + /** + * Adds SHA-1 padding to the message bytes. + * @param {Uint8Array} messageBytes - The message as bytes. + * @returns {Uint8Array} The padded message bytes. + */ + _addPadding(messageBytes) { + const msgLenBytes = messageBytes.length; + // Use BigInt for potentially large bit lengths + const bitLength = BigInt(msgLenBytes) * 8n; + + // Calculate the total padded length in bytes + // Need msgLenBytes + 1 (for 0x80) + k (zeros) + 8 (length) = N * 64 + // msgLenBytes + 9 + k = N * 64 + // The number of zero bytes 'k' needed is: + // k = (64 - (msgLenBytes + 9) % 64) % 64 + const k = (this.BLOCK_LENGTH - ((msgLenBytes + 9) % this.BLOCK_LENGTH)) % this.BLOCK_LENGTH; + const paddedLength = msgLenBytes + 1 + k + 8; + const paddedBytes = new Uint8Array(paddedLength); + + // 1. Copy original message + paddedBytes.set(messageBytes); + + // 2. Append a single '1' bit (0x80 byte) + paddedBytes[msgLenBytes] = 0x80; + + // 3. Append K '0' bits (zero bytes). Uint8Array initializes to 0, so this is implicit. + + // 4. Append length L as a 64-bit big-endian integer. + const lengthOffset = paddedLength - 8; + for (let i = 0; i < 8; i++) { + // Extract byte from BigInt bitLength + const shift = BigInt(i) * 8n; + // Place it in big-endian order (most significant byte first) + paddedBytes[lengthOffset + 7 - i] = Number((bitLength >> shift) & 0xffn); + } + + return paddedBytes; + } + + /** + * Computes the SHA-1 hash of a message string. + * @param {string} message - The input message string. + * @returns {string} The SHA-1 hash as a 40-character hex string. + */ + messageDigest(message) { + // 1. Convert message string to UTF-8 bytes + const encoder = new TextEncoder(); // Assumes UTF-8 + const messageBytes = encoder.encode(message); + + // 2. Add padding + const paddedBytes = this._addPadding(messageBytes); + + // 3. Initialize hash values + let state = [...this.H]; // Create a working copy + + // 4. Process message in 64-byte (512-bit) blocks + for (let i = 0; i < paddedBytes.length; i += this.BLOCK_LENGTH) { + const blockBytes = paddedBytes.subarray(i, i + this.BLOCK_LENGTH); + + // Prepare the message schedule (80 32-bit words) + const W = new Array(80); + + // a. Copy block into first 16 words (big-endian) + for (let t = 0; t < 16; t++) { + const offset = t * 4; + W[t] = ((blockBytes[offset] << 24) | + (blockBytes[offset + 1] << 16) | + (blockBytes[offset + 2] << 8) | + (blockBytes[offset + 3])) | 0; // | 0 ensures 32-bit signed int + } + + // b. Extend the first 16 words into the remaining 64 words + for (let t = 16; t < 80; t++) { + const wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]; + W[t] = this._rotl(wt, 1); + } + + // Initialize hash value for this block + let a = state[0]; + let b = state[1]; + let c = state[2]; + let d = state[3]; + let e = state[4]; + + // Main loop + for (let t = 0; t < 80; t++) { + let f, k; + const round = Math.floor(t / 20); + switch (round) { + case 0: // Rounds 0-19 + f = (b & c) | (~b & d); + k = this.K[0]; + break; + case 1: // Rounds 20-39 + f = b ^ c ^ d; + k = this.K[1]; + break; + case 2: // Rounds 40-59 + f = (b & c) | (b & d) | (c & d); + k = this.K[2]; + break; + case 3: // Rounds 60-79 + f = b ^ c ^ d; + k = this.K[3]; + break; + } + + // Ensure all additions are performed modulo 2^32 + const temp = (this._rotl(a, 5) + f + e + k + W[t]) | 0; + e = d; + d = c; + c = this._rotl(b, 30); + b = a; + a = temp; + } + + // Add this block's hash to the result so far (modulo 2^32) + state[0] = (state[0] + a) | 0; + state[1] = (state[1] + b) | 0; + state[2] = (state[2] + c) | 0; + state[3] = (state[3] + d) | 0; + state[4] = (state[4] + e) | 0; + } + + // 5. Produce the final hash value (big-endian) as a hex string + let hexHash = ""; + for (const h of state) { + // Convert each 32-bit component to hex, padding with '0' + // Use >>> 0 to treat h as unsigned before converting to hex parts + const unsignedH = h >>> 0; + hexHash += (unsignedH >>> 24).toString(16).padStart(2, '0'); + hexHash += ((unsignedH >>> 16) & 0xff).toString(16).padStart(2, '0'); + hexHash += ((unsignedH >>> 8) & 0xff).toString(16).padStart(2, '0'); + hexHash += (unsignedH & 0xff).toString(16).padStart(2, '0'); + } + + return hexHash; + } +} + +// --- Main execution (equivalent to C++ main) --- +const sha1 = new SHA1(); +const message = "Rosetta Code"; +const digest = sha1.messageDigest(message); +console.log(digest); diff --git a/Task/SHA-1/Zig/sha-1.zig b/Task/SHA-1/Zig/sha-1.zig new file mode 100644 index 0000000000..bf8ed827af --- /dev/null +++ b/Task/SHA-1/Zig/sha-1.zig @@ -0,0 +1,126 @@ +const std = @import("std"); + +const SHA1 = struct { + const BLOCK_LENGTH: u32 = 64; + + fn messageDigest(message: []const u8) ![40]u8 { + var state = [5]u32{ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; + + const bytes = try addPadding(message); + var i: usize = 0; + while (i < bytes.len / BLOCK_LENGTH) : (i += 1) { + var values = [_]u32{0} ** 80; + + var j: u32 = 0; + while (j < BLOCK_LENGTH) : (j += 1) { + values[j / 4] |= @as(u32, @intCast(bytes[i * BLOCK_LENGTH + j] & 0xff)) << @intCast((3 - j % 4) * 8); + } + + j = 16; + while (j < 80) : (j += 1) { + const value = values[j - 3] ^ values[j - 8] ^ values[j - 14] ^ values[j - 16]; + values[j] = std.math.rotl(u32, value, 1); + } + + var a = state[0]; + var b = state[1]; + var c = state[2]; + var d = state[3]; + var e = state[4]; + var f: u32 = 0; + var k: u32 = 0; + + j = 0; + while (j < 80) : (j += 1) { + switch (j / 20) { + 0 => { + f = (b & c) | (~b & d); + k = 0x5a827999; + }, + 1 => { + f = b ^ c ^ d; + k = 0x6ed9eba1; + }, + 2 => { + f = (b & c) | (b & d) | (c & d); + k = 0x8f1bbcdc; + }, + 3 => { + f = b ^ c ^ d; + k = 0xca62c1d6; + }, + else => unreachable, + } + + // Use wrapping add to prevent integer overflow panics + const rotated_a = std.math.rotl(u32, a, 5); + const temp = @addWithOverflow(rotated_a, f)[0]; + const temp2 = @addWithOverflow(temp, e)[0]; + const temp3 = @addWithOverflow(temp2, k)[0]; + const temp4 = @addWithOverflow(temp3, values[j])[0]; + + e = d; + d = c; + c = std.math.rotl(u32, b, 30); + b = a; + a = temp4; + } + + // Use wrapping adds for state updates + state[0] = @addWithOverflow(state[0], a)[0]; + state[1] = @addWithOverflow(state[1], b)[0]; + state[2] = @addWithOverflow(state[2], c)[0]; + state[3] = @addWithOverflow(state[3], d)[0]; + state[4] = @addWithOverflow(state[4], e)[0]; + } + + var result: [40]u8 = undefined; + var buffer: [8]u8 = undefined; + + for (0..20) |my_i| { + const byte_value: u8 = @intCast((state[my_i / 4] >> @intCast(24 - (my_i % 4) * 8)) & 0xff); + _ = try std.fmt.bufPrint(buffer[0..2], "{x:0>2}", .{byte_value}); + result[my_i * 2] = buffer[0]; + result[my_i * 2 + 1] = buffer[1]; + } + + return result; + } + + fn addPadding(message: []const u8) ![]u8 { + const allocator = std.heap.page_allocator; + + // Initialize with the message + var bytes = std.ArrayList(u8).init(allocator); + defer bytes.deinit(); + + try bytes.appendSlice(message); + try bytes.append(0x80); + + var padding: u32 = BLOCK_LENGTH - @as(u32, @intCast(bytes.items.len % BLOCK_LENGTH)); + if (padding < 8) { + padding += BLOCK_LENGTH; + } + + var i: u32 = 0; + while (i < padding - 8) : (i += 1) { + try bytes.append(0x0); + } + + const bit_length: u64 = 8 * message.len; + i = 0; + while (i < 8) : (i += 1) { + const shift_amount: u6 = @intCast(8 * (7 - i)); // Explicit cast to u6 for shift + try bytes.append(@intCast((bit_length >> shift_amount) & 0xff)); + } + + return bytes.toOwnedSlice(); + } +}; + +pub fn main() !void { + const message = "Rosetta Code"; + const result = try SHA1.messageDigest(message); + const stdout = std.io.getStdOut().writer(); + try stdout.print("{s}\n", .{result}); +} diff --git a/Task/SQL-based-authentication/FreeBASIC/sql-based-authentication.basic b/Task/SQL-based-authentication/FreeBASIC/sql-based-authentication.basic new file mode 100644 index 0000000000..706740e8fe --- /dev/null +++ b/Task/SQL-based-authentication/FreeBASIC/sql-based-authentication.basic @@ -0,0 +1,91 @@ +#Include once "mysql/mysql.bi" +#Include once "md5.bas" +'[https://rosettacode.org/wiki/MD5/Implementation#FreeBASIC] +#Include once "crt.bi" + +' Declare MySQL object +Dim Shared As MYSQL Ptr miSQL +Dim Shared As MYSQL_RES Ptr result +Dim Shared As String pass_salt, pass_md5 + +Function generate_salt() As String + Dim As String salt = "" + For i As Integer = 1 To 16 + salt &= Chr(Int(Rnd * 256)) ' Generate a random byte + Next i + Return salt +End Function + +Function generar_hash(Byval salt As String, Byval password As String) As String + Return MD5(salt & password) +End Function + +Sub connect_db() + miSQL = mysql_init(NULL) + ' Modify these parameters with your real connection data + If mysql_real_connect(miSQL, "localhost", "username", "password", "database", 0, NULL, 0) = NULL Then + Print "Connection error: "; mysql_error(miSQL) + Sleep: End 1 + Else + Print "Conexión exitosa a MySQL!" + End If +End Sub + +Sub create_user(Byval username As String, Byval password As String) + Dim As String query = "INSERT INTO users (username, pass_salt, pass_md5) VALUES ('" & safe_username & "', '" & pass_salt & "', '" & pass_md5 & "')" + + If mysql_query(miSQL, query) <> 0 Then + Print "Query error: "; mysql_error(miSQL) + Else + Print "Usuario creado exitosamente!" + End If +End Sub + +Function authenticate_user(Byval username As String, Byval password As String) As Boolean + Dim As String query = "SELECT * FROM users WHERE username = '" & username & "'" + + If mysql_query(miSQL, query) <> 0 Then + Print "Query error: "; mysql_error(miSQL) + Return False + End If + + result = mysql_store_result(miSQL) + + If result <> NULL Then + If mysql_num_rows(result) > 0 Then + Dim As MYSQL_ROW row = mysql_fetch_row(result) + Dim As String stored_salt = *row[1] ' Assuming pass_salt is in column 1 + Dim As String stored_hash = *row[2] ' Assuming pass_md5 is in column 2 + + Dim As String calculated_hash = generar_hash(stored_salt, password) + + mysql_free_result(result) + + If calculated_hash = stored_hash Then + Return True ' Authenticated user + End If + End If + + mysql_free_result(result) + End If + + Return False ' Authentication failed +End Function + +' Main program +Randomize Timer + +pass_salt = generate_salt() +pass_md5 = generar_hash(pass_salt, "testpassword") + +Print "Salt: "; pass_salt +Print "Hash: "; pass_md5 + +connect_db() +create_user("testuser", "testpassword") +Print "Authentication result: "; authenticate_user("testuser", "testpassword") + +' Free up resources +mysql_close(miSQL) + +Sleep diff --git a/Task/Safe-primes-and-unsafe-primes/EasyLang/safe-primes-and-unsafe-primes.easy b/Task/Safe-primes-and-unsafe-primes/EasyLang/safe-primes-and-unsafe-primes.easy index 1165aaae65..4ef723f12a 100644 --- a/Task/Safe-primes-and-unsafe-primes/EasyLang/safe-primes-and-unsafe-primes.easy +++ b/Task/Safe-primes-and-unsafe-primes/EasyLang/safe-primes-and-unsafe-primes.easy @@ -1,18 +1,12 @@ fastfunc isprim num . - if num < 2 - return 0 - . + if num < 2 : return 0 if num mod 2 = 0 - if num = 2 - return 1 - . + if num = 2 : return 1 return 0 . i = 3 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 . return 1 @@ -20,9 +14,7 @@ fastfunc isprim num . print "First 35 safe primes:" for i = 2 to 999999 if isprim i = 1 and isprim ((i - 1) / 2) = 1 - if count < 35 - write i & " " - . + if count < 35 : write i & " " count += 1 . . @@ -39,9 +31,7 @@ count = 0 print "First 40 unsafe primes:" for i = 2 to 999999 if isprim i = 1 and isprim ((i - 1) / 2) = 0 - if count < 40 - write i & " " - . + if count < 40 : write i & " " count += 1 . . diff --git a/Task/Safe-primes-and-unsafe-primes/REXX/safe-primes-and-unsafe-primes.rexx b/Task/Safe-primes-and-unsafe-primes/REXX/safe-primes-and-unsafe-primes.rexx index 6b56d55eb5..2a06d111a6 100644 --- a/Task/Safe-primes-and-unsafe-primes/REXX/safe-primes-and-unsafe-primes.rexx +++ b/Task/Safe-primes-and-unsafe-primes/REXX/safe-primes-and-unsafe-primes.rexx @@ -1,50 +1,72 @@ -/*REXX program lists a sequence (or a count) of ──safe── or ──unsafe── primes. */ -parse arg N kind _ . 1 . okind; upper kind /*obtain optional arguments from the CL*/ -if N=='' | N=="," then N= 35 /*Not specified? Then assume default.*/ -if kind=='' | kind=="," then kind= 'SAFE' /* " " " " " */ -if _\=='' then call ser 'too many arguments specified.' -if kind\=='SAFE' & kind\=='UNSAFE' then call ser 'invalid 2nd argument: ' okind -if kind =='UNSAFE' then safe= 0; else safe= 1 /*SAFE is a binary value for function.*/ -w = linesize() - 1 /*obtain the usable width of the term. */ -tell= (N>0); @.=; N= abs(N) /*N is negative? Then don't display. */ -!.=0; !.1=2; !.2=3; !.3=5; !.4=7; !.5=11; !.6=13; !.7=17; !.8=19; #= 8 -@.=''; @.2=1; @.3=1; @.5=1; @.7=1; @.11=1; @.13=1; @.17=1; @.19=1; start= # + 1 -m= 0; lim=0 /*# is the number of low primes so far*/ -$=; do i=1 for # while lim<=N; j= !.i /* [↓] find primes, and maybe show 'em*/ - call safeUnsafe; $= strip($) /*go see if other part of a KIND prime.*/ - end /*i*/ /* [↑] allows faster loop (below). */ - /* [↓] N: default lists up to 35 #'s.*/ - do j=!.#+2 by 2 while limN then do; lim= j; m= m-1; end; else call app; return 1 -app: if tell then if length($ j)>w then do; say $; $ =j; end; else $= $ j; return 1 -ser: say; say; say '***error***' arg(1); say; say; exit 13 /*tell error message. */ -commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -safeUnsafe: ?= (j-1) % 2 /*obtain the other part of KIND prime. */ - if safe then if @.? == '' then return 0 /*not a safe prime.*/ - else return add() /*is " " " */ - else if @.? == '' then return add() /*is an unsafe prime.*/ - else return 0 /*not " " " */ +call Primes 1e8 +call FirstSafe +call FirstUnsafe +call CountBoth +say Format(Time('e'),,3) 'seconds' +exit + +FirstSafe: +procedure expose flag. +say 'The first 35 safe primes are...' +n = 0 +do i = 3 by 2 until n = 35 + if flag.i then do + j = (i-1)/2 + if flag.j then do + n = n+1 + call Charout ,Right(i,5) + if n//10 = 0 then + say + end + end +end +say; say +return + +FirstUnsafe: +procedure expose flag. +say 'The first 40 unsafe primes are...' +call charout ,right(2,5); n = 1 +do i = 3 by 2 until n = 40 + if flag.i then do + j = (i-1)/2 + if \ flag.j then do + n = n+1 + call Charout ,Right(i,5) + if n//10 = 0 then + say + end + end +end +say +return + +CountBoth: +procedure expose flag. +s = 0; u = 1; p = 1 +do i = 3 by 2 to 1e8+1 + a = 1'e'p + if i > a then do + say s 'safe primes below 10^'p + say u 'unsafe primes below 10^'p + say + p = p+1 + end + if flag.i then do + j = (i-1)/2; s = s+(flag.j); u = u+(\ flag.j) + end +end +return + +include Sequences +include Functions +include Constants +include Abend diff --git a/Task/Self-describing-numbers/EasyLang/self-describing-numbers.easy b/Task/Self-describing-numbers/EasyLang/self-describing-numbers.easy index c3c8f85f75..d6c13e2600 100644 --- a/Task/Self-describing-numbers/EasyLang/self-describing-numbers.easy +++ b/Task/Self-describing-numbers/EasyLang/self-describing-numbers.easy @@ -1,20 +1,14 @@ -proc test d[] . . +proc test d[] . cnt[] = [ 0 0 0 0 0 0 0 0 0 0 ] - for d in d[] - cnt[d + 1] += 1 - . + for d in d[] : cnt[d + 1] += 1 for i to len d[] - if cnt[i] <> d[i] - return - . + if cnt[i] <> d[i] : return . # found - for d in d[] - write d - . + for d in d[] : write d print "" . -proc backtr ind max . d[] . +proc backtr ind max &d[] . if ind > len d[] test d[] return diff --git a/Task/Self-numbers/EasyLang/self-numbers.easy b/Task/Self-numbers/EasyLang/self-numbers.easy index ceb25d963d..6b5b6ae861 100644 --- a/Task/Self-numbers/EasyLang/self-numbers.easy +++ b/Task/Self-numbers/EasyLang/self-numbers.easy @@ -9,9 +9,7 @@ fastfunc isself start i . j = start sum = digsum start while j < i - if j + sum = i - return 0 - . + if j + sum = i : return 0 sum += 1 j += 1 if j mod 10 = 0 @@ -20,7 +18,7 @@ fastfunc isself start i . . return 1 . -proc main . . +proc main . i = 1 po = 10 digits = 1 @@ -29,9 +27,7 @@ proc main . . start = higher (i - offs) 0 if isself start i = 1 cnt += 1 - if cnt <= 50 - write i & " " - . + if cnt <= 50 : write i & " " . until cnt = 100000000 i += 1 diff --git a/Task/Semiprime/REXX/semiprime-2.rexx b/Task/Semiprime/REXX/semiprime-2.rexx index a05a39e14d..0ffff305e5 100644 --- a/Task/Semiprime/REXX/semiprime-2.rexx +++ b/Task/Semiprime/REXX/semiprime-2.rexx @@ -1,35 +1,36 @@ -/*REXX program determines if any integer (or a range of integers) is/are semiprime. */ -parse arg bot top . /*obtain optional arguments from the CL*/ -if bot=='' | bot=="," then bot=random() /*None given? User wants us to guess.*/ -if top=='' | top=="," then top=bot /*maybe define a range of numbers. */ -tell= top=>0 | top==bot /*should results be shown to the term? */ -w=max(length(bot), length(top)) + 5 /*obtain the maximum width of numbers. */ -numeric digits max(9, w) /*ensure there're enough decimal digits*/ -#=0 /*initialize number of semiprimes found*/ - do n=bot to abs(top) /*show results for a range of numbers. */ - ?=isSemiPrime(n); #=#+? /*Is N a semiprime?; Maybe bump counter*/ - if tell then say right(n,w) right(word("isn't" 'is', ?+1), 6) 'semiprime.' - end /*n*/ -say -if bot\==top then say 'found ' # " semiprimes." -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure; parse arg x; if x<2 then return 0 /*number too low?*/ - if wordpos(x, '2 3 5 7 11 13 17 19 23')\==0 then return 1 /*it's low prime.*/ - if x//2==0 then return 0; if x//3==0 then return 0 /*÷ by 2; ÷ by 3?*/ - do j=5 by 6 until j*j>x; if x//j==0 then return 0 /*not a prime. */ - if x//(j+2)==0 then return 0 /* " " " */ - end /*j*/ - return 1 /*indicate that X is a prime number. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isSemiPrime: procedure; parse arg x; if x<4 then return 0 +include Settings - do i=2 for 2; if x//i==0 then if isPrime(x%i) then return 1 - else return 0 - end /*i*/ - /* ___ */ - do j=5 by 6; if j*j>x then return 0 /* > √ x ?*/ - do k=j by 2 for 2; if x//k==0 then if isPrime(x%k) then return 1 - else return 0 - end /*k*/ /* [↑] see if 2nd factor is prime or ¬*/ - end /*j*/ /* [↑] J is never a multiple of three.*/ +say 'SEMIPRIME - 4 Mar 2025' +say version +say +numeric digits 100 +call Sequence 1,200 +call Sequence 100001,100200 +call Sequence 1000000001,1000000200 +call Sequence 158456325028528675187087900601,158456325028528675187087900660 +exit + +Sequence: +arg xx,yy +say 'Semiprimes between' xx 'to' yy +if yy = '' then + yy = xx +l = length(yy)+1 +n = 0 +do i = xx to yy + if Semiprime(i) then do + n = n+1 + call Charout ,right(i,l) + if n//5 = 0 then + say + end +end +say +say Format(Time('e'),,3) 'seconds' +say +return + +include Functions +include Numbers +include Sequences +include Abend diff --git a/Task/Semiprime/REXX/semiprime-3.rexx b/Task/Semiprime/REXX/semiprime-3.rexx deleted file mode 100644 index be871d5d54..0000000000 --- a/Task/Semiprime/REXX/semiprime-3.rexx +++ /dev/null @@ -1,41 +0,0 @@ -/*REXX program determines if any integer (or a range of integers) is/are semiprime. */ -parse arg bot top . /*obtain optional arguments from the CL*/ -if bot=='' | bot=="," then bot=random() /*None given? User wants us to guess.*/ -if top=='' | top=="," then top=bot /*maybe define a range of numbers. */ -tell= bot=>0 & top=>0 /*should results be shown to the term? */ -w=max(length(bot), length(top)) /*obtain the maximum width of numbers. */ -!.=; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1; !.13=1; !.17=1; !.19=1; !.23=1; !.29=1; !.31=1 -numeric digits max(9, w) /*ensure there're enough decimal digits*/ -#=0 /*initialize number of semiprimes found*/ - do n=abs(bot) to abs(top) /*show results for a range of numbers. */ - ?=isSemiPrime(n); #=#+? /*Is N a semiprime?; Maybe bump counter*/ - if tell then say right(n,w) right(word("isn't" 'is', ?+1), 6) 'semiprime.' - end /*n*/ -say -if bot\==top then say 'found ' # " semiprimes." -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure expose !.; parse arg x; if x<2 then return 0 /*number too low?*/ - if !.x==1 then return 1 /*a known prime. */ - if x// 2==0 then return 0; if x//3==0 then return 0 /*÷ by 2;÷by 3?*/ - parse var x '' -1 _; if _==5 then return 0 /*last digit a 5?*/ - if x// 7==0 then return 0; if x//11==0 then return 0 /*÷ by 7;÷by 11?*/ - if x//13==0 then return 0; if x//17==0 then return 0 /*÷ by 13;÷by 17?*/ - if x//19==0 then return 0; if x//23==0 then return 0 /*÷ by 19;÷by 23?*/ - do j=29 by 6 until j*j>x; if x//j==0 then return 0 /*not a prime. */ - if x//(j+2)==0 then return 0 /* " " " */ - end /*j*/ - !.x=1; return 1 /*indicate that X is a prime number. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isSemiPrime: procedure expose !.; parse arg x; if x<4 then return 0 - - do i=2 for 2; if x//i==0 then if isPrime(x%i) then return 1 - else return 0 - end /*i*/ - /* ___ */ - do j=5 by 6 until j*j>x /* > √ x ?*/ - do k=j by 2 for 2; if x//k==0 then if isPrime(x%k) then return 1 - else return 0 - end /*k*/ /* [↑] see if 2nd factor is prime or ¬*/ - end /*j*/ /* [↑] J is never a multiple of three.*/ - return 0 diff --git a/Task/Semiprime/REXX/semiprime-4.rexx b/Task/Semiprime/REXX/semiprime-4.rexx deleted file mode 100644 index 2b18d15b4f..0000000000 --- a/Task/Semiprime/REXX/semiprime-4.rexx +++ /dev/null @@ -1,57 +0,0 @@ -/*REXX program determines if any integer (or a range of integers) is/are semiprime. */ -/*REXX program determines if any integer (or a range of integers) is/are semiprime. */ -include Settings - -say version; say 'Semi Primes'; say -parse arg bot top . /*obtain optional arguments from the CL*/ -if bot=='' | bot=="," then bot=Random() /*None givenqq User wants us to guess.*/ -if top=='' | top=="," then top=bot /*maybe define a range of numbers. */ -tell= (top>0) /*should results be shown to the termqq */ -w=Max(Length(bot), Length(top)) /*obtain the maximum width of numbers. */ -numeric digits Max(9, w) /*ensure there're enough decimal digits*/ -hh=0 /*initialize Number of semiprimes found*/ - do n=Abs(bot) to Abs(top) /*show results for a range of numbers. */ - qq=IsSemiPrime(n); hh=hh+qq /*Is N a semiprimeqq; Maybe bump counter*/ -if tell then say Right(n,w) Right(Word("isn't" 'is', qq+1), 6) 'Semiprime.' '('Format(Time('e'),,3) 'seconds)' -call Time('r') - end /*n*/ -say -if bot\==top then say 'found ' hh " semiprimes." -say Format(Time('e'),,3) ' seconds' -exit /*stick a fork in it, we're all done. */ - -IsSemiprime: -/* Is a number semi prime? function */ -procedure expose glob. -arg x -/* Low semiprimes */ -s = '4 6 9 10 14 15 21 22 25 26 33 34 35 38 39 46 49 51 55 57 58 62 65 69 74 77 82 85 86 87 91 93 94 95' -/* Fast values */ -if x < 101 then do - if Wordpos(x,s) = 0 then - return 0 - else - return 1 -end -/* Wheeled scan */ -do i = 2 for 2 - if x//i = 0 then - if Prime(x%i) then - return 1 - else - return 0 -end -do i = 5 by 6 until i*i > x - do j = i by 2 for 2 - if x//j==0 then - if Prime(x%j) then - return 1 - else - return 0 - end -end -return 0 - -include Functions -include Numbers -include Abend diff --git a/Task/Semordnilap/R/semordnilap.r b/Task/Semordnilap/R/semordnilap.r new file mode 100644 index 0000000000..e0cd0022e9 --- /dev/null +++ b/Task/Semordnilap/R/semordnilap.r @@ -0,0 +1,17 @@ +library(stringi) + +unixdict <- read.table("unixdict.txt", col.names="forwards") +unixdict$backwards <- stri_reverse(unixdict$forwards) + +#Remove all actual palindromes, as we do not want those +unixdict <- subset(unixdict, forwards!=backwards) + +for(i in seq_along(unixdict$forwards)){ + unixdict$issemordnilap[i] <- with(unixdict, forwards[i] %in% backwards) +} + +semordnilaps <- subset(unixdict, (issemordnilap==TRUE)&(forwards>backwards), select=-issemordnilap) +length(semordnilaps$forwards) + +random <- sample(seq_along(semordnilaps$forwards), 5, replace=FALSE) +print(semordnilaps[random,], row.names=FALSE) diff --git a/Task/Sequence-of-primes-by-trial-division/ALGOL-60/sequence-of-primes-by-trial-division.alg b/Task/Sequence-of-primes-by-trial-division/ALGOL-60/sequence-of-primes-by-trial-division.alg new file mode 100644 index 0000000000..960870975a --- /dev/null +++ b/Task/Sequence-of-primes-by-trial-division/ALGOL-60/sequence-of-primes-by-trial-division.alg @@ -0,0 +1,46 @@ +begin + +comment - return n mod m; +integer procedure mod(n, m); + value n, m; integer n, m; +begin + mod := n - entier(n / m) * m; +end; + +integer i, k, m, n, sq, nprimes; +boolean divisible; + +nprimes := 20; +outstring(1,"Showing first"); +outinteger(1, nprimes); +outstring(1,"prime numbers\n"); +begin + integer array p[1:nprimes]; + comment - initialize p with first (and only even) prime; + p[1] := 2; + outinteger(1, p[1]); + i := 1; comment - count of primes found so far; + k := 1; comment - index of largest prime <= sqrt of n; + n := 3; comment - current number being checked; + for i := i while i < nprimes do + begin + sq := p[k] * p[k]; + if sq <= n then k := k + 1; + divisible := false; + m := 2; comment - index of possible divisors; + for m := m while m <= k and not divisible do + begin + if mod(n, p[m]) = 0 then divisible := true; + m := m + 1; + end; + if not divisible then + begin + i := i + 1; + p[i] := n; + outinteger(1, n); + end; + n := n + 2; + end; + end; + +end diff --git a/Task/Sequence-of-primes-by-trial-division/EasyLang/sequence-of-primes-by-trial-division.easy b/Task/Sequence-of-primes-by-trial-division/EasyLang/sequence-of-primes-by-trial-division.easy index 62bcc99d7a..260f62bfde 100644 --- a/Task/Sequence-of-primes-by-trial-division/EasyLang/sequence-of-primes-by-trial-division.easy +++ b/Task/Sequence-of-primes-by-trial-division/EasyLang/sequence-of-primes-by-trial-division.easy @@ -1,21 +1,14 @@ -func prime n . - if n mod 2 = 0 and n > 2 - return 0 - . - i = 3 - while i <= sqrt n - if n mod i = 0 - return 0 - . - i += 2 +fastfunc isprim num . + i = 2 + while i <= sqrt num + if num mod i = 0 : return 0 + i += 1 . return 1 . -proc primeSequ first last . sequ[] . +proc primeSequ first last &sequ[] . for i = first to last - if prime i = 1 - sequ[] &= i - . + if isprim i = 1 : sequ[] &= i . . primeSequ 2 100 seq[] diff --git a/Task/Sequence-of-primes-by-trial-division/PascalABC.NET/sequence-of-primes-by-trial-division.pas b/Task/Sequence-of-primes-by-trial-division/PascalABC.NET/sequence-of-primes-by-trial-division.pas index eee758aeaa..b30e4b8816 100644 --- a/Task/Sequence-of-primes-by-trial-division/PascalABC.NET/sequence-of-primes-by-trial-division.pas +++ b/Task/Sequence-of-primes-by-trial-division/PascalABC.NET/sequence-of-primes-by-trial-division.pas @@ -1,4 +1,4 @@ ## -function IsPrime(n: integer) := (2..n.Sqrt.Round).All(i -> n.NotDivs(i)); +function IsPrime(n: integer) := (2..n.Sqrt.Trunc).All(i -> n.NotDivs(i)); (2..100).Where(IsPrime).Println diff --git a/Task/Sequence-of-primes-by-trial-division/REXX/sequence-of-primes-by-trial-division-1.rexx b/Task/Sequence-of-primes-by-trial-division/REXX/sequence-of-primes-by-trial-division-1.rexx deleted file mode 100644 index 2874c730e3..0000000000 --- a/Task/Sequence-of-primes-by-trial-division/REXX/sequence-of-primes-by-trial-division-1.rexx +++ /dev/null @@ -1,18 +0,0 @@ -/*REXX program lists a sequence of primes by testing primality by trial division. */ -parse arg n . /*get optional number of primes to find*/ -if n=='' | n=="," then n= 26 /*Not specified? Then use the default.*/ -tell= (n>0); n= abs(n) /*Is N negative? Then don't display.*/ -@.1=2; if tell then say right(@.1, 9) /*display 2 as a special prime case. */ -#=1 /*# is number of primes found (so far)*/ - /* [↑] N: default lists up to 101 #s.*/ - do j=3 by 2 while #0); N= abs(N) /*N is negative? Then don't display. */ -@.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13; #= 5; s= @.# + 2 - /* [↑] is the number of low primes.*/ - do p=1 for # while p<=N /* [↓] find primes, and maybe show 'em*/ - if tell then say right(@.p, 9) /*display some pre─defined low primes. */ - !.p= @.p**2 /*also compute the squared value of P. */ - end /*p*/ /* [↑] allows faster loop (below). */ - /* [↓] N: default lists up to 101 #s.*/ - do j=s by 2 while # memo = []; +var n = 0; +var start = DateTime.Now; + +for (var count = 1; count <= 100; count++) +{ + Write($"{count}: "); + + // Did we already see this count from a smaller n? + if (memo.TryGetValue(count, out var k)) + { + WriteLine(k); + continue; + } + + // Count is prime or 1? + if (CountDivisors(count) <= 2) + { + k = BigInteger.One << (count - 1); // 2^(count-1) + WriteLine(k); + continue; + } + + // Count is 2 × prime? + if (count % 2 == 0 && CountDivisors(count / 2) == 2) + { + k = (BigInteger.One << (count / 2 - 1)) * 3; // 3⁽²⁻¹⁾ + WriteLine(k); + continue; + } + + // Count is 3 × prime? + if (count % 3 == 0 && CountDivisors(count / 3) == 2) + { + k = (BigInteger.One << (count / 3 - 1)) * 9; // 3⁽³⁻¹⁾ + WriteLine(k); + continue; + } + + // Count is 4 × prime? + if (count >= 16 && count % 4 == 0 && CountDivisors(count / 4) == 2) + { + // 4 is factored as 2x2 giving 3⁽²⁻¹⁾5⁽²⁻¹⁾ = 3·5 which is less than 3⁽⁴⁻¹⁾ = 27 + k = (BigInteger.One << (count / 4 - 1)) * 15; + WriteLine(k); + continue; + } + + // Etc. + if (count >= 25 && count % 5 == 0 && CountDivisors(count / 5) == 2) + { + k = (BigInteger.One << (count / 5 - 1)) * 81; // 3⁽⁵⁻¹⁾ + WriteLine(k); + continue; + } + + if (count >= 36 && count % 6 == 0 && CountDivisors(count / 6) == 2) + { + k = (BigInteger.One << (count / 6 - 1)) * 45; // 3⁽³⁻¹⁾5⁽²⁻¹⁾ = 9·5 + WriteLine(k); + continue; + } + + if (count >= 49 && count % 7 == 0 && CountDivisors(count / 7) == 2) + { + k = (BigInteger.One << (count / 7 - 1)) * 729; // 3⁽⁷⁻¹⁾ + WriteLine(k); + continue; + } + + // Otherwise just try each number until we find a match + while (true) + { + ++n; + var d = CountDivisors(n); + + if (d == count) + break; + + // Save this one for later + if (d > count && !memo.ContainsKey(d)) + memo[d] = n; + } + + WriteLine(n); +} + +WriteLine($"Elapsed time: {(DateTime.Now - start).TotalMilliseconds:0}ms"); diff --git a/Task/Set-puzzle/EasyLang/set-puzzle.easy b/Task/Set-puzzle/EasyLang/set-puzzle.easy index 876402c56a..fdd59e2387 100644 --- a/Task/Set-puzzle/EasyLang/set-puzzle.easy +++ b/Task/Set-puzzle/EasyLang/set-puzzle.easy @@ -4,28 +4,25 @@ attr$[][] &= [ "red " "green " "purple" ] attr$[][] &= [ "diamond" "oval" "squiggle" ] # subr init - for card = 0 to 80 - pack[] &= card - . + for card = 0 to 80 : pack[] &= card . -proc card2attr card . attr[] . +proc card2attr card &attr[] . attr[] = [ ] for i to 4 attr[] &= card mod 3 + 1 card = card div 3 . . -proc printcards cards[] . . +proc printcards cards[] . for card in cards[] card2attr card attr[] - for i to 4 - write attr$[i][attr[i]] & " " - . + write " " + for i to 4 : write attr$[i][attr[i]] & " " print "" . print "" . -proc getsets . cards[] set[] . +proc getsets &cards[] &set[] . set[] = [ ] for i to len cards[] card2attr cards[i] a[] @@ -36,9 +33,7 @@ proc getsets . cards[] set[] . ok = 1 for at to 4 s = a[at] + b[at] + c[at] - if s <> 3 and s <> 6 and s <> 9 - ok = 0 - . + if s <> 3 and s <> 6 and s <> 9 : ok = 0 . if ok = 1 set[] &= cards[i] @@ -49,8 +44,7 @@ proc getsets . cards[] set[] . . . . -proc run ncards nsets . . - # +proc run ncards nsets . repeat init cards[] = [ ] @@ -71,5 +65,3 @@ proc run ncards nsets . . . . run 9 4 -print " --------------------------" -run 12 6 diff --git a/Task/Set-puzzle/JavaScript/set-puzzle.js b/Task/Set-puzzle/JavaScript/set-puzzle.js new file mode 100644 index 0000000000..0774e4fc66 --- /dev/null +++ b/Task/Set-puzzle/JavaScript/set-puzzle.js @@ -0,0 +1,86 @@ +// Constants +const number = ["1", "2", "3"]; +const color = ["red", "green", "purple"]; +const shade = ["solid", "open", "striped"]; +const shape = ["oval", "squiggle", "diamond"]; + +// Card class +class Card { + constructor(value) { + this.value = value; + } + + toString() { + return `${number[Math.floor(this.value/27)]} ${color[Math.floor(this.value/9)%3]} ${shade[Math.floor(this.value/3)%3]} ${shape[this.value%3]}`; + } +} + +// Shuffle an array +function shuffle(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } +} + +// Main game function +function game(level, cards, sets) { + // Create deck + const deck = []; + for (let i = 0; i < 81; i++) { + deck.push(new Card(i)); + } + + let found = []; + while (found.length !== sets) { + found = []; + + // Deal + shuffle(deck); + + // Consider all triplets + for (let i = 2; i < cards; i++) { + const c1 = deck[i]; + for (let j = 1; j < i; j++) { + const c2 = deck[j]; + + outer: for (let k = 0; k < j; k++) { + const c3 = deck[k]; + + // Check if it's a set + for (let f = 1; f < 81; f *= 3) { + if ((Math.floor(c1.value/f)%3 + Math.floor(c2.value/f)%3 + Math.floor(c3.value/f)%3) % 3 !== 0) { + continue outer; // not a set + } + } + + // It's a set + found.push([c1, c2, c3]); + } + } + } + } + + // Output results + console.log(`${level} game. ${cards} cards, ${sets} sets.`); + console.log("Cards:"); + for (let i = 0; i < cards; i++) { + console.log(" ", deck[i].toString()); + } + + console.log("Sets:"); + for (const set of found) { + console.log(` ${set[0]}\n ${set[1]}\n ${set[2]}`); + } +} + +// Run the games +function main() { + // Set random seed with current time + Math.random(); + + game("Basic", 9, 4); + game("Advanced", 12, 6); +} + +main(); diff --git a/Task/Set-right-adjacent-bits/EasyLang/set-right-adjacent-bits.easy b/Task/Set-right-adjacent-bits/EasyLang/set-right-adjacent-bits.easy index 92b6e3a8ac..dfe6134bd5 100644 --- a/Task/Set-right-adjacent-bits/EasyLang/set-right-adjacent-bits.easy +++ b/Task/Set-right-adjacent-bits/EasyLang/set-right-adjacent-bits.easy @@ -1,4 +1,4 @@ -proc adjacent txt$ n . . +proc adjacent txt$ n . print "n = " & n & ", width = " & len txt$ print "input: " & txt$ txt$[] = strchars txt$ diff --git a/Task/Seven-sided-dice-from-five-sided-dice/EasyLang/seven-sided-dice-from-five-sided-dice.easy b/Task/Seven-sided-dice-from-five-sided-dice/EasyLang/seven-sided-dice-from-five-sided-dice.easy index 7bfb89acf3..52487b481e 100644 --- a/Task/Seven-sided-dice-from-five-sided-dice/EasyLang/seven-sided-dice-from-five-sided-dice.easy +++ b/Task/Seven-sided-dice-from-five-sided-dice/EasyLang/seven-sided-dice-from-five-sided-dice.easy @@ -14,16 +14,14 @@ func dice7b . . return h mod1 7 . -numfmt 3 0 +numfmt 0 3 n = 1000000 len dist[] 7 # -proc checkdist . . +proc checkdist . for i to len dist[] h = dist[i] / n * 7 - if abs (h - 1) > 0.01 - bad = 1 - . + if abs (h - 1) > 0.01 : bad = 1 dist[i] = 0 print h . diff --git a/Task/Sexy-primes/EasyLang/sexy-primes.easy b/Task/Sexy-primes/EasyLang/sexy-primes.easy index ade3d0377c..9e9f08a77a 100644 --- a/Task/Sexy-primes/EasyLang/sexy-primes.easy +++ b/Task/Sexy-primes/EasyLang/sexy-primes.easy @@ -1,5 +1,5 @@ len isdiv[] 1000035 -proc sieve . . +proc sieve . max = sqrt len isdiv[] for d = 2 to max if isdiv[d] = 0 @@ -11,7 +11,7 @@ proc sieve . . . sieve # -proc showsx nr . . +proc showsx nr . for i = len isdiv[] - 6 * nr downto 3 if isdiv[i] = 0 h = 0 @@ -39,7 +39,7 @@ proc showsx nr . . . print "" . -proc showunsx . . +proc showunsx . for i = len isdiv[] - 6 downto 2 if isdiv[i] = 0 and isdiv[i + 6] = 1 and (i <= 6 or isdiv[i - 6] = 1) cnt += 1 diff --git a/Task/Sexy-primes/REXX/sexy-primes.rexx b/Task/Sexy-primes/REXX/sexy-primes.rexx index 8be9f90333..a73774cf2a 100644 --- a/Task/Sexy-primes/REXX/sexy-primes.rexx +++ b/Task/Sexy-primes/REXX/sexy-primes.rexx @@ -1,88 +1,73 @@ -/*REXX program finds and displays various kinds of sexy and unsexy primes less than N.*/ -parse arg N endU end2 end3 end4 end5 . /*obtain optional argument from the CL.*/ -if N=='' | N=="," then N= 1000035 - 1 /*Not specified? Then use the default.*/ -if endU=='' | endU=="," then endU= 10 /* " " " " " " */ -if end2=='' | end2=="," then end2= 5 /* " " " " " " */ -if end3=='' | end3=="," then end3= 5 /* " " " " " " */ -if end4=='' | end4=="," then end4= 5 /* " " " " " " */ -if end5=='' | end5=="," then end4= 5 /* " " " " " " */ -call genSq /*gen some squares for the DO k=7 UNTIL*/ -call genPx /* " prime (@.) & sexy prime (X.) array*/ -call genXU /*gen lists, types of sexy Ps, unsexy P*/ -call getXs /*gen lists, last # of types of sexy Ps*/ - @sexy= ' sexy prime' /*a handy literal for some of the SAYs.*/ - w2= words( translate(x2,, '~') ); y2= words(x2) /*count #primes in the sexy pairs. */ - w3= words( translate(x3,, '~') ); y3= words(x3) /* " " " " " " triplets. */ - w4= words( translate(x4,, '~') ); y4= words(x4) /* " " " " " " quadruplets*/ - w5= words( translate(x5,, '~') ); y5= words(x5) /* " " " " " " quintuplets*/ -say 'There are ' commas(w2%2) @sexy "pairs less than " Nc -say 'The last ' commas(end2) @sexy "pairs are:"; say subword(x2, max(1,y2-end2+1)) +-- 12 Apr 2025 +include Settings + +call Time('r') +say 'SEXY PRIMES' +say version say -say 'There are ' commas(w3%3) @sexy "triplets less than " Nc -say 'The last ' commas(end3) @sexy "triplets are:"; say subword(x3, max(1,y3-end3+1)) +call GetPrimes 1e6+34 +call ShowCount +say Format(Time('e'),,3) 'seconds' +exit + +GetPrimes: +procedure expose prim. flag. +arg xx +say 'Get primes up to' xx'...' +call Primes xx +say prim.0 'found' say -say 'There are ' commas(w4%4) @sexy "quadruplets less than " Nc -say 'The last ' commas(end4) @sexy "quadruplets are:"; say subword(x4, max(1,y4-end4+1)) +return + +ShowCount: +procedure expose prim. flag. +arg xx +sexy. = 0; last. = 0 +do i = prim.0 by -1 to 2 + a = prim.i; b = a-6; c = a+6 + if \ flag.b & \ flag.c then do + sexy.0 = sexy.0+1; d = last.0.0 + if d < 11 then do + d = d+1; last.0.d = a; last.0.0 = d + end + iterate i + end + b = a + do n = 1 to 4 + b = b-6 + if flag.b then do + sexy.n = sexy.n+1; d = last.n.0 + if d < 5 then do + d = d+1; last.n.d = b; last.n.0 = d + end + end + else + iterate i + end +end +w = 'pairs triplets quadruplets quintuplets' +do i = 1 to 4 + say sexy.i word(w,i) 'ending with' + do j = 5 by -1 to 1 + a = last.i.j + if a > 0 then do + do k = 1 to i+1 + call Charout ,a' ' + a = a+6 + end + say + end + end + say +end +say sexy.0 'unsexy ending with' +do j = 11 by -1 to 2 + call Charout ,last.0.j' ' +end say -say 'There is ' commas(w5%5) @sexy "quintuplet less than " Nc -say 'The last ' commas(end4) @sexy "quintuplet are:"; say subword(x5, max(1,y5-end4+1)) say -say 'There are ' commas(s1) " sexy primes less than " Nc -say 'There are ' commas(u1) " unsexy primes less than " Nc -say 'The last ' commas(endU) " unsexy primes are: " subword(u, max(1,u1-endU+1)) -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: procedure; parse arg _; n= _'.9'; #= 123456789; b= verify(n, #, "M") - e= verify(n, #'0', , verify(n, #"0.", 'M') ) - 4 - do j=e to b by -3; _= insert(',', _, j); end /*j*/; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genSQ: do i=17 by 2 until i**2 > N+7; s.i= i**2; end; return /*S used for square roots*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genPx: @.=; #= 0; !.= 0. /*P array; P count; sexy P array*/ - if N>1 then do; #= 1; @.1= 2; !.2= 1; end /*count of primes found (so far)*/ - x.=!.; LPs=3 5 7 11 13 17 /*sexy prime array; low P list.*/ - do j=3 by 2 to N+6 /*start in the cellar & work up.*/ - if j<19 then if wordpos(j, LPs)==0 then iterate - else do; #= #+1; @.#= j; !.j= 1; b= j - 6 - if !.b then x.b= 1; iterate - end - if j// 3 ==0 then iterate /* ··· and eliminate multiples of 3.*/ - parse var j '' -1 _ /* get the rightmost digit of J. */ - if _ ==5 then iterate /* ··· and eliminate multiples of 5.*/ - if j// 7 ==0 then iterate /* ··· " " " " 7.*/ - if j//11 ==0 then iterate /* ··· " " " " 11.*/ - if j//13 ==0 then iterate /* ··· " " " " 13.*/ - do k=7 until s._ > j; _= @.k /*÷ by primes starting at 7th prime. */ - if j // _ == 0 then iterate j /*get the remainder of j÷@.k ___ */ - end /*k*/ /*divide up through & including √ J */ - if j<=N then do; #= #+1; @.#= j; end /*bump P counter; assign prime to @.*/ - !.j= 1 /*define Jth number as being prime.*/ - b= j - 6 /*B: lower part of a sexy prime pair?*/ - if !.b then do; x.b=1; if j<=N then x.j=1; end /*assign (both parts ?) sexy Ps.*/ - end /*j*/; return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genXU: u= 2; Nc=commas(N+1); s= /*1st unsexy prime; add commas to N+1*/ - say 'There are ' commas(#) " primes less than " Nc; say - do k=2 for #-1; p= @.k; if x.p then s=s p /*if sexy prime, add it to list*/ - else u= u p /* " unsexy " " " " " */ - end /*k*/ /* [↑] traispe through odd Ps. */ - s1= words(s); u1= words(u); return /*# of sexy primes; # unsexy primes.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -getXs: x2=; do k=2 for #-1; p=@.k; if \x.p then iterate /*build sexy prime list. */ - b=p- 6; if \x.b then iterate; x2=x2 b'~'p - end /*k*/ - x3=; do k=2 for #-1; p=@.k; if \x.p then iterate /*build sexy P triplets. */ - b=p- 6; if \x.b then iterate - t=p-12; if \x.t then iterate; x3=x3 t'~' || b"~"p - end /*k*/ - x4=; do k=2 for #-1; p=@.k; if \x.p then iterate /*build sexy P quads. */ - b=p- 6; if \x.b then iterate - t=p-12; if \x.t then iterate - q=p-18; if \x.q then iterate; x4=x4 q'~'t"~" || b'~'p - end /*k*/ - x5=; do k=2 for #-1; p=@.k; if \x.p then iterate /*build sexy P quints. */ - b=p- 6; if \x.b then iterate - t=p-12; if \x.t then iterate - q=p-18; if \x.q then iterate - v=p-24; if \x.v then iterate; x5=x5 v'~'q"~"t'~' || b"~"p - end /*k*/; return +return + +include Sequences +include Functions +include Abend diff --git a/Task/Shoelace-formula-for-polygonal-area/EasyLang/shoelace-formula-for-polygonal-area.easy b/Task/Shoelace-formula-for-polygonal-area/EasyLang/shoelace-formula-for-polygonal-area.easy index 327b4c349d..32bbcd3d78 100644 --- a/Task/Shoelace-formula-for-polygonal-area/EasyLang/shoelace-formula-for-polygonal-area.easy +++ b/Task/Shoelace-formula-for-polygonal-area/EasyLang/shoelace-formula-for-polygonal-area.easy @@ -1,13 +1,11 @@ -proc shoelace . p[][] res . - sum = 0 +func shoelace &p[][] . for i = 1 to len p[][] - 1 sum += p[i][1] * p[i + 1][2] sum -= p[i + 1][1] * p[i][2] . sum += p[i][1] * p[1][2] sum -= p[1][1] * p[i][2] - res = abs sum / 2 + return abs sum / 2 . data[][] = [ [ 3 4 ] [ 5 11 ] [ 12 8 ] [ 9 5 ] [ 5 6 ] ] -shoelace data[][] res -print res +print shoelace data[][] diff --git a/Task/Shoelace-formula-for-polygonal-area/Rust/shoelace-formula-for-polygonal-area.rs b/Task/Shoelace-formula-for-polygonal-area/Rust/shoelace-formula-for-polygonal-area.rs new file mode 100644 index 0000000000..47f98f3139 --- /dev/null +++ b/Task/Shoelace-formula-for-polygonal-area/Rust/shoelace-formula-for-polygonal-area.rs @@ -0,0 +1,25 @@ +fn shoelace(points: &[(f64, f64)]) -> f64 { + let mut left_sum = 0.0; + let mut right_sum = 0.0; + + for i in 0..points.len() { + let j = (i + 1) % points.len(); + left_sum += points[i].0 * points[j].1; + right_sum += points[j].0 * points[i].1; + } + + 0.5 * (left_sum - right_sum).abs() +} + +fn main() { + let points: Vec<(f64, f64)> = vec![ + (3.0, 4.0), + (5.0, 11.0), + (12.0, 8.0), + (9.0, 5.0), + (5.0, 6.0), + ]; + + let ans = shoelace(&points); + println!("{}", ans); +} diff --git a/Task/Show-ASCII-table/EasyLang/show-ascii-table.easy b/Task/Show-ASCII-table/EasyLang/show-ascii-table.easy index 363ed710b2..9ada74d0c2 100644 --- a/Task/Show-ASCII-table/EasyLang/show-ascii-table.easy +++ b/Task/Show-ASCII-table/EasyLang/show-ascii-table.easy @@ -1,4 +1,4 @@ -numfmt 0 3 +numfmt 3 0 for i range0 16 for j = 32 + i step 16 to 127 if j = 32 diff --git a/Task/Sierpinski-arrowhead-curve/EasyLang/sierpinski-arrowhead-curve.easy b/Task/Sierpinski-arrowhead-curve/EasyLang/sierpinski-arrowhead-curve.easy index 265b0204e3..a10991eb9c 100644 --- a/Task/Sierpinski-arrowhead-curve/EasyLang/sierpinski-arrowhead-curve.easy +++ b/Task/Sierpinski-arrowhead-curve/EasyLang/sierpinski-arrowhead-curve.easy @@ -1,13 +1,15 @@ x = 5 y = 10 ang = 60 -linewidth 0.5 +glinewidth 0.5 # -proc curv o l a . . +proc curv o l a . if o = 0 + px = x + py = y x += cos ang * l y += sin ang * l - line x y + gline px py x y else o -= 1 l /= 2 @@ -18,5 +20,4 @@ proc curv o l a . . curv o l (-a) . . -move x y curv 7 90 -60 diff --git a/Task/Sierpinski-carpet/EasyLang/sierpinski-carpet.easy b/Task/Sierpinski-carpet/EasyLang/sierpinski-carpet.easy index d4bf14c923..070ed36b34 100644 --- a/Task/Sierpinski-carpet/EasyLang/sierpinski-carpet.easy +++ b/Task/Sierpinski-carpet/EasyLang/sierpinski-carpet.easy @@ -1,6 +1,5 @@ -proc carp x y sz . . - move x - sz / 2 y - sz / 2 - rect sz sz +proc carp x y sz . + grect x - sz / 2 y - sz / 2 sz sz if sz > 0.5 h = sz / 3 carp x - sz y - sz h @@ -13,7 +12,7 @@ proc carp x y sz . . carp x y + sz h . . -background 000 -clear -color 633 +gbackground 000 +gclear +gcolor 633 carp 50 50 100 / 3 diff --git a/Task/Sierpinski-pentagon/EasyLang/sierpinski-pentagon.easy b/Task/Sierpinski-pentagon/EasyLang/sierpinski-pentagon.easy index 385eed3747..6e916e0a21 100644 --- a/Task/Sierpinski-pentagon/EasyLang/sierpinski-pentagon.easy +++ b/Task/Sierpinski-pentagon/EasyLang/sierpinski-pentagon.easy @@ -1,16 +1,18 @@ order = 5 # -clear -linewidth 0.2 +gclear +glinewidth 0.2 scale = 1 / (2 + cos 72 * 2) # -proc pentagon x y side depth . . +proc pentagon x y side depth . if depth = 0 move x y for angle = 0 step 72 to 288 + px = x + py = y x += cos angle * side y += sin angle * side - line x y + gline px py x y . else side *= scale diff --git a/Task/Sierpinski-square-curve/EasyLang/sierpinski-square-curve.easy b/Task/Sierpinski-square-curve/EasyLang/sierpinski-square-curve.easy index 99fbca096e..67a22b4578 100644 --- a/Task/Sierpinski-square-curve/EasyLang/sierpinski-square-curve.easy +++ b/Task/Sierpinski-square-curve/EasyLang/sierpinski-square-curve.easy @@ -1,4 +1,4 @@ -proc lsysexp level . axiom$ rules$[] . +proc lsysexp level &axiom$ &rules$[] . for l to level an$ = "" for c$ in strchars axiom$ @@ -13,14 +13,15 @@ proc lsysexp level . axiom$ rules$[] . swap axiom$ an$ . . -proc lsysdraw axiom$ x y ang lng . . - linewidth 0.3 - move x y +proc lsysdraw axiom$ x y ang lng . + glinewidth 0.3 for c$ in strchars axiom$ if c$ = "F" + xp = x + yp = y x += cos dir * lng y += sin dir * lng - line x y + gline xp yp x y elif c$ = "-" dir -= ang elif c$ = "+" diff --git a/Task/Sierpinski-triangle-Graphical/EasyLang/sierpinski-triangle-graphical.easy b/Task/Sierpinski-triangle-Graphical/EasyLang/sierpinski-triangle-graphical.easy index 94d4deb12c..ad1b1af585 100644 --- a/Task/Sierpinski-triangle-Graphical/EasyLang/sierpinski-triangle-graphical.easy +++ b/Task/Sierpinski-triangle-Graphical/EasyLang/sierpinski-triangle-graphical.easy @@ -1,7 +1,6 @@ -proc triang lev x y size . . +proc triang lev x y size . if lev = 0 - move x y - circle 0.15 + gcircle x y 0.15 else lev -= 1 size /= 2 diff --git a/Task/Sierpinski-triangle/Uxntal/sierpinski-triangle.uxnatl b/Task/Sierpinski-triangle/Uxntal/sierpinski-triangle.uxnatl index 5fe1af088c..228f499d0f 100644 --- a/Task/Sierpinski-triangle/Uxntal/sierpinski-triangle.uxnatl +++ b/Task/Sierpinski-triangle/Uxntal/sierpinski-triangle.uxnatl @@ -1,23 +1,15 @@ -( uxncli sierpinski.rom ) - -|100 @on-reset ( -> ) - - #10 STHk #01 SUB - &ver ( -- ) - DUP - #00 EQUk ?{ - &pad ( -- ) - #2018 DEO - INC GTHk ?&pad - } POP - #00 - &fill - ANDk #202a ROT ?{ SWP } POP #18 DEO - #2018 DEO - INC ADDk STHkr LTH ?&fill - POP2 - #0a18 DEO - #01 SUB DUP #ff NEQ ?&ver - POP POPr - +@sierpinski ( -> ) + ( mask ) [ LIT2r 0a18 ] [ LIT2r 2018 ] + ( size ) [ LIT2 &size 1001 ] SUB + &>ver ( -- ) + DUP INCk + &>pad ( length -- ) + DEOkr + #01 SUB DUP ?&>pad + &>fill ( length i -- ) + ANDk DUP2r ?{ POP2r ORA2kr } DEOr DEOkr + INC ADDk ,&size LDR LTH ?&>fill + POP2 OVR2r DEOr + #01 SUB INCk ?&>ver + POP POP2r POP2r BRK BRK diff --git a/Task/Sieve-of-Eratosthenes/PascalABC.NET/sieve-of-eratosthenes.pas b/Task/Sieve-of-Eratosthenes/PascalABC.NET/sieve-of-eratosthenes.pas index 07aafc9fdb..e8ed58c4e3 100644 --- a/Task/Sieve-of-Eratosthenes/PascalABC.NET/sieve-of-eratosthenes.pas +++ b/Task/Sieve-of-Eratosthenes/PascalABC.NET/sieve-of-eratosthenes.pas @@ -2,7 +2,7 @@ function Eratosthenes(N: integer): List; type primetype = (nonprime,prime); begin var sieve := |nonprime|*2 + |prime|*(N-1); - for var i:=2 to N.Sqrt.Round do + for var i:=2 to N.Sqrt.Trunc do if sieve[i] = prime then for var j := i*i to N step i do sieve[j] := nonprime; diff --git a/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-1.rexx b/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-1.rexx index 1a8497693c..a232b3bdbf 100644 --- a/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-1.rexx +++ b/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-1.rexx @@ -1,12 +1,29 @@ -/*REXX program generates and displays primes via the sieve of Eratosthenes algorithm.*/ -parse arg H .; if H=='' | H=="," then H= 200 /*optain optional argument from the CL.*/ -w= length(H); @prime= right('prime', 20) /*W: is used for aligning the output.*/ -@.=. /*assume all the numbers are prime. */ -#= 0 /*number of primes found (so far). */ - do j=2 for H-1; if @.j=='' then iterate /*all prime integers up to H inclusive.*/ - #= # + 1 /*bump the prime number counter. */ - say @prime right(#,w) " ───► " right(j,w) /*display the prime to the terminal. */ - do m=j*j to H by j; @.m=; end /*strike all multiples as being ¬ prime*/ - end /*j*/ /* ─── */ -say /*stick a fork in it, we're all done. */ -say right(#, 1+w+length(@prime) ) 'primes found up to and including ' H +/*REXX program generates primes via sieve of Eratosthenes algorithm. +* 21.07.2012 Walter Pachl derived from above Rexx version +* avoid symbols @ and # (not supported by ooRexx) +* avoid negations (think positive) +**********************************************************************/ + highest=200 /*define highest number to use. */ + is_prime.=1 /*assume all numbers are prime. */ + w=length(highest) /*width of the biggest number, */ + /* it's used for aligned output.*/ + Do j=3 To highest By 2, /*strike multiples of odd ints. */ + While j*j<=highest /* up to sqrt(highest) */ + If is_prime.j Then Do + Do jm=j*3 To highest By j+j /*start with next odd mult. of J */ + is_prime.jm=0 /*mark odd mult. of J not prime. */ + End + End + End + np=0 /*number of primes shown */ + Call tell 2 + Do n=3 To highest By 2 /*list all the primes found. */ + If is_prime.n Then Do + Call tell n + End + End + Exit +tell: Parse Arg prime + np=np+1 + Say ' prime number' right(np,w) " --> " right(prime,w) + Return diff --git a/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-2.rexx b/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-2.rexx index 77294f8bc1..7ed21e1fa3 100644 --- a/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-2.rexx +++ b/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-2.rexx @@ -1,24 +1,68 @@ -/*REXX program generates primes via a wheeled sieve of Eratosthenes algorithm. */ -parse arg H .; if H=='' then H=200 /*let the highest number be specified. */ -tell=h>0; H=abs(H); w=length(H) /*a negative H suppresses prime listing*/ -if 2<=H & tell then say right(1, w+20)'st prime ───► ' right(2, w) -@.= '0'x /*assume that all numbers are prime. */ -cw= length(@.) /*the cell width that holds numbers. */ -#= w<=H /*the number of primes found (so far).*/ -!=0 /*skips the top part of sieve marking. */ - do j=3 by 2 for (H-2)%2; b= j%cw /*odd integers up to H inclusive. */ - if substr(x2b(c2x(@.b)),j//cw+1,1) then iterate /*is J composite ? */ - #= # + 1 /*bump the prime number counter. */ - if tell then say right(#, w+20)th(#) 'prime ───► ' right(j, w) - if ! then iterate /*should the top part be skipped ? */ - jj=j * j /*compute the square of J. ___*/ - if jj>H then !=1 /*indicates skip top part if j > √ H */ - do m=jj to H by j+j; call . m; end /* [↑] strike odd multiples ¬ prime */ - end /*j*/ /* ─── */ +-- 12 Apr 2025 +include Settings -say; say right(#, w+20) 'prime's(#) "found up to and including " H -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────────────*/ -.: parse arg n; b=n%cw; r=n//cw+1;_=x2b(c2x(@.b));@.b=x2c(b2x(left(_,r-1)'1'substr(_,r+1)));return -s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*pluralizer.*/ -th: procedure; parse arg x; x=abs(x); return word('th st nd rd',1+x//10*(x//100%10\==1)*(x//10<4)) +call Time('r') +say 'SIEVE OF ERATOSTHENES' +say version +say +call GetBasic 200 +call ShowPrimes 200 +call GetPrimes 200 +call ShowPrimes 200 +say Format(Time('e'),,3) 'seconds'; say +exit + +GetBasic: +procedure expose prim. +arg xx +say 'Basic sieve up to' xx'...' +call Basic xx +say prim.0 'found' +say +return + +Basic: +procedure expose prim. work. +arg xx +work. = 1 +do i = 2 while i*i <= xx + if work.i then do + do j = i*i by i to xx + work.j = 0 + end + end +end +zz = 0 +do i = 2 to xx + if work.i then do + zz = zz+1; prim.zz = i + end +end +prim.0 = zz +return zz + +GetPrimes: +procedure expose prim. flag. +arg xx +say 'Wheeled sieve up to' xx'...' +call Primes xx +say prim.0 'found' +say +return + +ShowPrimes: +procedure expose prim. +arg xx +say 'Primes up to' xx +do i = 1 to prim.0 + call Charout ,right(prim.i,4) + if i//10 = 0 then + say +end +say +say +return + +include Sequences +include Functions +include Abend diff --git a/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-3.rexx b/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-3.rexx deleted file mode 100644 index 4e18e68268..0000000000 --- a/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-3.rexx +++ /dev/null @@ -1,16 +0,0 @@ -/*REXX pgm generates and displays primes via a wheeled sieve of Eratosthenes algorithm. */ -parse arg H .; if H=='' | H=="," then H= 200 /*obtain the optional argument from CL.*/ -w= length(H); @prime= right('prime', 20) /*w: is used for aligning the output. */ -if 2<=H then say @prime right(1, w) " ───► " right(2, w) -#= 2<=H /*the number of primes found (so far).*/ -@.=. /*assume all the numbers are prime. */ -!=0; do j=3 by 2 for (H-2)%2 /*the odd integers up to H inclusive.*/ - if @.j=='' then iterate /*Is composite? Then skip this number.*/ - #= # + 1 /*bump the prime number counter. */ - say @prime right(#,w) " ───► " right(j,w) /*display the prime to the terminal. */ - if ! then iterate /*skip the top part of loop? ___ */ - if j*j>H then !=1 /*indicate skip top part if J > √ H */ - do m=j*j to H by j+j; @.m=; end /*strike odd multiples as not prime. */ - end /*j*/ /* ─── */ -say /*stick a fork in it, we're all done. */ -say right(#, 1 + w + length(@prime) ) 'primes found up to and including ' H diff --git a/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-4.rexx b/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-4.rexx deleted file mode 100644 index a232b3bdbf..0000000000 --- a/Task/Sieve-of-Eratosthenes/REXX/sieve-of-eratosthenes-4.rexx +++ /dev/null @@ -1,29 +0,0 @@ -/*REXX program generates primes via sieve of Eratosthenes algorithm. -* 21.07.2012 Walter Pachl derived from above Rexx version -* avoid symbols @ and # (not supported by ooRexx) -* avoid negations (think positive) -**********************************************************************/ - highest=200 /*define highest number to use. */ - is_prime.=1 /*assume all numbers are prime. */ - w=length(highest) /*width of the biggest number, */ - /* it's used for aligned output.*/ - Do j=3 To highest By 2, /*strike multiples of odd ints. */ - While j*j<=highest /* up to sqrt(highest) */ - If is_prime.j Then Do - Do jm=j*3 To highest By j+j /*start with next odd mult. of J */ - is_prime.jm=0 /*mark odd mult. of J not prime. */ - End - End - End - np=0 /*number of primes shown */ - Call tell 2 - Do n=3 To highest By 2 /*list all the primes found. */ - If is_prime.n Then Do - Call tell n - End - End - Exit -tell: Parse Arg prime - np=np+1 - Say ' prime number' right(np,w) " --> " right(prime,w) - Return diff --git a/Task/Sieve-of-Pritchard/EasyLang/sieve-of-pritchard.easy b/Task/Sieve-of-Pritchard/EasyLang/sieve-of-pritchard.easy index fb9fb5a77d..2d9c1c665e 100644 --- a/Task/Sieve-of-Pritchard/EasyLang/sieve-of-pritchard.easy +++ b/Task/Sieve-of-Pritchard/EasyLang/sieve-of-pritchard.easy @@ -1,4 +1,4 @@ -proc pritchard limit . primes[] . +proc pritchard limit &primes[] . len members[] limit members[1] = 1 steplength = 1 @@ -23,19 +23,13 @@ proc pritchard limit . primes[] . mcpy[] = members[] for w to nlimit if mcpy[w] = 1 - if np = 5 and w > prime - np = w - . + if np = 5 and w > prime : np = w n = prime * w - if n > nlimit - break 1 - . + if n > nlimit : break 1 members[n] = 0 . . - if np < prime - break 1 - . + if np < prime : break 1 primes[] &= prime if prime = 2 prime = 3 @@ -45,9 +39,7 @@ proc pritchard limit . primes[] . nlimit = lower (steplength * prime) limit . for i = 2 to len members[] - if members[i] = 1 - primes[] &= i - . + if members[i] = 1 : primes[] &= i . . pritchard 150 p[] diff --git a/Task/Sieve-of-Pritchard/REXX/sieve-of-pritchard.rexx b/Task/Sieve-of-Pritchard/REXX/sieve-of-pritchard.rexx new file mode 100644 index 0000000000..7c5434290f --- /dev/null +++ b/Task/Sieve-of-Pritchard/REXX/sieve-of-pritchard.rexx @@ -0,0 +1,95 @@ +-- 12 Apr 2025 +include Settings + +call Time('r') +say 'SIEVE OF PRITCHARD' +say version +say +call Pritchard 150,1 +call Pritchard 1e6,0 +call Eratosthenes 1e6 +exit + +Pritchard: +procedure +call Time('r') +arg xx,yy +say 'Primes up to' xx 'by Pritchard...' +memb. = 0; memb.1 = 1; mcpy. = 0; prim. = 0; nwpr. = 0 +nl = 2; nn = 0; pr = 2; rl = Sqrt(xx); sl = 1; ub = xx+1 +do while pr <= rl + if sl < xx then do + do w = 1 to ub + if memb.w then do + n = w+sl + do while n <= nl + memb.n = 1; n = n+sl + end + end + end + sl = nl + end + do i = 1 to ub + mcpy.i = memb.i + end + np = 5 + do i = 1 to ub + if mcpy.i then do + if np = 5 then + if i > pr then + np = i + n = pr*i + if n > xx then + leave i + memb.n = 0 + end + end + if np < pr then + leave + nn = nn+1 + prim.nn = pr + if pr = 2 then + pr = 3 + else + pr = np + nl = Min(sl*pr,xx) +end +nwpr. = 0 +do i = 2 to ub + if memb.i then + nwpr.i = i +end +nn = 0 +do i = 1 to 1000 + if prim.i > 0 then do + if yy then + call Charout ,prim.i' ' + nn = nn+1 + end +end +do i = 1 to ub + if nwpr.i > 0 then do + if yy then + call Charout ,i' ' + nn = nn+1 + end +end +if yy then + say +say nn 'found' +say Format(Time('e'),,3) 'seconds' +say +return nn + +Eratosthenes: +procedure +call Time('r') +arg xx +say 'Primes up to' xx 'by Eratosthenes...' +say Primes(xx) 'found' +say Format(Time('e'),,3) 'seconds' +return + +include Sequences +include Functions +include Abend diff --git a/Task/Simple-database/M2000-Interpreter/simple-database.m2000 b/Task/Simple-database/M2000-Interpreter/simple-database.m2000 index 83545002c0..e15cd7a54e 100644 --- a/Task/Simple-database/M2000-Interpreter/simple-database.m2000 +++ b/Task/Simple-database/M2000-Interpreter/simple-database.m2000 @@ -124,7 +124,7 @@ if ret=0 then beep: exit if not islet then try { open "tool.bat" for output as #f - print #f, {@}+appdir$+{m2000.exe data {%*}: dir %cd%:load tool + print #f, {@}+shortdir$(appdir$)+{m2000.exe data {%*}: dir %cd%:load tool } close #f } diff --git a/Task/Simple-turtle-graphics/EasyLang/simple-turtle-graphics.easy b/Task/Simple-turtle-graphics/EasyLang/simple-turtle-graphics.easy index ad6606a423..6be5d8dc64 100644 --- a/Task/Simple-turtle-graphics/EasyLang/simple-turtle-graphics.easy +++ b/Task/Simple-turtle-graphics/EasyLang/simple-turtle-graphics.easy @@ -3,25 +3,24 @@ subr home x = 50 y = 50 down = 0 - move x y . home # -proc forward n . . +proc forward n . + px = x + py = y x += cos deg * n y += sin deg * n if down = 1 - line x y - else - move x y + gline px py x y . - sleep 0.1 + sleep 0.05 . -proc turn a . . +proc turn a . deg -= a . # -proc house . . +proc house . turn 180 forward 45 turn 180 @@ -43,7 +42,7 @@ proc house . . . house # -proc bar a[] . . +proc bar a[] . turn 90 forward 30 turn -90 diff --git a/Task/Simple-turtle-graphics/M2000-Interpreter/simple-turtle-graphics.m2000 b/Task/Simple-turtle-graphics/M2000-Interpreter/simple-turtle-graphics.m2000 new file mode 100644 index 0000000000..54894fe000 --- /dev/null +++ b/Task/Simple-turtle-graphics/M2000-Interpreter/simple-turtle-graphics.m2000 @@ -0,0 +1,69 @@ +Module TurtleGraphics { + cls 15,0 + pen 0 + single penangle=pi + boolean pendraw=true + hlen=min.data(scale.x, scale.y)/4 + move scale.x/4, scale.y/2 + house(hlen) + penup() + forward(hlen) + pendown() + d=(50, 33, 200, 130, 50) + items=len(d) + dspan=d#max() + ratio=scale.y/4/dspan + ditem=each(d) + while ditem + barvalue(scale.x/4, scale.y/3 ,items, ditem^, array(ditem)/dspan) + end while + + sub house(n) + for i=1 to 3 + right(120) + forward(n) + next + right(90) + bar(n, n) + right(90) + end sub + sub bar(w, h) + local i + for i=1 to 2 + right(90) + forward(h) + right(90) + forward(w) + next + end sub + sub barvalue(maxW, maxH, bars, barno, valratio) + local bW=maxW/bars + forward(bw) + bar(bw, -maxH*valratio) + end sub + // Turtle Minimum Pack + // need: + // single penangle=pi + // boolean pendraw=true + // + sub penup() + pendraw=false + end sub + sub pendown() + pendraw=true + end sub + sub forward(distance) + if pendraw then + draw angle penangle, distance + else + step angle penangle, distance + end if + end sub + sub backward(distance) + forward(-distance) + end sub + sub right(angle) + penangle-=angle/180*pi + end sub +} +TurtleGraphics diff --git a/Task/Simple-turtle-graphics/Raku/simple-turtle-graphics.raku b/Task/Simple-turtle-graphics/Raku/simple-turtle-graphics.raku new file mode 100644 index 0000000000..ad265e38df --- /dev/null +++ b/Task/Simple-turtle-graphics/Raku/simple-turtle-graphics.raku @@ -0,0 +1,54 @@ +# 20250303 Raku programming solution + +use Cairo; + +sub house(Cairo::Context $cr, $x, $y, $size) { + $cr.save; + $cr.rgb(1.0, 1.0, 1.0); + + $cr.rectangle($x, $y, $size, $size); + $cr.stroke; + + $cr.move_to($x + $size / 2, $y - $size / 2); + $cr.line_to($x, $y); + $cr.line_to($x + $size, $y); + $cr.close_path; + $cr.stroke; + + $cr.restore; +} + +sub barchart(Cairo::Context $cr, @data, $x is copy, $y, $size) { + $cr.save; + $cr.rgb(1.0, 1.0, 1.0); + + my $maxdata = @data.max || 1; + my $bar-width = $size / (@data.elems || 1); + my $bar-spacing = $bar-width * 0.1; + + for @data -> $n { + my $bar-height = ($n / $maxdata) * $size; + $cr.rectangle($x, $y - $bar-height, $bar-width - $bar-spacing, $bar-height); + $cr.stroke; + $x += $bar-width; + } + + $cr.restore; +} + +sub testturtle($width = 400, $height = 600) { + my $image = Cairo::Image.create(Cairo::FORMAT_ARGB32, $width, $height); + my $cr = Cairo::Context.new($image); + + $cr.rgb(0.0, 0.0, 0.0); + $cr.paint; + + $cr.line_width = 2.0; + + barchart($cr, [15, 10, 50, 35, 20], $width * 0.6, $height, $width / 3); + house($cr, $width / 4, $height / 3, $width / 3); + + $image.write_png('turtle-raku.png'); +} + +testturtle(); diff --git a/Task/Simulate-input-Keyboard/FreeBASIC/simulate-input-keyboard.basic b/Task/Simulate-input-Keyboard/FreeBASIC/simulate-input-keyboard.basic new file mode 100644 index 0000000000..1ffc77abd0 --- /dev/null +++ b/Task/Simulate-input-Keyboard/FreeBASIC/simulate-input-keyboard.basic @@ -0,0 +1,40 @@ +#include once "windows.bi" + +Dim ki(0 To 7) As INPUT_ + +' A +ki(0).type = INPUT_KEYBOARD +ki(0).ki.wVk = Asc("A") +ki(0).ki.dwFlags = 0 +ki(1).type = INPUT_KEYBOARD +ki(1).ki.wVk = Asc("A") +ki(1).ki.dwFlags = KEYEVENTF_KEYUP + +' B +ki(2).type = INPUT_KEYBOARD +ki(2).ki.wVk = Asc("B") +ki(2).ki.dwFlags = 0 +ki(3).type = INPUT_KEYBOARD +ki(3).ki.wVk = Asc("B") +ki(3).ki.dwFlags = KEYEVENTF_KEYUP + +' C +ki(4).type = INPUT_KEYBOARD +ki(4).ki.wVk = Asc("C") +ki(4).ki.dwFlags = 0 +ki(5).type = INPUT_KEYBOARD +ki(5).ki.wVk = Asc("C") +ki(5).ki.dwFlags = KEYEVENTF_KEYUP + +' ENTER (VK_RETURN = &HD) +ki(6).type = INPUT_KEYBOARD +ki(6).ki.wVk = VK_RETURN +ki(6).ki.dwFlags = 0 +ki(7).type = INPUT_KEYBOARD +ki(7).ki.wVk = VK_RETURN +ki(7).ki.dwFlags = KEYEVENTF_KEYUP + +Print "Make the target window active. Sending keys in 3 seconds..." +Sleep 3000 + +SendInput(Ubound(ki), @ki(0), Len(INPUT_)) diff --git a/Task/Sisyphus-sequence/ALGOL-68/sisyphus-sequence.alg b/Task/Sisyphus-sequence/ALGOL-68/sisyphus-sequence.alg index aba0b1030b..3c6aff36d7 100644 --- a/Task/Sisyphus-sequence/ALGOL-68/sisyphus-sequence.alg +++ b/Task/Sisyphus-sequence/ALGOL-68/sisyphus-sequence.alg @@ -1,17 +1,9 @@ BEGIN # generate elements of the Sysiphus Sequence: see OEIS A350877 # - # returns the largest element in a # - OP MAX = ( []INT a )INT: - IF LWB a >UPB a THEN 0 - ELSE - INT result := a[ LWB a ]; - FOR i FROM LWB a + 1 TO UPB a DO - IF result < a[ i ] THEN result := a[ i ] FI - OD; - result - FI # MAX # ; + PR read "rows.incl.a68" PR # include row (array) utilities # + # sieve the primes # - INT sieve max = 1 000 000 000; ### CHANGE TO E.G.: 100 000 000 FOR ALGOL 68G ### + INT sieve max = 100 000 000; ### 10 000 000 for ALGOL 68 Genie version 3 # BOOL is odd := TRUE; [ sieve max ]BOOL sieve; FOR i TO UPB sieve DO sieve[ i ] := is odd; is odd := NOT is odd OD; sieve[ 1 ] := FALSE; diff --git a/Task/Sisyphus-sequence/EasyLang/sisyphus-sequence.easy b/Task/Sisyphus-sequence/EasyLang/sisyphus-sequence.easy index 27988008d1..befbb870ce 100644 --- a/Task/Sisyphus-sequence/EasyLang/sisyphus-sequence.easy +++ b/Task/Sisyphus-sequence/EasyLang/sisyphus-sequence.easy @@ -1,24 +1,20 @@ func isprim num . - if num mod 2 = 0 and num > 2 - return 0 - . + if num mod 2 = 0 and num > 2 : return 0 i = 3 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 . return 1 . prim = 1 -proc nextprim . . +proc nextprim . repeat prim += 1 until isprim prim = 1 . . -numfmt 0 4 +numfmt 4 0 n = 1 write n for i = 2 to 100 @@ -29,7 +25,5 @@ for i = 2 to 100 n /= 2 . write n - if i mod 10 = 0 - print "" - . + if i mod 10 = 0 : print "" . diff --git a/Task/Sisyphus-sequence/Mathematica/sisyphus-sequence.math b/Task/Sisyphus-sequence/Mathematica/sisyphus-sequence.math new file mode 100644 index 0000000000..a56731f395 --- /dev/null +++ b/Task/Sisyphus-sequence/Mathematica/sisyphus-sequence.math @@ -0,0 +1,33 @@ +num = 1; +primepi = 1; +res = Table[ + If[EvenQ[num], + num /= 2; + , + num += Prime[primepi]; + primepi++; + ]; + num + , + {99} + ]; +PrependTo[res, 1]; +Partition[res, 10] // Grid + +Table[ + num = 1; + primepi = 1; + Do[ + If[EvenQ[num], + num /= 2; + , + num += Prime[primepi]; + primepi++; + ]; + , + {j} + ]; + {num, Prime[primepi - 1]} + , + {j, {999, 9999, 99999, 999999, 9999999, 99999999}} +] diff --git a/Task/Sleep/JavaScript/sleep-1.js b/Task/Sleep/JavaScript/sleep-1.js new file mode 100644 index 0000000000..87504243c2 --- /dev/null +++ b/Task/Sleep/JavaScript/sleep-1.js @@ -0,0 +1,11 @@ +function delay (ms) { + return new Promise((res) => setTimeout(res, ms)) +} + +void (async () => { + for (let i = 10; i > 0; --i) { + console.log(i) + await delay(1000) + } + console.log('Blast off!') +})() diff --git a/Task/Sleep/JavaScript/sleep-2.js b/Task/Sleep/JavaScript/sleep-2.js new file mode 100644 index 0000000000..50bf051403 --- /dev/null +++ b/Task/Sleep/JavaScript/sleep-2.js @@ -0,0 +1,14 @@ +function worker() { + const buf = new Int32Array(new WebAssembly.Memory({ initial: 1, maximum: 1, shared: true }).buffer) + function sleep(ms) { + Atomics.wait(buf, 0, 0, ms) + } + + for (let i = 10; i > 0; --i) { + console.log(i) + sleep(1000) + } + console.log('Blast off!') +} + +new Worker(URL.createObjectURL(new Blob([`(${worker})()`]))) diff --git a/Task/Sleep/JavaScript/sleep-3.js b/Task/Sleep/JavaScript/sleep-3.js new file mode 100644 index 0000000000..405372a9b1 --- /dev/null +++ b/Task/Sleep/JavaScript/sleep-3.js @@ -0,0 +1,8 @@ +function sleepFuriously(ms) { + const start = Date.now() + while (Date.now() - start < ms); +} + +console.log('sleeping...') +sleepFuriously(1000) +console.log('wow, that was exhausting!') diff --git a/Task/Sleep/JavaScript/sleep.js b/Task/Sleep/JavaScript/sleep.js deleted file mode 100644 index 067888bdcb..0000000000 --- a/Task/Sleep/JavaScript/sleep.js +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/Task/Sleep/REXX/sleep-3.rexx b/Task/Sleep/REXX/sleep-3.rexx index 628dc3f7c8..7e4b63a3b0 100644 --- a/Task/Sleep/REXX/sleep-3.rexx +++ b/Task/Sleep/REXX/sleep-3.rexx @@ -1,4 +1,8 @@ -Main: +include Settings + +say 'SLEEP - 2 Mar 2025' +say version +say call Sleep 1 call Sleep 2 call Sleep 3 @@ -11,3 +15,5 @@ say time('l') 'Waiting for' s 'seconds...' 'timeout /t' s '/nobreak > nul' say time('l') 'Done!' return + +include Abend diff --git a/Task/Smarandache-prime-digital-sequence/REXX/smarandache-prime-digital-sequence.rexx b/Task/Smarandache-prime-digital-sequence/REXX/smarandache-prime-digital-sequence.rexx index 71aa99ccc1..9f7d6e9c4e 100644 --- a/Task/Smarandache-prime-digital-sequence/REXX/smarandache-prime-digital-sequence.rexx +++ b/Task/Smarandache-prime-digital-sequence/REXX/smarandache-prime-digital-sequence.rexx @@ -1,30 +1,65 @@ -/*REXX program lists a sequence of SPDS (Smarandache prime-digital sequence) primes.*/ -parse arg n q /*get optional number of primes to find*/ -if n=='' | n=="," then n= 25 /*Not specified? Then use the default.*/ -if q='' then q= 100 1000 /* " " " " " " */ -say '═══listing the first' n "SPDS primes═══" -call spds n - do i=1 for words(q)+1; y=word(q, i); if y=='' | y=="," then iterate - say - say '═══listing the last of ' y "SPDS primes═══" - call spds -y - end /*i*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -spds: parse arg x 1 ox; x= abs(x) /*obtain the limit to be used for list.*/ - c= 0 /*C number of SPDS primes found so far*/ - #= 0 /*# number of primes found so far*/ - do j=1 by 2 while c0 then iterate j /*Digits ¬prime? Then skip this prime.*/ - c= c + 1 /*bump the number of SPDS primes found.*/ - if ox<0 then iterate /*don't display it, display the last #.*/ - say right(z, 21) /*maybe display this prime ──► terminal*/ - end /*j*/ /* [↑] only display N number of primes*/ - if ox<0 then say right(z, 21) /*display one (the last) SPDS prime. */ - return +-- 12 Apr 2025 +include Settings +numeric digits 12 + +call Time('r') +say 'SMARANDACHE PRIME-DIGITAL SEQUENCE' +say version +say +call Task1 +call Task2 +say Format(Time('e'),,3) 'seconds' +exit + +Task1: +procedure expose prim. +say 'First 25 SPDS primes...' +n = 0 +do i = 1 until n = 25 + if PrimeDigits(i) then do + if Prime(i) then do + n = n+1 + call Charout ,Right(i,9) + if n //10 = 0 then + say + end + end +end +say +say +return + +Task2: +procedure expose prim. +say 'Higher in the sequence...' +n = 4; t = 0 +do i = 23 by 2 until n = 23e3 + if Pos(Right(i,1),37) > 0 then do + if PrimeDigits(i) then do + t = t+1 + if Prime(i) then do + n = n+1 + if n//1000 = 0 then do + say n'th is' i + end + end + end + end +end +say t 'prime tests performed' +say +return + +PrimeDigits: +procedure +arg xx +a = Verify(xx,2357) +if a > 0 then + return 0 +else + return 1 + +include Numbers +include Sequences +include Functions +include Abend diff --git a/Task/Snake/EasyLang/snake.easy b/Task/Snake/EasyLang/snake.easy index 159718d50e..79fe0072b8 100644 --- a/Task/Snake/EasyLang/snake.easy +++ b/Task/Snake/EasyLang/snake.easy @@ -10,18 +10,15 @@ subr start dir = random 4 timer 0 . -background 242 -move 30 70 -clear -color 997 -text "SNAKE" -textsize 5 -move 6 40 -text "Keys or mouse for controlling" -move 6 30 -text "Space or click to to start" +gbackground 242 +gclear +gcolor 997 +gtext 30 70 "SNAKE" +gtextsize 5 +gtext 6 40 "Keys or mouse for controlling" +gtext 6 30 "Space or click to start" # -on key +on key_down if game = 0 and keybkey = " " start return @@ -59,16 +56,19 @@ on mouse_down . . . +proc over . + gcolor 997 + gtext 10 10 "Space or click for new game" + game = 2 + timer 1 +. on timer - clear - color 997 - move 2 95 - text "Score: " & 10 * len sx[] - 50 - color 966 - move rx ry - circle 1.5 - # - sx = sx[1] ; sy = sy[1] + if game = 2 + game = 0 + return + . + sx = sx[1] + sy = sy[1] if dir = 1 sy += 5 elif dir = 2 @@ -79,45 +79,44 @@ on timer sx -= 5 . if sx < 0 or sx > 100 or sy < 0 or sy > 100 - game = 0 + over + return . - color 494 for i = len sx[] downto 2 if sx = sx[i] and sy = sy[i] - game = 0 + over + return . + . + gclear + gcolor 997 + gtext 2 95 "Score: " & 10 * len sx[] - 50 + gcolor 966 + gcircle rx ry 1.5 + # + gcolor 494 + for i = len sx[] downto 2 sx[i] = sx[i - 1] sy[i] = sy[i - 1] if sx[i] > 0 - move sx[i] sy[i] - circle 2.5 + gcircle sx[i] sy[i] 2.5 . . - move sx sy - circle 2.5 - color 000 + gcircle sx sy 2.5 + gcolor 000 if dir = 2 or dir = 4 - move sx sy + 1 - circle 0.5 - move sx sy - 1 - circle 0.5 + gcircle sx sy + 1 0.5 + gcircle sx sy - 1 0.5 else - move sx + 1 sy - circle 0.5 - move sx - 1 sy - circle 0.5 + gcircle sx + 1 sy 0.5 + gcircle sx - 1 sy 0.5 . if sx = rx and sy = ry len sx[] len sx[] + 3 len sy[] len sy[] + 3 fruit . - sx[1] = sx ; sy[1] = sy - if game = 1 - timer 0.15 - else - color 997 - move 10 10 - text "Space or click new game" - . + sx[1] = sx + sy[1] = sy + timer 0.15 . diff --git a/Task/Solve-a-Hidato-puzzle/EasyLang/solve-a-hidato-puzzle.easy b/Task/Solve-a-Hidato-puzzle/EasyLang/solve-a-hidato-puzzle.easy index faab3d3d1e..af920153fe 100644 --- a/Task/Solve-a-Hidato-puzzle/EasyLang/solve-a-hidato-puzzle.easy +++ b/Task/Solve-a-Hidato-puzzle/EasyLang/solve-a-hidato-puzzle.easy @@ -1,28 +1,20 @@ moves[][] = [ [ -1 -1 ] [ -1 0 ] [ -1 1 ] [ 0 -1 ] [ 0 1 ] [ 1 -1 ] [ 1 0 ] [ 1 1 ] ] global brd[][] maxr maxc maxcnt ancor . func solve r c cnt . - if cnt - ancor > 13 - return 0 - . - if cnt > maxcnt - return 1 - . + if cnt - ancor > 13 : return 0 + if cnt > maxcnt : return 1 for m = 1 to len moves[][] rn = r + moves[m][1] cn = c + moves[m][2] if rn >= 1 and rn <= maxr and cn >= 1 and cn <= maxc if brd[rn][cn] = 0 brd[rn][cn] = cnt - if solve rn cn (cnt + 1) = 1 - return 1 - . + if solve rn cn (cnt + 1) = 1 : return 1 brd[rn][cn] = 0 elif brd[rn][cn] = cnt oldanc = ancor ancor = cnt - if solve rn cn (cnt + 1) = 1 - return 1 - . + if solve rn cn (cnt + 1) = 1 : return 1 ancor = oldanc . . @@ -39,7 +31,7 @@ brd$ = " . . . . __ 7 __ __ . . . . . . 5 __ " -proc prepare . r0 c0 . +proc prepare &r0 &c0 . brd$[] = strsplit brd$ "\n" maxc = len brd$[2] / 3 maxr = len brd$[] - 2 @@ -64,8 +56,8 @@ proc prepare . r0 c0 . . ancor = 1 . -proc printbrd . . - numfmt 0 3 +proc printbrd . + numfmt 3 0 for r to maxr for c to maxc if brd[r][c] = -1 diff --git a/Task/Solve-a-Hidato-puzzle/JavaScript/solve-a-hidato-puzzle.js b/Task/Solve-a-Hidato-puzzle/JavaScript/solve-a-hidato-puzzle.js new file mode 100644 index 0000000000..afcb0dc362 --- /dev/null +++ b/Task/Solve-a-Hidato-puzzle/JavaScript/solve-a-hidato-puzzle.js @@ -0,0 +1,113 @@ +let board = []; +let start = []; +let given = []; + +function setup(input) { + /* This task is not about input validation, so + we're going to trust the input to be valid */ + const puzzle = input.map(line => line.split(/\s+/)); + const nCols = puzzle[0].length; + const nRows = puzzle.length; + let list = new Array(nRows * nCols); + + board = Array(nRows + 2).fill().map(() => + Array(nCols + 2).fill(-1) + ); + + for (let r = 0; r < nRows; r++) { + const row = puzzle[r]; + for (let c = 0; c < nCols; c++) { + const cell = row[c]; + switch (cell) { + case "_": + board[r + 1][c + 1] = 0; + break; + case ".": + break; + default: + const val = parseInt(cell, 10); + board[r + 1][c + 1] = val; + list.push(val); + if (val === 1) { + start = [r + 1, c + 1]; + } + break; + } + } + } + + list.sort((a, b) => a - b); + given = [...list]; +} + +function solve(r, c, n, next) { + if (n > given[given.length - 1]) { + return true; + } + + const back = board[r][c]; + if (back !== 0 && back !== n) { + return false; + } + + if (back === 0 && given[next] === n) { + return false; + } + + if (back === n) { + next++; + } + + board[r][c] = n; + for (let i = -1; i < 2; i++) { + for (let j = -1; j < 2; j++) { + if (solve(r + i, c + j, n + 1, next)) { + return true; + } + } + } + + board[r][c] = back; + return false; +} + +function printBoard() { + for (const row of board) { + let rowStr = ''; + for (const c of row) { + switch (true) { + case c === -1: + rowStr += ' . '; + break; + case c > 0: + rowStr += c.toString().padStart(2) + ' '; + break; + default: + rowStr += '__ '; + break; + } + } + console.log(rowStr); + } +} + +function main() { + const input = [ + "_ 33 35 _ _ . . .", + "_ _ 24 22 _ . . .", + "_ _ _ 21 _ _ . .", + "_ 26 _ 13 40 11 . .", + "27 _ _ _ 9 _ 1 .", + ". . _ _ 18 _ _ .", + ". . . . _ 7 _ _", + ". . . . . . 5 _" + ]; + + setup(input); + printBoard(); + console.log("\nFound:"); + solve(start[0], start[1], 1, 0); + printBoard(); +} + +main(); diff --git a/Task/Solve-a-Holy-Knights-tour/EasyLang/solve-a-holy-knights-tour.easy b/Task/Solve-a-Holy-Knights-tour/EasyLang/solve-a-holy-knights-tour.easy index 9c7df10abd..268a1b3472 100644 --- a/Task/Solve-a-Holy-Knights-tour/EasyLang/solve-a-holy-knights-tour.easy +++ b/Task/Solve-a-Holy-Knights-tour/EasyLang/solve-a-holy-knights-tour.easy @@ -11,23 +11,19 @@ brd$ = " moves[][] = [ [ -2 -1 ] [ -2 1 ] [ -1 -2 ] [ -1 2 ] [ 1 -2 ] [ 1 2 ] [ 2 -1 ] [ 2 1 ] ] global brd[][] maxr maxc maxcnt . func solve r c cnt . - if cnt > maxcnt - return 1 - . + if cnt > maxcnt : return 1 for m = 1 to len moves[][] rn = r + moves[m][1] cn = c + moves[m][2] if rn >= 1 and rn <= maxr and cn >= 1 and cn <= maxc and brd[rn][cn] = 0 brd[rn][cn] = cnt - if solve rn cn (cnt + 1) = 1 - return 1 - . + if solve rn cn (cnt + 1) = 1 : return 1 brd[rn][cn] = 0 . . return 0 . -proc prepare . r0 c0 . +proc prepare &r0 &c0 . brd$[] = strsplit brd$ "\n" maxc = len brd$[2] maxr = len brd$[] - 2 @@ -45,8 +41,8 @@ proc prepare . r0 c0 . . . . -proc printbrd . . - numfmt 0 3 +proc printbrd . + numfmt 3 0 for r to maxr for c to maxc if brd[r][c] = -1 diff --git a/Task/Solve-a-Holy-Knights-tour/Rust/solve-a-holy-knights-tour.rs b/Task/Solve-a-Holy-Knights-tour/Rust/solve-a-holy-knights-tour.rs new file mode 100644 index 0000000000..2533753df8 --- /dev/null +++ b/Task/Solve-a-Holy-Knights-tour/Rust/solve-a-holy-knights-tour.rs @@ -0,0 +1,188 @@ +use std::collections::HashSet; +use std::iter::FromIterator; +use std::str::FromStr; + +#[derive(Clone, Copy)] +struct Node { + val: isize, + neighbors: u8, +} + +struct NSolver { + dx: [isize; 8], + dy: [isize; 8], + wid: usize, + hei: usize, + max: usize, + arr: Vec, +} + +impl NSolver { + fn new() -> Self { + let dx = [-1, -1, 1, 1, -2, -2, 2, 2]; + let dy = [-2, 2, -2, 2, -1, 1, -1, 1]; + + Self { + dx, + dy, + wid: 0, + hei: 0, + max: 0, + arr: vec![], + } + } + + fn solve(&mut self, puzz: &mut Vec, max_wid: usize) { + if puzz.is_empty() { + return; + } + + self.wid = max_wid; + self.hei = puzz.len() / self.wid; + let len = self.wid * self.hei; + self.max = len; + self.arr = vec![Node { val: 0, neighbors: 0 }; len]; + + let mut c = 0; + let mut empty_coords = HashSet::new(); + + for s in puzz.iter() { + if s == "*" { + self.max -= 1; + self.arr[c].val = -1; + c += 1; + continue; + } + + if s == "." { + empty_coords.insert(c); + c += 1; + continue; + } + + if let Ok(val) = isize::from_str(s) { + self.arr[c].val = val; + c += 1; + } + } + + self.solve_it(); + + c = 0; + for s in puzz.iter_mut() { + if s == "." { + let val = self.arr[c].val; + *s = format!("{:02}", val); + } + c += 1; + } + } + + fn solve_it(&mut self) { + let (x, y, z) = self.find_start(); + if z == 99999 { + println!("Can't find start point!"); + return; + } + + self.search(x, y, z + 1); + } + + fn find_start(&self) -> (usize, usize, isize) { + let mut x = 0; + let mut y = 0; + let mut z = 99999; + + for b in 0..self.hei { + for a in 0..self.wid { + let idx = a + b * self.wid; + if self.arr[idx].val > 0 && self.arr[idx].val < z { + x = a; + y = b; + z = self.arr[idx].val; + } + } + } + + (x, y, z) + } + + fn search(&mut self, x: usize, y: usize, w: isize) -> bool { + if w > self.max as isize { + return true; + } + + let idx = x + y * self.wid; + self.arr[idx].neighbors = self.get_neighbors(x, y); + + for d in 0..8 { + if (self.arr[idx].neighbors & (1 << d)) != 0 { + let a = (x as isize + self.dx[d]) as usize; + let b = (y as isize + self.dy[d]) as usize; + let n_idx = a + b * self.wid; + + if self.arr[n_idx].val == 0 { + self.arr[n_idx].val = w; + if self.search(a, b, w + 1) { + return true; + } + self.arr[n_idx].val = 0; + } + } + } + + false + } + + fn get_neighbors(&self, x: usize, y: usize) -> u8 { + let mut c = 0u8; + + for i in 0..8 { + let a = x as isize + self.dx[i]; + let b = y as isize + self.dy[i]; + + if a >= 0 && b >= 0 { + let a = a as usize; + let b = b as usize; + if a < self.wid && b < self.hei { + if self.arr[a + b * self.wid].val > -1 { + c |= 1 << i; + } + } + } + } + + c + } +} + +fn main() { + // Example input (comment/uncomment for different puzzles) + let p = "* * * * * 1 * . * * * * * * * * * * . * . * * * * * * * * * . . . . . * * * * * * * * * . . . * * * * * * * . * * . * . * * . * * . . . . . * * * . . . . . * * . . * * * * * . . * * . . . . . * * * . . . . . * * . * * . * . * * . * * * * * * * . . . * * * * * * * * * . . . . . * * * * * * * * * . * . * * * * * * * * * * . * . * * * * * "; + let wid = 13; + + let puzz: Vec = p.split_whitespace().map(|s| s.to_string()).collect(); + + let mut puzz_vec = puzz.clone(); + + let mut solver = NSolver::new(); + solver.solve(&mut puzz_vec, wid); + + let mut c = 0; + for item in puzz_vec.iter() { + if item == "*" || item == "." { + print!(" "); + } else { + print!("{:2} ", item); + } + + c += 1; + if c >= wid { + println!(); + c = 0; + } + } + + println!("\nPress any key to exit..."); + let _ = std::io::stdin().read_line(&mut String::new()); +} diff --git a/Task/Solve-a-Holy-Knights-tour/Zig/solve-a-holy-knights-tour.zig b/Task/Solve-a-Holy-Knights-tour/Zig/solve-a-holy-knights-tour.zig new file mode 100644 index 0000000000..cf7ec96c84 --- /dev/null +++ b/Task/Solve-a-Holy-Knights-tour/Zig/solve-a-holy-knights-tour.zig @@ -0,0 +1,208 @@ +const std = @import("std"); + +const Node = struct { + val: isize, + neighbors: u8, +}; + +const NSolver = struct { + dx: [8]isize = .{-1, -1, 1, 1, -2, -2, 2, 2}, + dy: [8]isize = .{-2, 2, -2, 2, -1, 1, -1, 1}, + wid: usize, + hei: usize, + max: usize, + arr: []Node, + allocator: std.mem.Allocator, + + pub fn init(allocator: std.mem.Allocator) NSolver { + return NSolver{ + .wid = 0, + .hei = 0, + .max = 0, + .arr = &[_]Node{}, // will be overwritten in `solve` + .allocator = allocator, + }; + } + + // The key problem was here - tokens was being passed as a pointer to a split iterator + // but the function expected [][]const u8 + pub fn solve(self: *NSolver, puzz: []const u8, max_wid: usize) ![][]const u8 { + // Split the input string into tokens + var tokens = std.ArrayList([]const u8).init(self.allocator); + defer tokens.deinit(); + + var iter = std.mem.splitSequence(u8, puzz, " "); + while (iter.next()) |tok| { + if (tok.len == 0) continue; // Skip empty tokens + try tokens.append(tok); + } + + if (tokens.items.len == 0) return &[_][]const u8{}; + + self.wid = max_wid; + self.hei = tokens.items.len / max_wid; + self.max = tokens.items.len; + const len = self.wid * self.hei; + + // allocate and zero‐initialize the board + self.arr = try self.allocator.alloc(Node, len); + for (self.arr) |*n| { + n.* = Node{ .val = 0, .neighbors = 0 }; + } + + // parse the input tokens into our board + var c: usize = 0; + for (tokens.items) |tok| { + if (std.mem.eql(u8, tok, "*")) { + self.max -= 1; + self.arr[c].val = -1; + } else if (std.mem.eql(u8, tok, ".")) { + // leave . as 0 for "empty" + self.arr[c].val = 0; + } else { + // parse a pre‐filled number + const v = try std.fmt.parseInt(isize, tok, 10); + self.arr[c].val = v; + } + c += 1; + } + + // run the backtracking search + self.solveIt(); + + // Create result array to hold the modified tokens + var result = try self.allocator.alloc([]const u8, tokens.items.len); + + // write back any "." slots with zero‐padded numbers + c = 0; + for (tokens.items, 0..) |tok, i| { + if (std.mem.eql(u8, tok, ".")) { + const v = self.arr[c].val; + // format as two digits, zero-pad + result[i] = try std.fmt.allocPrint(self.allocator, "{d:0>2}", .{v}); + } else { + // For non-modified tokens, just copy the reference + result[i] = tok; + } + c += 1; + } + + return result; + } + + fn solveIt(self: *NSolver) void { + const start = self.findStart(); + if (start.z == @as(isize, @intCast(std.math.maxInt(isize)))) { + std.debug.print("Can't find start point!\n", .{}); + return; + } + _ = self.search(start.x, start.y, start.z + 1); + } + + fn findStart(self: *NSolver) struct { x: usize, y: usize, z: isize } { + var best_x: usize = 0; + var best_y: usize = 0; + var best_z: isize = std.math.maxInt(isize); + + // The original code had a bug here - trying to iterate over the height and width directly + var b: usize = 0; + while (b < self.hei) : (b += 1) { + var a: usize = 0; + while (a < self.wid) : (a += 1) { + const idx = a + b * self.wid; + const v = self.arr[idx].val; + if (v > 0 and v < best_z) { + best_x = a; + best_y = b; + best_z = v; + } + } + } + + return .{ .x = best_x, .y = best_y, .z = best_z }; + } + + fn search(self: *NSolver, x: usize, y: usize, w: isize) bool { + if (w > @as(isize, @intCast(self.max))) return true; + + const idx = x + y * self.wid; + self.arr[idx].neighbors = self.getNeighbors(x, y); + + // The original code had a bug here - trying to iterate over dx directly + for (0..self.dx.len) |d| { + if ((self.arr[idx].neighbors & (@as(u8, 1) << @as(u3, @intCast(d)))) != 0) { + const a_s = @as(isize, @intCast(x)) + self.dx[d]; + const b_s = @as(isize, @intCast(y)) + self.dy[d]; + if (a_s >= 0 and b_s >= 0) { + const a = @as(usize, @intCast(a_s)); + const b = @as(usize, @intCast(b_s)); + if (a < self.wid and b < self.hei) { + const n_idx = a + b * self.wid; + if (self.arr[n_idx].val == 0) { + self.arr[n_idx].val = w; + if (self.search(a, b, w + 1)) return true; + self.arr[n_idx].val = 0; + } + } + } + } + } + return false; + } + + fn getNeighbors(self: *NSolver, x: usize, y: usize) u8 { + var mask: u8 = 0; + for (0..self.dx.len) |i| { + const a_s = @as(isize, @intCast(x)) + self.dx[i]; + const b_s = @as(isize, @intCast(y)) + self.dy[i]; + if (a_s >= 0 and b_s >= 0) { + const a = @as(usize, @intCast(a_s)); + const b = @as(usize, @intCast(b_s)); + if (a < self.wid and b < self.hei) { + if (self.arr[a + b * self.wid].val > -1) { + mask |= ( @as(u8, 1) << @as(u3, @intCast(i))); + } + } + } + } + return mask; + } +}; + +pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + const allocator = std.heap.page_allocator; + + // Example puzzle (same as your Rust example) + const p_str = "* * * * * 1 * . * * * * * * * * * * . * . * * * * * * * * * . . . . . * * * * * * * * * . . . * * * * * * * . * * . * . * * . * * . . . . . * * * . . . . . * * . . * * * * * . . * * . . . . . * * * . . . . . * * . * * . * . * * . * * * * * * * . . . * * * * * * * * * . . . . . * * * * * * * * * . * . * * * * * * * * * * . * . * * * * * "; + const wid: usize = 13; + + // solve + var solver = NSolver.init(allocator); + const result = try solver.solve(p_str, wid); + defer allocator.free(solver.arr); + + // Print the solved board + var count: usize = 0; + for (result) |tok| { + if (std.mem.eql(u8, tok, "*")) { + try stdout.print(" ", .{}); + } else { + try stdout.print("{s} ", .{tok}); + } + count += 1; + if (count == wid) { + try stdout.print("\n", .{}); + count = 0; + } + } + try stdout.print("\n", .{}); + + // Free allocated memory for any new tokens + for (result) |tok| { + if (!std.mem.eql(u8, tok, "*") and !std.mem.eql(u8, tok, ".") and !std.mem.eql(u8, tok, "1")) { + allocator.free(tok); + } + } + allocator.free(result); +} diff --git a/Task/Solve-a-Hopido-puzzle/EasyLang/solve-a-hopido-puzzle.easy b/Task/Solve-a-Hopido-puzzle/EasyLang/solve-a-hopido-puzzle.easy index 692a5c4809..0054bef045 100644 --- a/Task/Solve-a-Hopido-puzzle/EasyLang/solve-a-hopido-puzzle.easy +++ b/Task/Solve-a-Hopido-puzzle/EasyLang/solve-a-hopido-puzzle.easy @@ -9,23 +9,19 @@ brd$ = " moves[][] = [ [ -3 0 ] [ 0 3 ] [ 3 0 ] [ 0 -3 ] [ 2 2 ] [ 2 -2 ] [ -2 2 ] [ -2 -2 ] ] global brd[][] maxr maxc maxcnt . func solve r c cnt . - if cnt > maxcnt - return 1 - . + if cnt > maxcnt : return 1 for m = 1 to len moves[][] rn = r + moves[m][1] cn = c + moves[m][2] if rn >= 1 and rn <= maxr and cn >= 1 and cn <= maxc and brd[rn][cn] = 0 brd[rn][cn] = cnt - if solve rn cn (cnt + 1) = 1 - return 1 - . + if solve rn cn (cnt + 1) = 1 : return 1 brd[rn][cn] = 0 . . return 0 . -proc prepare . r0 c0 . +proc prepare &r0 &c0 . brd$[] = strsplit brd$ "\n" maxc = len brd$[2] maxr = len brd$[] - 2 @@ -42,8 +38,8 @@ proc prepare . r0 c0 . . . . -proc printbrd . . - numfmt 0 3 +proc printbrd . + numfmt 3 0 for r to maxr for c to maxc if brd[r][c] = -1 diff --git a/Task/Solve-a-Hopido-puzzle/Rust/solve-a-hopido-puzzle.rs b/Task/Solve-a-Hopido-puzzle/Rust/solve-a-hopido-puzzle.rs new file mode 100644 index 0000000000..0d2536a530 --- /dev/null +++ b/Task/Solve-a-Hopido-puzzle/Rust/solve-a-hopido-puzzle.rs @@ -0,0 +1,258 @@ +use std::io::{self, Write}; // Import Write trait for flush + +const DX: [i32; 8] = [-2, -2, 2, 2, -3, 3, 0, 0]; +const DY: [i32; 8] = [-2, 2, -2, 2, 0, 0, -3, 3]; + +// Equivalent to C++ 'node' struct +#[derive(Clone, Copy, Debug, Default)] +struct Node { + val: i32, // -1 for obstacle, 0 for empty, >0 for number + neighbors: u8, // Bitmask of valid moves (indices into DX/DY) +} + +// Equivalent to C++ 'nSolver' class +struct NSolver { + wid: usize, + hei: usize, + max_val: i32, // The highest number to place (number of non-obstacle cells) + arr: Vec, +} + +impl NSolver { + // Main function to set up and run the solver + // Modifies the input 'puzz' vector in place + pub fn solve_puzzle(puzz: &mut Vec, max_wid: usize) { + if puzz.is_empty() { + return; + } + + let wid = max_wid; + if wid == 0 { + eprintln!("Error: Width cannot be zero."); + return; + } + let hei = puzz.len() / wid; + if hei * wid != puzz.len() { + eprintln!("Error: Puzzle size ({}) must be a multiple of width ({}).", puzz.len(), wid); + return; + } + + let len = wid * hei; + + // --- START FIX --- + // Create a record of which cells were originally "." BEFORE creating the solver/modifying arr + let was_originally_dot: Vec = puzz.iter().map(|s| s == ".").collect(); + // --- END FIX --- + + let mut arr = vec![Node::default(); len]; + let mut max_val = 0; // Count non-obstacle cells + + // Initialize 'arr' based on the initial 'puzz' state + for (c, item) in puzz.iter().enumerate() { + if c >= len { break; } // Should not happen with the size check above, but safe + + // Match the C++ logic: '*' is obstacle (-1), others are parsed or default to 0. + // Count non-obstacles towards the max value to be filled. + if item == "*" { + arr[c].val = -1; + } else { + // atoi returns 0 for non-numeric strings like ".". + arr[c].val = item.parse::().unwrap_or(0); + max_val += 1; + } + } + + // Check if there's anything to solve + if max_val == 0 { + println!("\nNo valid cells to fill (all obstacles?)."); + return; // Nothing to solve + } + + let mut solver = NSolver { + wid, + hei, + max_val, + arr, + }; + + // Find start and solve + solver.solve_it(); + + // Update the original puzz vector with results + // Now use the 'was_originally_dot' vector for the check + for (c, item) in puzz.iter_mut().enumerate() { + if c >= solver.arr.len() { break; } // Safety break + + // --- Use the pre-calculated boolean --- + if was_originally_dot[c] { + let node_val = solver.arr[c].val; + // Only update if the solver actually put a positive number there? + // C++ seems to update with whatever is in arr[c] (could be 0 if not reached). + // Let's stick to that behavior. + if node_val >= 0 { // Avoid writing "-1" into a "." cell + *item = node_val.to_string(); + } else { + // If for some reason the solver put -1 here, leave it as "."? + // This case seems unlikely if logic is correct. + eprintln!("Warning: Obstacle value (-1) found at index {} which was originally '.'", c); + *item = ".".to_string(); // Keep it as dot? Or maybe solver.arr[c].val.to_string()? + } + + } + // Cells that were not originally "." remain unchanged. + } + } + + // Internal function to orchestrate the solving process + + fn solve_it(&mut self) { + match self.find_start() { + Some((x, y, start_val)) => { + if !self.search(x, y, start_val + 1) { + println!("\nSearch failed to find a complete path from start ({}, {}). Board may be partially filled.", x, y); + } + // else: Search succeeded, board is filled (or should be) + } + None => { + // Check if already solved (no zeros found) or impossible + let has_zero = self.arr.iter().any(|node| node.val == 0); + if !has_zero && self.max_val > 0 { + // This case could happen if the input already contained a partial or full solution + // and find_start requires a 0 to begin. + println!("\nPuzzle seems pre-filled or already solved. No empty cell (0) found to start search."); + } else if self.max_val > 0 { + // This means find_start iterated through all cells and none were 0. + // Could happen if the board is all obstacles, or already fully numbered. + println!("\nCan't find start point (an empty cell with value 0)! Check input puzzle."); + } + // The max_val == 0 case is handled earlier in solve_puzzle + } + } + } + + // Find the first empty cell (value 0), set it to 1, and return its info + fn find_start(&mut self) -> Option<(usize, usize, i32)> { + for y in 0..self.hei { + for x in 0..self.wid { + let index = x + y * self.wid; + // Ensure we don't try to access out of bounds if arr size is wrong + if index < self.arr.len() && self.arr[index].val == 0 { + self.arr[index].val = 1; // Set start value to 1 + return Some((x, y, 1)); // Return coords and the value assigned (1) + } + } + } + None // No cell with value 0 found + } + + // Recursive backtracking search function + fn search(&mut self, x: usize, y: usize, w: i32) -> bool { + if w > self.max_val { + return true; // Successfully placed all numbers + } + + let current_index = x + y * self.wid; + // Calculate and store neighbors for the current node + self.arr[current_index].neighbors = self.get_neighbors(x, y); + let neighbors_mask = self.arr[current_index].neighbors; + + for d in 0..8 { // Iterate through 8 possible moves + if (neighbors_mask & (1 << d)) != 0 { // Check if the d-th neighbor is valid + let next_x_i32 = (x as i32) + DX[d]; + let next_y_i32 = (y as i32) + DY[d]; + + // Bounds check (redundant if get_neighbors is correct, but safe) + if next_x_i32 >= 0 && next_x_i32 < self.wid as i32 && + next_y_i32 >= 0 && next_y_i32 < self.hei as i32 + { + let next_x = next_x_i32 as usize; + let next_y = next_y_i32 as usize; + let next_index = next_x + next_y * self.wid; + + // Check bounds on arr access too + if next_index < self.arr.len() && self.arr[next_index].val == 0 { + self.arr[next_index].val = w; // Place the next number + + if self.search(next_x, next_y, w + 1) { // Recurse + return true; // Found a valid path + } + + // Backtrack: If the recursive call failed, undo the move + // Check index before backtracking write too + if next_index < self.arr.len() { + self.arr[next_index].val = 0; + } + } + } + } + } + false // If no neighbor leads to a solution + } + + // Calculate the neighbor bitmask for a given cell (x, y) + fn get_neighbors(&self, x: usize, y: usize) -> u8 { + let mut c = 0u8; + for d in 0..8 { // Check all 8 potential moves + let nx_i32 = (x as i32) + DX[d]; + let ny_i32 = (y as i32) + DY[d]; + + // Check bounds + if nx_i32 >= 0 && nx_i32 < self.wid as i32 && + ny_i32 >= 0 && ny_i32 < self.hei as i32 + { + let index = (nx_i32 as usize) + (ny_i32 as usize) * self.wid; + // Check bounds on arr access + if index < self.arr.len() && self.arr[index].val > -1 { // Check not obstacle + c |= 1 << d; // Set the d-th bit + } + } + } + c + } +} // end impl NSolver + + + + +fn main() { + let p = "* . . * . . * . . . . . . . . . . . . . . * . . . . . * * * . . . * * * * * . * * *"; + let wid = 7; + + let mut puzz: Vec = p.split_whitespace().map(String::from).collect(); + + NSolver::solve_puzzle(&mut puzz, wid); + + println!("Solved Puzzle:"); + for (c, item) in puzz.iter().enumerate() { + match item.as_str() { + "*" => print!(" "), // Obstacle + "." => print!(" . "), // Unfilled cell + _ => { + match item.parse::() { + Ok(n) => { + // Handle 0 specifically - it means a '.' cell wasn't reached by the solver + if n == 0 { + print!(" . "); + } else if n < 10 { + print!("0{} ", n); // Pad single digits + } else { + print!("{} ", n); + } + } + Err(_) => { // Should ideally not happen if we only write numbers or "." back + print!(" ? "); + } + } + } + } + if (c + 1) % wid == 0 { + println!(); + } + } + println!("\n"); + + println!("Press Enter to exit..."); + let _ = io::stdout().flush(); + let mut buffer = String::new(); + io::stdin().read_line(&mut buffer).expect("Failed to read line"); +} diff --git a/Task/Solve-a-Numbrix-puzzle/ALGOL-68/solve-a-numbrix-puzzle.alg b/Task/Solve-a-Numbrix-puzzle/ALGOL-68/solve-a-numbrix-puzzle.alg new file mode 100644 index 0000000000..cb88b7c77a --- /dev/null +++ b/Task/Solve-a-Numbrix-puzzle/ALGOL-68/solve-a-numbrix-puzzle.alg @@ -0,0 +1,132 @@ +BEGIN # solve a Numbrix puzzle - based on the Wren Hidato solver plus this # + # solves puzzles with 1 as an unknown using the zkl sample's method # + PR read "sort.incl.a68" PR # include sort utilities # + + [,]INT moves = ( ( 1, 0 ), ( 0, 1 ), ( -1, 0 ), ( 0, -1 ) ); + + # returns TRUE if a solution for board with the specified given values # + # ( the values initially placed on the board ) can be found # + # n is the value to place, r and c the starting row and column # + # and next the position of the next value in given # + # returns FALSE if a solution cannot be found # + PROC solve board with givens = ( REF[,]INT board, []INT given, INT r, c, n, next, board size )BOOL: + IF n > board size + THEN TRUE + ELIF r < 1 LWB board OR r > 1 UPB board + OR c < 2 LWB board OR c > 2 UPB board + THEN FALSE + ELIF INT back = board[ r, c ]; + back /= 0 AND back /= n + THEN FALSE + ELIF back = 0 AND IF next > UPB given THEN FALSE ELSE given[ next ] = n FI + THEN FALSE + ELSE INT next2 = IF back = n THEN next + 1 ELSE next FI; + board[ r, c ] := n; + BOOL found := FALSE; + FOR m pos FROM 1 LWB moves TO 1 UPB moves + WHILE INT rm = r + moves[ m pos, 2 LWB moves ]; + INT cm = c + moves[ m pos, 2 UPB moves ]; + NOT ( found := solve board with givens( board, given, rm, cm, n + 1, next2, board size ) ) + DO SKIP OD; + IF NOT found THEN board[ r, c ] := back FI; + found + FI # solve board with givens # ; + + # returns the solution for board data # + # or an empty board if there isn't one # + PROC solve = ( [,]INT board data )[,]INT: + BEGIN + [ 1 LWB board data : 1 UPB board data + , 2 LWB board data : 2 UPB board data + ]INT board := board data; + INT board size = ( ( 1 UPB board - 1 LWB board ) + 1 ) + * ( ( 2 UPB board - 2 LWB board ) + 1 ) + ; + [ 1 : board size ]INT given1; + INT g pos := 0, start r := 0, start c := 0; + FOR i FROM 1 LWB board TO 1 UPB board DO + FOR j FROM 2 LWB board TO 2 UPB board DO + IF board[ i, j ] > 0 THEN + given1[ g pos +:= 1 ] := board[ i, j ]; + IF board[ i, j ] = 1 THEN start r := i; start c := j FI + FI + OD + OD; + IF start r = 0 THEN # need to pretend 1 is on the board, even # + given1[ g pos +:= 1 ] := 1 # though is isn't # + FI; + [ 1 : g pos ]INT given := given1[ 1 : g pos ]; + QUICKSORT given; + BOOL solved := FALSE; + IF start r /= 0 THEN # the position of 1 is known # + solved := solve board with givens( board, given, start r, start c, 1, 1, board size ) + ELSE # try 1 in all empty places until we find a solution # + FOR r pos FROM 1 LWB board TO 1 UPB board WHILE NOT solved DO + FOR c pos FROM 2 LWB board TO 2 UPB board WHILE NOT solved DO + IF board[ r pos, c pos ] = 0 THEN + board[ r pos, c pos ] := 1; + solved := solve board with givens( board, given, r pos, c pos, 1, 1, board size ); + IF NOT solved THEN board[ r pos, c pos ] := 0 FI + FI + OD + OD + FI; + IF solved THEN board ELSE [ 1 : 0, 1 : 0 ]INT no solution; no solution FI + END # solve # ; + + PROC print board = ( [,]INT board )VOID: + FOR i FROM 1 LWB board TO 1 UPB board DO + FOR j FROM 2 LWB board TO 2 UPB board DO + INT v = board[ i, j ]; + IF v < 0 THEN print( ( " " ) ) + ELIF v = 0 THEN print( ( " __" ) ) + ELSE print( ( whole( v, -3 ) ) ) + FI + OD; + print( ( newline ) ) + OD # print board # ; + + + [,,]INT tests = ( ( ( 0, 0, 0, 0, 0, 0, 0, 0, 0 ) + , ( 0, 0, 46, 45, 0, 55, 74, 0, 0 ) + , ( 0, 38, 0, 0, 43, 0, 0, 78, 0 ) + , ( 0, 35, 0, 0, 0, 0, 0, 71, 0 ) + , ( 0, 0, 33, 0, 0, 0, 59, 0, 0 ) + , ( 0, 17, 0, 0, 0, 0, 0, 67, 0 ) + , ( 0, 18, 0, 0, 11, 0, 0, 64, 0 ) + , ( 0, 0, 24, 21, 0, 1, 2, 0, 0 ) + , ( 0, 0, 0, 0, 0, 0, 0, 0, 0 ) + ) + , ( ( 0, 0, 0, 0, 0, 0, 0, 0, 0 ) + , ( 0, 11, 12, 15, 18, 21, 62, 61, 0 ) + , ( 0, 6, 0, 0, 0, 0, 0, 60, 0 ) + , ( 0, 33, 0, 0, 0, 0, 0, 57, 0 ) + , ( 0, 32, 0, 0, 0, 0, 0, 56, 0 ) + , ( 0, 37, 0, 1, 0, 0, 0, 73, 0 ) + , ( 0, 38, 0, 0, 0, 0, 0, 72, 0 ) + , ( 0, 43, 44, 47, 48, 51, 76, 77, 0 ) + , ( 0, 0, 0, 0, 0, 0, 0, 0, 0 ) + ) + , ( ( 17, 0, 0, 0, 11, 0, 0, 0, 59 ) + , ( 0, 15, 0, 0, 6, 0, 0, 61, 0 ) + , ( 0, 0, 3, 0, 0, 0, 63, 0, 0 ) + , ( 0, 0, 0, 0, 66, 0, 0, 0, 0 ) + , ( 23, 24, 0, 68, 67, 78, 0, 54, 55 ) + , ( 0, 0, 0, 0, 72, 0, 0, 0, 0 ) + , ( 0, 0, 35, 0, 0, 0, 49, 0, 0 ) + , ( 0, 29, 0, 0, 40, 0, 0, 47, 0 ) + , ( 31, 0, 0, 0, 39, 0, 0, 0, 45 ) + ) + ); + FOR t pos FROM 1 LWB tests TO 1 UPB tests DO + [,]INT board = tests[ t pos, : , : ]; + print board( board ); + print( ( newline ) ); + IF [,]INT solution = solve( board ); + 1 LWB solution > 1 UPB solution + THEN print( ( "No solution found", newline ) ) + ELSE print board( solution ) + FI; + print( ( newline ) ) + OD +END diff --git a/Task/Solve-a-Numbrix-puzzle/EasyLang/solve-a-numbrix-puzzle.easy b/Task/Solve-a-Numbrix-puzzle/EasyLang/solve-a-numbrix-puzzle.easy new file mode 100644 index 0000000000..eb3600a661 --- /dev/null +++ b/Task/Solve-a-Numbrix-puzzle/EasyLang/solve-a-numbrix-puzzle.easy @@ -0,0 +1,76 @@ +moves[][] = [ [ -1 0 ] [ 0 -1 ] [ 0 1 ] [ 1 0 ] ] +global brd[][] maxr maxc maxcnt . +func solve r c cnt . + if cnt > maxcnt : return 1 + for m = 1 to 4 + rn = r + moves[m][1] + cn = c + moves[m][2] + if rn >= 1 and rn <= maxr and cn >= 1 and cn <= maxc + if brd[rn][cn] = 0 + brd[rn][cn] = cnt + if solve rn cn (cnt + 1) = 1 : return 1 + brd[rn][cn] = 0 + elif brd[rn][cn] = cnt + if solve rn cn (cnt + 1) = 1 : return 1 + . + . + . + return 0 +. +proc prepare brd$ &r0 &c0 . + brd$[] = strsplit brd$ "\n" + maxc = len brd$[2] / 3 + maxr = len brd$[] - 2 + maxcnt = maxc * maxr + len brd[][] maxr + for r to maxr + len brd[r][] maxc + for c to maxc + c$ = substr brd$[r + 1] (c * 3 - 2) 3 + h = number c$ + if h = 1 + r0 = r + c0 = c + . + brd[r][c] = h + . + . +. +proc printbrd . + numfmt 3 0 + for r to maxr + for c to maxc : write brd[r][c] + print "" + . +. +proc numbrix brd$ . + prepare brd$ r0 c0 + if solve r0 c0 2 = 1 + printbrd + else + print "no solutions found" + . + print "" +. +numbrix " + 0 0 0 0 0 0 0 0 0 + 0 0 46 45 0 55 74 0 0 + 0 38 0 0 43 0 0 78 0 + 0 35 0 0 0 0 0 71 0 + 0 0 33 0 0 0 59 0 0 + 0 17 0 0 0 0 0 67 0 + 0 18 0 0 11 0 0 64 0 + 0 0 24 21 0 1 2 0 0 + 0 0 0 0 0 0 0 0 0 +" +numbrix " + 0 0 0 0 0 0 0 0 0 + 0 11 12 15 18 21 62 61 0 + 0 6 0 0 0 0 0 60 0 + 0 33 0 0 0 0 0 57 0 + 0 32 0 0 0 0 0 56 0 + 0 37 0 1 0 0 0 73 0 + 0 38 0 0 0 0 0 72 0 + 0 43 44 47 48 51 76 77 0 + 0 0 0 0 0 0 0 0 0 +" diff --git a/Task/Solve-a-Numbrix-puzzle/JavaScript/solve-a-numbrix-puzzle.js b/Task/Solve-a-Numbrix-puzzle/JavaScript/solve-a-numbrix-puzzle.js new file mode 100644 index 0000000000..da020fa10a --- /dev/null +++ b/Task/Solve-a-Numbrix-puzzle/JavaScript/solve-a-numbrix-puzzle.js @@ -0,0 +1,110 @@ +const example1 = [ + "00,00,00,00,00,00,00,00,00", + "00,00,46,45,00,55,74,00,00", + "00,38,00,00,43,00,00,78,00", + "00,35,00,00,00,00,00,71,00", + "00,00,33,00,00,00,59,00,00", + "00,17,00,00,00,00,00,67,00", + "00,18,00,00,11,00,00,64,00", + "00,00,24,21,00,01,02,00,00", + "00,00,00,00,00,00,00,00,00", +]; + +const example2 = [ + "00,00,00,00,00,00,00,00,00", + "00,11,12,15,18,21,62,61,00", + "00,06,00,00,00,00,00,60,00", + "00,33,00,00,00,00,00,57,00", + "00,32,00,00,00,00,00,56,00", + "00,37,00,01,00,00,00,73,00", + "00,38,00,00,00,00,00,72,00", + "00,43,44,47,48,51,76,77,00", + "00,00,00,00,00,00,00,00,00", +]; + +const moves = [[1, 0], [0, 1], [-1, 0], [0, -1]]; + +let grid, clues, totalToFill; + +function solve(r, c, count, nextClue) { + if (count > totalToFill) { + return true; + } + + const back = grid[r][c]; + + if (back !== 0 && back !== count) { + return false; + } + + if (back === 0 && nextClue < clues.length && clues[nextClue] === count) { + return false; + } + + let newNextClue = nextClue; + if (back === count) { + newNextClue++; + } + + grid[r][c] = count; + for (const move of moves) { + if (solve(r + move[1], c + move[0], count + 1, newNextClue)) { + return true; + } + } + grid[r][c] = back; + return false; +} + +function printResult(n) { + console.log(`Solution for example ${n}:`); + for (const row of grid) { + let line = ""; + for (const i of row) { + if (i === -1) { + continue; + } + line += `${i.toString().padStart(2)} `; + } + console.log(line); + } +} + +function main() { + const boards = [example1, example2]; + + for (let n = 0; n < boards.length; n++) { + const board = boards[n]; + const nRows = board.length + 2; + const nCols = board[0].split(',').length + 2; + let startRow = 0, startCol = 0; + grid = Array(nRows).fill().map(() => Array(nCols).fill(-1)); + totalToFill = (nRows - 2) * (nCols - 2); + let lst = []; + + for (let r = 0; r < nRows; r++) { + if (r >= 1 && r < nRows - 1) { + const row = board[r - 1].split(','); + for (let c = 1; c < nCols - 1; c++) { + const val = parseInt(row[c - 1]); + if (val > 0) { + lst.push(val); + } + if (val === 1) { + startRow = r; + startCol = c; + } + grid[r][c] = val; + } + } + } + + lst.sort((a, b) => a - b); + clues = lst; + if (solve(startRow, startCol, 1, 0)) { + printResult(n + 1); + } + } +} + +main(); diff --git a/Task/Solve-a-Numbrix-puzzle/Rust/solve-a-numbrix-puzzle.rs b/Task/Solve-a-Numbrix-puzzle/Rust/solve-a-numbrix-puzzle.rs new file mode 100644 index 0000000000..eea882792c --- /dev/null +++ b/Task/Solve-a-Numbrix-puzzle/Rust/solve-a-numbrix-puzzle.rs @@ -0,0 +1,205 @@ +use std::io::{self, Write}; + +#[derive(Clone)] // Add Clone derivation to fix the compilation error +struct Node { + val: i32, + neighbors: u8, +} + +struct NSolver { + wid: i32, + hei: i32, + max: i32, + arr: Vec, + we_have: Vec, + dx: Vec, + dy: Vec, +} + +impl NSolver { + fn new() -> Self { + NSolver { + wid: 0, + hei: 0, + max: 0, + arr: Vec::new(), + we_have: Vec::new(), + dx: vec![-1, 1, 0, 0], + dy: vec![0, 0, -1, 1], + } + } + + fn solve(&mut self, puzz: &mut Vec, max_wid: i32) { + if puzz.is_empty() { + return; + } + + self.wid = max_wid; + self.hei = puzz.len() as i32 / self.wid; + self.max = self.wid * self.hei; + let len = self.max as usize; + + self.arr = vec![Node { val: 0, neighbors: 0 }; len]; + self.we_have = vec![false; len + 1]; + + let mut c = 0; + for s in puzz.iter() { + if s == "*" { + self.max -= 1; + self.arr[c].val = -1; + c += 1; + continue; + } + + self.arr[c].val = s.parse::().unwrap_or(0); + if self.arr[c].val > 0 { + self.we_have[self.arr[c].val as usize] = true; + } + c += 1; + } + + self.solve_it(); + + c = 0; + for s in puzz.iter_mut() { + if s == "." { + *s = self.arr[c].val.to_string(); + } + c += 1; + } + } + + fn search(&mut self, x: i32, y: i32, w: i32, dr: i32) -> bool { + if (w > self.max && dr > 0) || (w < 1 && dr < 0) || (w == self.max && self.we_have[w as usize]) { + return true; + } + + let idx = (x + y * self.wid) as usize; + self.arr[idx].neighbors = self.get_neighbors(x, y); + + if self.we_have[w as usize] { + for d in 0..4 { + if (self.arr[idx].neighbors & (1 << d)) != 0 { + let a = x + self.dx[d]; + let b = y + self.dy[d]; + let neighbor_idx = (a + b * self.wid) as usize; + + if self.arr[neighbor_idx].val == w { + if self.search(a, b, w + dr, dr) { + return true; + } + } + } + } + return false; + } + + for d in 0..4 { + if (self.arr[idx].neighbors & (1 << d)) != 0 { + let a = x + self.dx[d]; + let b = y + self.dy[d]; + let neighbor_idx = (a + b * self.wid) as usize; + + if self.arr[neighbor_idx].val == 0 { + self.arr[neighbor_idx].val = w; + if self.search(a, b, w + dr, dr) { + return true; + } + self.arr[neighbor_idx].val = 0; + } + } + } + + false + } + + fn get_neighbors(&self, x: i32, y: i32) -> u8 { + let mut retval: u8 = 0; + + for xx in 0..4 { + let a = x + self.dx[xx]; + let b = y + self.dy[xx]; + + if a < 0 || b < 0 || a >= self.wid || b >= self.hei { + continue; + } + + let idx = (a + b * self.wid) as usize; + if self.arr[idx].val > -1 { + retval |= 1 << xx; + } + } + + retval + } + + fn solve_it(&mut self) { + let (x, y, z) = self.find_start(); + if z == 99999 { + println!("\nCan't find start point!"); + return; + } + + self.search(x, y, z + 1, 1); + if z > 1 { + self.search(x, y, z - 1, -1); + } + } + + fn find_start(&self) -> (i32, i32, i32) { + let mut z = 99999; + let mut x = 0; + let mut y = 0; + + for b in 0..self.hei { + for a in 0..self.wid { + let idx = (a + self.wid * b) as usize; + if self.arr[idx].val > 0 && self.arr[idx].val < z { + x = a; + y = b; + z = self.arr[idx].val; + } + } + } + + (x, y, z) + } +} + +fn main() { + let wid = 9; + //let p = ". . . . . . . . . . . 46 45 . 55 74 . . . 38 . . 43 . . 78 . . 35 . . . . . 71 . . . 33 . . . 59 . . . 17 . . . . . 67 . . 18 . . 11 . . 64 . . . 24 21 . 1 2 . . . . . . . . . . ."; + //let p = ". . . . . . . . . . 11 12 15 18 21 62 61 . . 6 . . . . . 60 . . 33 . . . . . 57 . . 32 . . . . . 56 . . 37 . 1 . . . 73 . . 38 . . . . . 72 . . 43 44 47 48 51 76 77 . . . . . . . . . ."; + let p = "17 . . . 11 . . . 59 . 15 . . 6 . . 61 . . . 3 . . . 63 . . . . . . 66 . . . . 23 24 . 68 67 78 . 54 55 . . . . 72 . . . . . . 35 . . . 49 . . . 29 . . 40 . . 47 . 31 . . . 39 . . . 45"; + + let mut puzz: Vec = p.split_whitespace().map(|s| s.to_string()).collect(); + let mut solver = NSolver::new(); + solver.solve(&mut puzz, wid); + + let mut c = 0; + for s in &puzz { + if s != "*" && s != "." { + if let Ok(num) = s.parse::() { + if num < 10 { + print!("0"); + } + } + print!("{} ", s); + } else { + print!(" "); + } + + c += 1; + if c >= wid { + println!(); + c = 0; + } + } + println!("\n"); + + // Equivalent of system("pause") in Rust + // print!("Press Enter to continue..."); + // io::stdout().flush().unwrap(); + // let mut input = String::new(); + // io::stdin().read_line(&mut input).unwrap(); +} diff --git a/Task/Solve-a-Numbrix-puzzle/Zkl/solve-a-numbrix-puzzle-1.zkl b/Task/Solve-a-Numbrix-puzzle/Zkl/solve-a-numbrix-puzzle-1.zkl index de12ddf8a7..c03498dfd5 100644 --- a/Task/Solve-a-Numbrix-puzzle/Zkl/solve-a-numbrix-puzzle-1.zkl +++ b/Task/Solve-a-Numbrix-puzzle/Zkl/solve-a-numbrix-puzzle-1.zkl @@ -10,7 +10,7 @@ class Puzzle{ // hold info concerning this puzzle fcn print_board{ d:=Dictionary(-1," ", 0,"__"); foreach r in (board){ - r.pump(String,'wrap(c){ "%2s ".fmt(d.find(c,c)) }).println(); + r.pump(String,'wrap(c){ "%2s ".fmt(d.find(c,c)) }).println(); } } fcn init(s,adjacent){ @@ -21,14 +21,14 @@ class Puzzle{ // hold info concerning this puzzle given,start=List(),Void; cells,terminated=0,True; foreach r,row in (lines.enumerate()){ - foreach c,cell in (row.split().enumerate()){ - if(cell=="X") continue; // X == not in play, leave at -1 - cells+=1; - val:=cell.toInt(); - board[r][c]=val; - given.append(val); - if(val==1) start=T(r,c); - } + foreach c,cell in (row.split().enumerate()){ + if(cell=="X") continue; // X == not in play, leave at -1 + cells+=1; + val:=cell.toInt(); + board[r][c]=val; + given.append(val); + if(val==1) start=T(r,c); + } } println("Number of cells = ",cells); if(not given.holds(cells)){ given.append(cells); terminated=False; } @@ -37,7 +37,7 @@ class Puzzle{ // hold info concerning this puzzle fcn solve{ //-->Bool if(start) return(_solve(start.xplode())); foreach r,c in (nrows,ncols){ - if(board[r][c]==0 and _solve(r,c)) return(True); + if(board[r][c]==0 and _solve(r,c)) return(True); } False } diff --git a/Task/Solve-a-Numbrix-puzzle/Zkl/solve-a-numbrix-puzzle-2.zkl b/Task/Solve-a-Numbrix-puzzle/Zkl/solve-a-numbrix-puzzle-2.zkl index ff1b705375..79fb9e68c7 100644 --- a/Task/Solve-a-Numbrix-puzzle/Zkl/solve-a-numbrix-puzzle-2.zkl +++ b/Task/Solve-a-Numbrix-puzzle/Zkl/solve-a-numbrix-puzzle-2.zkl @@ -23,12 +23,25 @@ hi2:= // 0==empty cell, X==not a cell 0 43 44 47 48 51 76 77 0 0 0 0 0 0 0 0 0 0"; #<<< + +hi3:= +#<<< +"17 0 0 0 11 0 0 0 59 + 0 15 0 0 6 0 0 61 0 + 0 0 3 0 0 0 63 0 0 + 0 0 0 0 66 0 0 0 0 + 23 24 0 68 67 78 0 54 55 + 0 0 0 0 72 0 0 0 0 + 0 0 35 0 0 0 49 0 0 + 0 29 0 0 40 0 0 47 0 + 31 0 0 0 39 0 0 0 45"; +#<<< adjacent:=T( T(-1,0), T( 0,-1), T( 0,1), T( 1,0) ); -foreach hi in (T(hi1,hi2)){ - puzzle:=Puzzle(hi); puzzle.adjacent=adjacent; +foreach hi in (T(hi1,hi2,hi3)){ + puzzle:=Puzzle(hi,adjacent); puzzle.print_board(); puzzle.solve(); println(); diff --git a/Task/Solve-the-no-connection-puzzle/ALGOL-68/solve-the-no-connection-puzzle.alg b/Task/Solve-the-no-connection-puzzle/ALGOL-68/solve-the-no-connection-puzzle.alg new file mode 100644 index 0000000000..9605f99749 --- /dev/null +++ b/Task/Solve-the-no-connection-puzzle/ALGOL-68/solve-the-no-connection-puzzle.alg @@ -0,0 +1,90 @@ +BEGIN CO Solve the no connection puzzle + the board looks like: + A B + /|\ /|\ + / | X | \ + / |/ \| \ + C - D - E - F + \ |\ /| / + \ | X | / + \|/ \|/ + G H + we need to place 1..8 at A..G so that each connected + value differs by at least 2 (e.g., A=1 and D=3 is OK + but A=1 and D=2 is not) + CO + + PROC not ok = ( INT x )BOOL: ABS x < 2; + PROC ok = ( INT a, b, c, d, e, f, g, h )BOOL: + IF not ok( a - c ) OR not ok( a - d ) OR not ok( a - e ) THEN FALSE + ELIF not ok( b - d ) OR not ok( b - e ) OR not ok( b - f ) THEN FALSE + ELIF not ok( g - c ) OR not ok( g - d ) OR not ok( g - e ) THEN FALSE + ELIF not ok( h - d ) OR not ok( h - e ) OR not ok( h - f ) THEN FALSE + ELIF not ok( c - d ) OR not ok( d - e ) OR not ok( e - f ) THEN FALSE + ELSE TRUE + FI # ok # ; + + PROC is solution = ( []INT a )BOOL: + ok( a[ 0 ], a[ 1 ], a[ 2 ], a[ 3 ], a[ 4 ], a[ 5 ], a[ 6 ], a[ 7 ] ); + + # Heap's algorithm for generating permutations # + # - from the pseudo-code on the Wikipedia page # + # have permutation is called for each generated permutation # + PROC generate = ( INT k, REF[]INT a, REF INT swap count, PROC([]INT,INT)VOID have permutation )VOID: + IF k = 1 THEN + have permutation( a, swap count ) + ELSE + # Generate permutations with kth unaltered # + # Initially k = length a # + generate( k - 1, a, swap count, have permutation ); + # Generate permutations for kth swapped with each k-1 initial # + FOR i FROM 0 TO k - 2 DO + # Swap choice dependent on parity of k (even or odd) # + swap count +:= 1; + INT swap item = IF ODD k THEN 0 ELSE i FI; + INT t = a[ swap item ]; + a[ swap item ] := a[ k - 1 ]; + a[ k - 1 ] := t; + generate( k - 1, a, swap count, have permutation ) + OD + FI # generate # ; + # generate permutations of a # + PROC permute = ( REF[]INT a, PROC([]INT,INT)VOID have permutation )VOID: + BEGIN + INT swap count := 0; + generate( ( UPB a + 1 ) - LWB a, a[ AT 0 ], swap count, have permutation ) + END # permute # ; + + # handle a permutation # + PROC possible solution = ( []INT p, INT swap count )VOID: + IF is solution( p ) THEN # have a solution # + IF first solution THEN + print( ( "First solution found:", newline ) ); + OP N = ( INT v )CHAR: REPR ( v + ABS "0" ); + CHAR a = N p[ 0 ], b = N p[ 1 ], c = N p[ 2 ], d = N p[ 3 ]; + CHAR e = N p[ 4 ], f = N p[ 5 ], g = N p[ 6 ], h = N p[ 7 ]; + print( ( " ", a, " ", b, newline ) ); + print( ( " /|\ /|\", newline ) ); + print( ( " / | X | \", newline ) ); + print( ( " / |/ \| \", newline ) ); + print( ( " ", c, " - ", d, " - ", e, " - ", f, newline ) ); + print( ( " \ |\ /| /", newline ) ); + print( ( " \ | X | /", newline ) ); + print( ( " \|/ \|/", newline ) ); + print( ( " ", g, " ", h, newline ) ); + print( ( newline, "All solutions:", newline ) ); + first solution := FALSE + FI; + print( ( " [" ) ); + FOR i FROM LWB p TO UPB p DO + print( ( whole( p[ i ], 0 ) ) ); + IF i = UPB p THEN print( ( "]" ) ) ELSE print( ( ", " ) ) FI + OD; + print( ( " after ", whole( swap count, 0 ), " swaps", newline ) ) + FI # possible solution # ; + + [ 1 : 8 ]INT items := ( 1, 2, 3, 4, 5, 6, 7, 8 ); + BOOL first solution := TRUE; + permute( items, possible solution ) + +END diff --git a/Task/Solve-the-no-connection-puzzle/EasyLang/solve-the-no-connection-puzzle.easy b/Task/Solve-the-no-connection-puzzle/EasyLang/solve-the-no-connection-puzzle.easy new file mode 100644 index 0000000000..4245d66273 --- /dev/null +++ b/Task/Solve-the-no-connection-puzzle/EasyLang/solve-the-no-connection-puzzle.easy @@ -0,0 +1,23 @@ +cons[][] = [ [ 3 4 5 ] [ 4 5 6 ] [ 4 7 ] [ 5 7 8 ] [ 6 7 8 ] [ 8 ] [ ] [ ] ] +n = len cons[][] +len peg[] n +# +proc init . + for i to n : peg[i] = i +. +init +# +proc permute k . + for i = k to n + swap peg[i] peg[k] + permute k + 1 + swap peg[k] peg[i] + . + if k = n + for i to n : for j in cons[i][] + if abs (peg[i] - peg[j]) = 1 : break 2 + . + if i > n : print peg[] + . +. +permute 1 diff --git a/Task/Sort-a-list-of-object-identifiers/APL/sort-a-list-of-object-identifiers.apl b/Task/Sort-a-list-of-object-identifiers/APL/sort-a-list-of-object-identifiers.apl new file mode 100644 index 0000000000..4e28e5deb5 --- /dev/null +++ b/Task/Sort-a-list-of-object-identifiers/APL/sort-a-list-of-object-identifiers.apl @@ -0,0 +1 @@ +oidsort ← {⍵[⍋{⊃(//)'.'⎕VFI⍵}¨⍵]} diff --git a/Task/Sort-a-list-of-object-identifiers/EasyLang/sort-a-list-of-object-identifiers.easy b/Task/Sort-a-list-of-object-identifiers/EasyLang/sort-a-list-of-object-identifiers.easy index 73666aae50..39dd5e8ce9 100644 --- a/Task/Sort-a-list-of-object-identifiers/EasyLang/sort-a-list-of-object-identifiers.easy +++ b/Task/Sort-a-list-of-object-identifiers/EasyLang/sort-a-list-of-object-identifiers.easy @@ -1,20 +1,12 @@ -proc sort . d$[] . - for s$ in d$[] - d[][] &= number strsplit s$ "." - . +proc sort &d$[] . + for s$ in d$[] : d[][] &= number strsplit s$ "." n = len d[][] - for i = 1 to n - 1 - for j = i + 1 to n - m = lower len d[i][] len d[j][] - for k to m - if d[i][k] <> d[j][k] - break 1 - . - . - if k > m and len d[i][] > len d[j][] or d[i][k] > d[j][k] - swap d[i][] d[j][] - . + for i = 1 to n - 1 : for j = i + 1 to n + m = lower len d[i][] len d[j][] + for k to m + if d[i][k] <> d[j][k] : break 1 . + if k > m and len d[i][] > len d[j][] or d[i][k] > d[j][k] : swap d[i][] d[j][] . for i to len d[][] d$[i] = d[i][1] diff --git a/Task/Sort-an-array-of-composite-structures/Crystal/sort-an-array-of-composite-structures.cr b/Task/Sort-an-array-of-composite-structures/Crystal/sort-an-array-of-composite-structures.cr new file mode 100644 index 0000000000..5570a1ab95 --- /dev/null +++ b/Task/Sort-an-array-of-composite-structures/Crystal/sort-an-array-of-composite-structures.cr @@ -0,0 +1,11 @@ +record City, name : String, country : String + +cities = [{"Warsaw", "Poland"}, {"Prague", "Czech Republic"}, {"Paris", "France"}, + {"Lima", "Peru"}, {"Montevideo", "Uruguay"}, {"Bogotá", "Colombia"}, + {"Cairo", "Egypt"}, {"Yaoundé", "Cameroon"}, {"Luanda", "Angola"}] + .map {|name, country| City.new name, country } + +puts "unsorted:" +pp cities +puts "sorted:" +pp cities.sort_by &.name diff --git a/Task/Sort-an-array-of-composite-structures/M2000-Interpreter/sort-an-array-of-composite-structures.m2000 b/Task/Sort-an-array-of-composite-structures/M2000-Interpreter/sort-an-array-of-composite-structures.m2000 index 6f21257769..9a3d221aaa 100644 --- a/Task/Sort-an-array-of-composite-structures/M2000-Interpreter/sort-an-array-of-composite-structures.m2000 +++ b/Task/Sort-an-array-of-composite-structures/M2000-Interpreter/sort-an-array-of-composite-structures.m2000 @@ -57,7 +57,7 @@ module Sort_an_array_of_composite_structures{ return } Sort_an_array_of_composite_structures -Pint +Print module Checkit2 { Inventory Alfa="Joe":=5531, "Adam":=2341, "Bernie":=122 Append Alfa, "Walter":=1234, "David":=19 diff --git a/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-2.rexx b/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-2.rexx index 55bf6843c1..0dbe5524de 100644 --- a/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-2.rexx +++ b/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-2.rexx @@ -1,16 +1,18 @@ -Main: +include Settings + +say 'SORT COMPOSITE ARRAY - 5 Mar 2025' +say version +say call Create call Show 'Not ordered' call SortStateCity call Show 'By state and city' call SortPopCityN call Show 'By pop (numeric desc) and city' -table = 'states.' -keys = 'pop. state.'; data = 'city.' +table = 'states.'; keys = 'pop. state.'; data = 'city.' call SortPopCityS table,keys,data call Show 'By pop (string) and city' -table = 'states.' -keys = 'city. state.'; data = 'pop.' +table = 'states.'; keys = 'city. state.'; data = 'pop.' call SortCityState table,keys,data call Show 'By city and state' return diff --git a/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-3.rexx b/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-3.rexx deleted file mode 100644 index 0df1385350..0000000000 --- a/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-3.rexx +++ /dev/null @@ -1,124 +0,0 @@ --- Module Quicksort21.inc - Build 30 Jan 2025 --- Fast stem sort - -default [label]=Quicksort21 [table]=table. [key1]=key1. [key2]=key2. [data1]=data1. [lt]=< [eq]== [gt]=> - -[label]: --- Sort a stem on 2 key columns, syncing 1 data column -procedure expose [table] --- Sort -n = [table]0; s = 1; sl.1 = 1; sr.1 = n -do until s = 0 - l = sl.s; r = sr.s; s = s-1 - do until l >= r --- Up to 19 rows selection sort is faster - if r-l < 20 then do - do i = l+1 to r - a = [table][key1]i - b = [table][key2]i - c = [table][data1]i - do j = i-1 by -1 to l - if [table][key1]j [lt] a then - leave - if [table][key1]j [eq] a then - if [table][key2]j [lt]= b then - leave - k = j+1 - [table][key1]k = [table][key1]j - [table][key2]k = [table][key2]j - [table][data1]k = [table][data1]j - end - k = j+1 - [table][key1]k = a - [table][key2]k = b - [table][data1]k = c - end - if s = 0 then - leave - l = sl.s; r = sr.s; s = s-1 - end - else do --- Find optimized pivot - m = (l+r)%2 - if [table][key1]l [gt] [table][key1]m then do - t = [table][key1]l; [table][key1]l = [table][key1]m; [table][key1]m = t - t = [table][key2]l; [table][key2]l = [table][key2]m; [table][key2]m = t - t = [table][data1]l; [table][data1]l = [table][data1]m; [table][data1]m = t - end - else do - if [table][key1]l [eq] [table][key1]m then do - if [table][key2]l [gt] [table][key2]m then do - t = [table][key2]l; [table][key2]l = [table][key2]m; [table][key2]m = t - t = [table][data1]l; [table][data1]l = [table][data1]m; [table][data1]m = t - end - end - end - if [table][key1]l [gt] [table][key1]r then do - t = [table][key1]l; [table][key1]l = [table][key1]r; [table][key1]r = t - t = [table][key2]l; [table][key2]l = [table][key2]r; [table][key2]r = t - t = [table][data1]l; [table][data1]l = [table][data1]r; [table][data1]r = t - end - else do - if [table][key1]l [eq] [table][key1]r then do - if [table][key2]l [gt] [table][key2]r then do - t = [table][key2]l; [table][key2]l = [table][key2]r; [table][key2]r = t - t = [table][data1]l; [table][data1]l = [table][data1]r; [table][data1]r = t - end - end - end - if [table][key1]m [gt] [table][key1]r then do - t = [table][key1]m; [table][key1]m = [table][key1]r; [table][key1]r = t - t = [table][key2]m; [table][key2]m = [table][key2]r; [table][key2]r = t - t = [table][data1]m; [table][data1]m = [table][data1]r; [table][data1]r = t - end - else do - if [table][key1]m [eq] [table][key1]r then do - if [table][key2]m [gt] [table][key2]r then do - t = [table][key2]m; [table][key2]m = [table][key2]r; [table][key2]r = t - t = [table][data1]m; [table][data1]m = [table][data1]r; [table][data1]r = t - end - end - end --- Rearrange rows in partition - i = l; j = r - a = [table][key1]m - b = [table][key2]m - do until i > j - do i = i - if [table][key1]i [gt] a then - leave - if [table][key1]i [eq] a then - if [table][key2]i [gt]= b then - leave - end - do j = j by -1 - if [table][key1]j [lt] a then - leave - if [table][key1]j [eq] a then - if [table][key2]j [lt]= b then - leave - end - if i <= j then do - t = [table][key1]i; [table][key1]i = [table][key1]j; [table][key1]j = t - t = [table][key2]i; [table][key2]i = [table][key2]j; [table][key2]j = t - t = [table][data1]i; [table][data1]i = [table][data1]j; [table][data1]j = t - i = i+1; j = j-1 - end - end --- Next partition - if j-l < r-i then do - if i < r then do - s = s+1; sl.s = i; sr.s = r - end - r = j - end - else do - if l < j then do - s = s+1; sl.s = l; sr.s = j - end - l = i - end - end - end -end -return diff --git a/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-4.rexx b/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-4.rexx deleted file mode 100644 index b12abc5667..0000000000 --- a/Task/Sort-an-array-of-composite-structures/REXX/sort-an-array-of-composite-structures-4.rexx +++ /dev/null @@ -1,173 +0,0 @@ --- Module Quicksort.inc - Build 30 Jan 2025 --- Generic stem sort - -default [label]=Quicksort [lt]=< [eq]== [gt]=> - -[label]: --- Sort a stem on 1 or more key columns, syncing 0 or more data columns -procedure expose (table) -arg table,keys,data --- Collect keys -kn = Words(keys) -do x = 1 to kn - key.x = Word(keys,x) -end --- Collect data -dn = Words(data) -do x = 1 to dn - data.x = Word(data,x) -end --- Sort -n = Value(table||0); s = 1; sl.1 = 1; sr.1 = n -do until s = 0 - l = sl.s; r = sr.s; s = s-1 - do until l >= r --- Up to 19 rows insertion sort is faster - if r-l < 20 then do - do i = l+1 to r - do x = 1 to kn - k.x = Value(table||key.x||i) - end - do x = 1 to dn - d.x = Value(table||data.x||i) - end - do j=i-1 to l by -1 - do x = 1 to kn - a = Value(table||key.x||j) - if a [gt] k.x then - leave x - if a [eq] k.x then - if x < kn then - iterate x - leave j - end - k = j+1 - do x = 1 to kn - t = Value(table||key.x||j) - call value table||key.x||k,t - end - do x = 1 to dn - t = Value(table||data.x||j) - call value table||data.x||k,t - end - end - k = j+1 - do x = 1 to kn - call value table||key.x||k,k.x - end - do x = 1 to dn - call value table||data.x||k,d.x - end - end - if s = 0 then - leave - l = sl.s; r = sr.s; s = s-1 - end - else do --- Find optimized pivot - m = (l+r)%2 - do x = 1 to kn - a = Value(table||key.x||l); b = Value(table||key.x||m) - if a [gt] b then do - do y = 1 to kn - t = Value(table||key.y||l); u = Value(table||key.y||m) - call value table||key.y||l,u; call value table||key.y||m,t - end - do y = 1 to dn - t = Value(table||data.y||l); u = Value(table||data.y||m) - call value table||data.y||l,u; call value table||data.y||m,t - end - leave - end - if a [lt] b then - leave - end - do x = 1 to kn - a = Value(table||key.x||l); b = Value(table||key.x||r) - if a [gt] b then do - do y = 1 to kn - t = Value(table||key.y||l); u = Value(table||key.y||r) - call value table||key.y||l,u; call value table||key.y||r,t - end - do y = 1 to dn - t = Value(table||data.y||l); u = Value(table||data.y||r) - call value table||data.y||l,u; call value table||data.y||r,t - end - leave - end - if a [lt] b then - leave - end - do x = 1 to kn - a = Value(table||key.x||m); b = Value(table||key.x||r) - if a [gt] b then do - do y = 1 to kn - t = Value(table||key.y||m); u = Value(table||key.y||r) - call value table||key.y||m,u; call value table||key.y||r,t - end - do y = 1 to dn - t = Value(table||data.y||m); u = Value(table||data.y||r) - call value table||data.y||m,u; call value table||data.y||r,t - end - leave - end - if a [lt] b then - leave - end --- Rearrange rows in partition - i = l; j = r - do x = 1 to kn - p.x = Value(table||key.x||m) - end - do until i > j - do i = i - do x = 1 to kn - a = Value(table||key.x||i) - if a [lt] p.x then - leave x - if a [eq] p.x then - if x < kn then - iterate x - leave i - end - end - do j = j by -1 - do x = 1 to kn - a = Value(table||key.x||j) - if a [gt] p.x then - leave x - if a [eq] p.x then - if x < kn then - iterate x - leave j - end - end - if i <= j then do - do x = 1 to kn - t = Value(table||key.x||i); u = Value(table||key.x||j) - call value table||key.x||i,u; call value table||key.x||j,t - end - do x = 1 to dn - t = Value(table||data.x||i); u = Value(table||data.x||j) - call value table||data.x||i,u; call value table||data.x||j,t - end - i = i+1; j = j-1 - end - end --- Next partition - if j-l < r-i then do - if i < r then do - s = s+1; sl.s = i; sr.s = r - end - r = j - end - else do - if l < j then do - s = s+1; sl.s = l; sr.s = j - end - l = i - end - end - end -end -return diff --git a/Task/Sort-an-integer-array/EasyLang/sort-an-integer-array.easy b/Task/Sort-an-integer-array/EasyLang/sort-an-integer-array.easy index 5e57891875..44ddb91b3a 100644 --- a/Task/Sort-an-integer-array/EasyLang/sort-an-integer-array.easy +++ b/Task/Sort-an-integer-array/EasyLang/sort-an-integer-array.easy @@ -1,10 +1,6 @@ -proc sort . d[] . - for i = 1 to len d[] - 1 - for j = i + 1 to len d[] - if d[j] < d[i] - swap d[j] d[i] - . - . +proc sort &d[] . + for i = 1 to len d[] - 1 : for j = i + 1 to len d[] + if d[j] < d[i] : swap d[j] d[i] . . a[] = [ 2 4 3 1 2 ] diff --git a/Task/Sort-an-outline-at-every-level/EasyLang/sort-an-outline-at-every-level.easy b/Task/Sort-an-outline-at-every-level/EasyLang/sort-an-outline-at-every-level.easy index 44d5917f87..f6ffbc327d 100644 --- a/Task/Sort-an-outline-at-every-level/EasyLang/sort-an-outline-at-every-level.easy +++ b/Task/Sort-an-outline-at-every-level/EasyLang/sort-an-outline-at-every-level.easy @@ -1,9 +1,7 @@ sortdir = 1 -proc sort . d$[][] . - for i = 1 to len d$[][] - 1 - for j = i + 1 to len d$[][] - if sortdir * strcmp d$[j][1] d$[i][1] < 0 : swap d$[j][] d$[i][] - . +proc sort &d$[][] . + for i = 1 to len d$[][] - 1 : for j = i + 1 to len d$[][] + if sortdir * strcmp d$[j][1] d$[i][1] < 0 : swap d$[j][] d$[i][] . . repeat @@ -19,7 +17,7 @@ subr init . istab = -1 # -proc nextline . . +proc nextline . if linpos = -1 : return linpos += 1 if linpos > len inp$[] @@ -73,7 +71,7 @@ func$[] outline . if linpos <> -1 : linpos -= 1 return r$[] . -proc run dir . . +proc run dir . sortdir = dir call init nextline diff --git a/Task/Sort-numbers-lexicographically/Crystal/sort-numbers-lexicographically.cr b/Task/Sort-numbers-lexicographically/Crystal/sort-numbers-lexicographically.cr new file mode 100644 index 0000000000..eddeed0680 --- /dev/null +++ b/Task/Sort-numbers-lexicographically/Crystal/sort-numbers-lexicographically.cr @@ -0,0 +1,2 @@ +n = 13 +p (1..n).to_a.sort_by! &.to_s diff --git a/Task/Sort-numbers-lexicographically/R/sort-numbers-lexicographically.r b/Task/Sort-numbers-lexicographically/R/sort-numbers-lexicographically.r new file mode 100644 index 0000000000..7212a68cf2 --- /dev/null +++ b/Task/Sort-numbers-lexicographically/R/sort-numbers-lexicographically.r @@ -0,0 +1,6 @@ +lex_sort <- function(n){ + str <- sort(as.character(1:n)) + return(as.numeric(str)) +} + +lex_sort(13) diff --git a/Task/Sort-three-variables/Crystal/sort-three-variables.cr b/Task/Sort-three-variables/Crystal/sort-three-variables.cr new file mode 100644 index 0000000000..8a1796a4ed --- /dev/null +++ b/Task/Sort-three-variables/Crystal/sort-three-variables.cr @@ -0,0 +1,14 @@ +x = "lions, tigers, and" +y = "bears, oh my!" +z = "(from the \"Wizard of OZ\")" + +x, y, z = [x, y, z].sort +puts "x = #{x}", "y = #{y}", "z = #{z}" +puts "--" + +x = 77444 +y = -12 +z = 0 + +x, y, z = [x, y, z].sort +puts "x = #{x}", "y = #{y}", "z = #{z}" diff --git a/Task/Sort-three-variables/EasyLang/sort-three-variables.easy b/Task/Sort-three-variables/EasyLang/sort-three-variables.easy index 99eeed717e..e07716d7eb 100644 --- a/Task/Sort-three-variables/EasyLang/sort-three-variables.easy +++ b/Task/Sort-three-variables/EasyLang/sort-three-variables.easy @@ -1,13 +1,7 @@ -proc sort3 . a b c . - if a > c - swap a c - . - if b > c - swap b c - . - if a > b - swap a b - . +proc sort3 &a &b &c . + if a > c : swap a c + if b > c : swap b c + if a > b : swap a b . x = 77444 y = -12 @@ -15,16 +9,10 @@ z = 0 sort3 x y z print x & " " & y & " " & z # -proc sort3str . a$ b$ c$ . - if strcmp a$ c$ > 0 - swap a$ c$ - . - if strcmp b$ c$ > 0 - swap b$ c$ - . - if strcmp a$ b$ > 0 - swap a$ b$ - . +proc sort3str &a$ &b$ &c$ . + if strcmp a$ c$ > 0 : swap a$ c$ + if strcmp b$ c$ > 0 : swap b$ c$ + if strcmp a$ b$ > 0 : swap a$ b$ . x$ = "lions, tigers, and" y$ = "bears, oh my!" diff --git a/Task/Sort-three-variables/XPL0/sort-three-variables.xpl0 b/Task/Sort-three-variables/XPL0/sort-three-variables.xpl0 new file mode 100644 index 0000000000..2511980d3a --- /dev/null +++ b/Task/Sort-three-variables/XPL0/sort-three-variables.xpl0 @@ -0,0 +1,31 @@ +include xpllib; \for StrSort and Print + +int X, Y, Z; +int L, M, H; +real RX, RY, RZ, RT; +[X:= 77444; Y:= -12; Z:= 0; +L:= X; +if L>Y then L:= Y; +if L>Z then L:= Z; +H:= X; +if HRY then [RT:= RX; RX:= RY; RY:= RT]; +if RY>RZ then [RT:= RY; RY:= RZ; RZ:= RT]; +if RX>RY then [RT:= RX; RX:= RY; RY:= RT]; +RlOut(0, RX); CrLf(0); +RlOut(0, RY); CrLf(0); +RlOut(0, RZ); CrLf(0); + +X:= "lions, tigers, and"; +Y:= "bears, oh my!"; +Z:= "(from the ^"Wizard of OZ^")"; +StrSort(@X, 3); \the address of X is used as an array containing X, Y, Z +Print("%s\n%s\n%s\n", X, Y, Z); +] diff --git a/Task/Sorting-Algorithms-Circle-Sort/Crystal/sorting-algorithms-circle-sort.cr b/Task/Sorting-Algorithms-Circle-Sort/Crystal/sorting-algorithms-circle-sort.cr new file mode 100644 index 0000000000..63667ae92c --- /dev/null +++ b/Task/Sorting-Algorithms-Circle-Sort/Crystal/sorting-algorithms-circle-sort.cr @@ -0,0 +1,35 @@ +class Array + private def circle_sort_ (lo, hi) + return 0 if lo == hi + swaps = 0 + low, high = lo, hi + mid = (hi - lo) // 2 + while lo < hi + if self[lo] > self[hi] + swap lo, hi + swaps += 1 + end + lo += 1 + hi -= 1 + end + if lo == hi && self[lo] > self[hi+1] + swap lo, hi+1 + swaps += 1 + end + swaps + circle_sort_(low, low+mid) + circle_sort_(low+mid+1, high) + end + + def circle_sort! + while circle_sort_(0, size-1) > 0 + end + self + end +end + +arr = Array.new(20) { rand 100 } +p arr +p arr.circle_sort! + +arr = %w(The quick brown fox jumps over the lazy dog.) +p arr +p arr.circle_sort! diff --git a/Task/Sorting-algorithms-Bead-sort/Rust/sorting-algorithms-bead-sort.rs b/Task/Sorting-algorithms-Bead-sort/Rust/sorting-algorithms-bead-sort.rs new file mode 100644 index 0000000000..c994ed5f11 --- /dev/null +++ b/Task/Sorting-algorithms-Bead-sort/Rust/sorting-algorithms-bead-sort.rs @@ -0,0 +1,37 @@ +fn distribute(dist: usize, list: &mut Vec) { + // If dist exceeds current length, extend the vector with zeros + if dist > list.len() { + list.resize(dist, 0); + } + + // Increment each of the first `dist` positions (simulate gravity) + for i in 0..dist { + list[i] += 1; + } +} + +fn bead_sort(arr: &[usize]) -> Vec { + let mut list = Vec::new(); + let mut list2 = Vec::new(); + + println!("#1 Beads falling down: "); + for &num in arr { + distribute(num, &mut list); + } + + println!("\nBeads on their sides: {:?}", list); + + println!("#2 Beads right side up: "); + for &count in &list { + distribute(count, &mut list2); + } + + list2 +} + +fn main() { + let myints = [734, 3, 1, 24, 324, 324, 32, 432, 42, 3, 4, 1, 1]; + let sorted = bead_sort(&myints); + + println!("Sorted list/array: {:?}", sorted); +} diff --git a/Task/Sorting-algorithms-Bogosort/EasyLang/sorting-algorithms-bogosort.easy b/Task/Sorting-algorithms-Bogosort/EasyLang/sorting-algorithms-bogosort.easy index 7f7b93d3ce..527e5afa4d 100644 --- a/Task/Sorting-algorithms-Bogosort/EasyLang/sorting-algorithms-bogosort.easy +++ b/Task/Sorting-algorithms-Bogosort/EasyLang/sorting-algorithms-bogosort.easy @@ -1,22 +1,17 @@ -proc shuffle . l[] . +proc shuffle &l[] . for i = len l[] downto 2 r = random i swap l[i] l[r] . . -proc issorted . l[] r . +func issorted &l[] . for i = 2 to len l[] - if l[i] < l[i - 1] - r = 0 - return - . + if l[i] < l[i - 1] : return 0 . - r = 1 + return 1 . -proc bogosort . l[] . - repeat - issorted l[] r - until r = 1 +proc bogosort &l[] . + while issorted l[] = 0 shuffle l[] . . diff --git a/Task/Sorting-algorithms-Bubble-sort/Crystal/sorting-algorithms-bubble-sort.cr b/Task/Sorting-algorithms-Bubble-sort/Crystal/sorting-algorithms-bubble-sort.cr new file mode 100644 index 0000000000..bf32ab26d5 --- /dev/null +++ b/Task/Sorting-algorithms-Bubble-sort/Crystal/sorting-algorithms-bubble-sort.cr @@ -0,0 +1,17 @@ +class Array + def bubble_sort! + i = size - 1 + while i > 0 + (1..i).each do |j| + swap(j, j-1) if self[j] < self[j-1] + end + i -= 1 + end + self + end +end + +arr = Array.new(20) { rand 100 } + +p arr +p arr.bubble_sort! diff --git a/Task/Sorting-algorithms-Bubble-sort/EasyLang/sorting-algorithms-bubble-sort.easy b/Task/Sorting-algorithms-Bubble-sort/EasyLang/sorting-algorithms-bubble-sort.easy index 7b5cfcb533..e91075d923 100644 --- a/Task/Sorting-algorithms-Bubble-sort/EasyLang/sorting-algorithms-bubble-sort.easy +++ b/Task/Sorting-algorithms-Bubble-sort/EasyLang/sorting-algorithms-bubble-sort.easy @@ -1,9 +1,7 @@ -proc bubble_sort . d[] . +proc bubble_sort &d[] . for i = len d[] - 1 downto 1 for j = 1 to i - if d[j] > d[j + 1] - swap d[j] d[j + 1] - . + if d[j] > d[j + 1] : swap d[j] d[j + 1] . . . diff --git a/Task/Sorting-algorithms-Cocktail-sort/EasyLang/sorting-algorithms-cocktail-sort.easy b/Task/Sorting-algorithms-Cocktail-sort/EasyLang/sorting-algorithms-cocktail-sort.easy index 0eee706f5a..1a5a20e7b4 100644 --- a/Task/Sorting-algorithms-Cocktail-sort/EasyLang/sorting-algorithms-cocktail-sort.easy +++ b/Task/Sorting-algorithms-Cocktail-sort/EasyLang/sorting-algorithms-cocktail-sort.easy @@ -1,4 +1,4 @@ -proc sort . d[] . +proc sort &d[] . a = 1 b = len d[] - 1 while a <= b diff --git a/Task/Sorting-algorithms-Comb-sort/EasyLang/sorting-algorithms-comb-sort.easy b/Task/Sorting-algorithms-Comb-sort/EasyLang/sorting-algorithms-comb-sort.easy index 78061a2157..9abab6fec5 100644 --- a/Task/Sorting-algorithms-Comb-sort/EasyLang/sorting-algorithms-comb-sort.easy +++ b/Task/Sorting-algorithms-Comb-sort/EasyLang/sorting-algorithms-comb-sort.easy @@ -1,4 +1,4 @@ -proc combsort . d[] . +proc combsort &d[] . gap = len d[] while gap > 1 or swaps = 1 gap = higher 1 (gap div 1.25) diff --git a/Task/Sorting-algorithms-Counting-sort/EasyLang/sorting-algorithms-counting-sort.easy b/Task/Sorting-algorithms-Counting-sort/EasyLang/sorting-algorithms-counting-sort.easy index 76f36523ee..6468fbe2dc 100644 --- a/Task/Sorting-algorithms-Counting-sort/EasyLang/sorting-algorithms-counting-sort.easy +++ b/Task/Sorting-algorithms-Counting-sort/EasyLang/sorting-algorithms-counting-sort.easy @@ -1,8 +1,6 @@ -proc countsort min max . d[] . +proc countsort min max &d[] . len count[] max - min + 1 - for n in d[] - count[n - min + 1] += 1 - . + for n in d[] : count[n - min + 1] += 1 z = 1 for i = min to max while count[i - min + 1] > 0 diff --git a/Task/Sorting-algorithms-Gnome-sort/EasyLang/sorting-algorithms-gnome-sort.easy b/Task/Sorting-algorithms-Gnome-sort/EasyLang/sorting-algorithms-gnome-sort.easy index 4fe89983da..ae31e78a96 100644 --- a/Task/Sorting-algorithms-Gnome-sort/EasyLang/sorting-algorithms-gnome-sort.easy +++ b/Task/Sorting-algorithms-Gnome-sort/EasyLang/sorting-algorithms-gnome-sort.easy @@ -1,4 +1,4 @@ -proc sort . d[] . +proc sort &d[] . i = 2 j = 3 while i <= len d[] diff --git a/Task/Sorting-algorithms-Heapsort/EasyLang/sorting-algorithms-heapsort.easy b/Task/Sorting-algorithms-Heapsort/EasyLang/sorting-algorithms-heapsort.easy index 8c699020bb..9fae6acb7d 100644 --- a/Task/Sorting-algorithms-Heapsort/EasyLang/sorting-algorithms-heapsort.easy +++ b/Task/Sorting-algorithms-Heapsort/EasyLang/sorting-algorithms-heapsort.easy @@ -1,4 +1,4 @@ -proc sort . d[] . +proc sort &d[] . n = len d[] # make heap for i = 2 to n @@ -17,12 +17,8 @@ proc sort . d[] . j = 1 ind = 2 while ind < i - if ind + 1 < i and d[ind + 1] > d[ind] - ind += 1 - . - if d[j] < d[ind] - swap d[j] d[ind] - . + if ind + 1 < i and d[ind + 1] > d[ind] : ind += 1 + if d[j] < d[ind] : swap d[j] d[ind] j = ind ind = 2 * j . diff --git a/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-1.rexx b/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-1.rexx index 222e7da632..0c318e4d70 100644 --- a/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-1.rexx +++ b/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-1.rexx @@ -1,22 +1,72 @@ -/*REXX pgm sorts an array (names of epichoric Greek letters) using a heapsort algorithm.*/ -parse arg x; call init /*use args or default, define @ array.*/ -call show "before sort:" /*#: the number of elements in array*/ -call heapSort #; say copies('▒', 40) /*sort; then after sort, show separator*/ -call show " after sort:" -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -init: _= 'alpha beta gamma delta digamma epsilon zeta eta theta iota kappa lambda mu nu' , - "xi omicron pi san qoppa rho sigma tau upsilon phi chi psi omega" - if x='' then x= _; #= words(x) /*#: number of words in X*/ - do j=1 for #; @.j= word(x, j); end; return /*assign letters to array*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -heapSort: procedure expose @.; arg n; do j=n%2 by -1 to 1; call shuffle j,n; end /*j*/ - do n=n by -1 to 2; _= @.1; @.1= @.n; @.n= _; call heapSuff 1,n-1 - end /*n*/; return /* [↑] swap two elements; and shuffle.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -heapSuff: procedure expose @.; parse arg i,n; $= @.i /*obtain parent.*/ - do while i+i<=n; j= i+i; k= j+1; if k<=n then if @.k>@.j then j= k - if $>=@.j then leave; @.i= @.j; i= j - end /*while*/; @.i= $; return /*define lowest.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -show: do s=1 for #; say ' element' right(s, length(#)) arg(1) @.s; end; return +/* REXX *************************************************************** +* Translated from PL/I +* 27.07.2013 Walter Pachl +**********************************************************************/ + list='---letters of the modern Greek Alphabet---|'||, + '==========================================|'||, + 'alpha|beta|gamma|delta|epsilon|zeta|eta|theta|'||, + 'iota|kappa|lambda|mu|nu|xi|omicron|pi|'||, + 'rho|sigma|tau|upsilon|phi|chi|psi|omega' + Do i=0 By 1 While list<>'' + Parse Var list a.i '|' list + End + n=i-1 + + Call showa 'before sort' + Call heapsort n + Call showa ' after sort' + Exit + + heapSort: Procedure Expose a. + Parse Arg count + Call heapify count + end=count-1 + do while end>0 + Call swap end,0 + end=end-1 + Call siftDown 0,end + End + Return + + heapify: Procedure Expose a. + Parse Arg count + start=(count-2)%2 + Do while start>=0 + Call siftDown start,count-1 + start=start-1 + End + Return + + siftDown: Procedure Expose a. + Parse Arg start,end + root=start + Do while root*2+1<= end + child=root*2+1 + sw=root + if a.swroot Then Do + Call swap root,sw + root=sw + End + else + return + End + Return + + swap: Procedure Expose a. + Parse arg x,y + temp=a.x + a.x=a.y + a.y=temp + Return + + showa: Procedure Expose a. n + Parse Arg txt + Do j=0 To n-1 + Say 'element' format(j,2) txt a.j + End + Return diff --git a/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-2.rexx b/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-2.rexx index 0c318e4d70..ac693ac5ea 100644 --- a/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-2.rexx +++ b/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-2.rexx @@ -1,72 +1,62 @@ -/* REXX *************************************************************** -* Translated from PL/I -* 27.07.2013 Walter Pachl -**********************************************************************/ - list='---letters of the modern Greek Alphabet---|'||, - '==========================================|'||, - 'alpha|beta|gamma|delta|epsilon|zeta|eta|theta|'||, - 'iota|kappa|lambda|mu|nu|xi|omicron|pi|'||, - 'rho|sigma|tau|upsilon|phi|chi|psi|omega' - Do i=0 By 1 While list<>'' - Parse Var list a.i '|' list - End - n=i-1 +include Settings - Call showa 'before sort' - Call heapsort n - Call showa ' after sort' - Exit +say 'HEAPSORT - 4 Mar 2025' +say version +say +call Generate +call Show +call Heapsort +call Show +exit - heapSort: Procedure Expose a. - Parse Arg count - Call heapify count - end=count-1 - do while end>0 - Call swap end,0 - end=end-1 - Call siftDown 0,end - End - Return +Generate: +call Random,,12345 +n = 10 +do i = 1 to n + stem.i = Random() +end +stem.0 = n +return - heapify: Procedure Expose a. - Parse Arg count - start=(count-2)%2 - Do while start>=0 - Call siftDown start,count-1 - start=start-1 - End - Return +Show: +do i = 1 to n + say right(i,2) right(stem.i,3) +end +say +return - siftDown: Procedure Expose a. - Parse Arg start,end - root=start - Do while root*2+1<= end - child=root*2+1 - sw=root - if a.swroot Then Do - Call swap root,sw - root=sw - End - else - return - End - Return +HeapSort: +procedure expose stem. +n = stem.0 +if n < 2 then + return +n = stem.0; l = (n%2)+1; s = n +do while 1 + if l > 1 then do + l = l-1; r = stem.l + end + else do + r = stem.s; stem.s = stem.1; s = s-1 + if s = 1 then do + stem.1 = r + leave + end + end + i = l; j = l*2 + do while j <= s + if j < s then do + k = j+1 + if stem.j < stem.k then + j = j+1 + end + if r < stem.j then do + stem.i = stem.j; i = j; j = j+i + end + else + j = s+1 + end + stem.i = r +end +return - swap: Procedure Expose a. - Parse arg x,y - temp=a.x - a.x=a.y - a.y=temp - Return - - showa: Procedure Expose a. n - Parse Arg txt - Do j=0 To n-1 - Say 'element' format(j,2) txt a.j - End - Return +include Abend diff --git a/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-3.rexx b/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-3.rexx deleted file mode 100644 index 38b7e57afe..0000000000 --- a/Task/Sorting-algorithms-Heapsort/REXX/sorting-algorithms-heapsort-3.rexx +++ /dev/null @@ -1,56 +0,0 @@ -Main: -call Generate -call Show -call Heapsort -call Show -exit - -Generate: -call Random,,12345 -n = 10 -do i = 1 to n - stem.i = Random() -end -stem.0 = n -return - -Show: -do i = 1 to n - say right(i,2) right(stem.i,3) -end -say -return - -HeapSort: -procedure expose stem. -n = stem.0 -if n < 2 then - return -n = stem.0; l = (n%2)+1; s = n -do while 1 - if l > 1 then do - l = l-1; r = stem.l - end - else do - r = stem.s; stem.s = stem.1; s = s-1 - if s = 1 then do - stem.1 = r - leave - end - end - i = l; j = l*2 - do while j <= s - if j < s then do - k = j+1 - if stem.j < stem.k then - j = j+1 - end - if r < stem.j then do - stem.i = stem.j; i = j; j = j+i - end - else - j = s+1 - end - stem.i = r -end -return diff --git a/Task/Sorting-algorithms-Insertion-sort/EasyLang/sorting-algorithms-insertion-sort.easy b/Task/Sorting-algorithms-Insertion-sort/EasyLang/sorting-algorithms-insertion-sort.easy index ae0c415130..cd85b00b0b 100644 --- a/Task/Sorting-algorithms-Insertion-sort/EasyLang/sorting-algorithms-insertion-sort.easy +++ b/Task/Sorting-algorithms-Insertion-sort/EasyLang/sorting-algorithms-insertion-sort.easy @@ -1,4 +1,4 @@ -proc sort . d[] . +proc sort &d[] . for i = 2 to len d[] h = d[i] j = i - 1 diff --git a/Task/Sorting-algorithms-Merge-sort/EasyLang/sorting-algorithms-merge-sort.easy b/Task/Sorting-algorithms-Merge-sort/EasyLang/sorting-algorithms-merge-sort.easy index 784d954f34..eb9af0bcf9 100644 --- a/Task/Sorting-algorithms-Merge-sort/EasyLang/sorting-algorithms-merge-sort.easy +++ b/Task/Sorting-algorithms-Merge-sort/EasyLang/sorting-algorithms-merge-sort.easy @@ -1,4 +1,4 @@ -proc sort . d[] . +proc sort &d[] . len tmp[] len d[] sz = 1 while sz < len d[] @@ -7,13 +7,9 @@ proc sort . d[] . while left < len d[] # merge mid = left + sz - 1 - if mid > len d[] - mid = len d[] - . + if mid > len d[] : mid = len d[] right = mid + sz - if right > len d[] - right = len d[] - . + if right > len d[] : right = len d[] l = left r = mid + 1 for i = left to right diff --git a/Task/Sorting-algorithms-Merge-sort/REXX/sorting-algorithms-merge-sort-3.rexx b/Task/Sorting-algorithms-Merge-sort/REXX/sorting-algorithms-merge-sort-3.rexx index 954c469b17..a68efddb45 100644 --- a/Task/Sorting-algorithms-Merge-sort/REXX/sorting-algorithms-merge-sort-3.rexx +++ b/Task/Sorting-algorithms-Merge-sort/REXX/sorting-algorithms-merge-sort-3.rexx @@ -1,4 +1,8 @@ -Main: +include Settings + +say 'MERGE SORT - 4 Mar 2025' +say version +say call Generate call Show call Mergesort 1,n @@ -65,3 +69,5 @@ do i = b to e stem.i = work.i end return + +include Abend diff --git a/Task/Sorting-algorithms-Merge-sort/ZED/sorting-algorithms-merge-sort.zed b/Task/Sorting-algorithms-Merge-sort/ZED/sorting-algorithms-merge-sort.zed index a4dd852c14..23efdd62c7 100644 --- a/Task/Sorting-algorithms-Merge-sort/ZED/sorting-algorithms-merge-sort.zed +++ b/Task/Sorting-algorithms-Merge-sort/ZED/sorting-algorithms-merge-sort.zed @@ -3,35 +3,10 @@ #true (003) "append" list1 list2 -(car) pair +(cons) item list ========= #true -(002) "car" pair - -(cadr) pair -========= -#true -(002) "cadr" pair - -(cdr) pair -========= -#true -(002) "cdr" pair - -(cddr) pair -========= -#true -(002) "cddr" pair - -(cons) one two -========= -#true -(003) "cons" one two - -(list1a) item -========= -#true -(002) "list" item +(003) "cons" item list (map) function list ========= @@ -39,35 +14,35 @@ (003) "map" function list (merge) comparator list1 list2 -CONTINUE WITH COLLECT ARGUMENT +BRING IN COLLECT ARGUMENT #true (merge01) comparator list1 list2 nil (merge01) comparator list1 list2 collect -LIST2 EXHAUSTED -> MERGED +LIST2 EXHAUSTED (null?) list2 (append) (reverse) collect list1 (merge01) comparator list1 list2 collect -LIST1 EXHAUSTED -> MERGED +LIST1 EXHAUSTED (null?) list1 (append) (reverse) collect list2 (merge01) comparator list1 list2 collect -TAKE FROM LIST2 (HANDLES ONE CASE) -(003) comparator (car) list2 (car) list1 +COMPARATOR CHOOSES LIST2 +(003) comparator (1) list2 (1) list1 (merge01) comparator list1 - (cdr) list2 - (cons) (car) list2 collect + (!) list2 + (cons) (1) list2 collect (merge01) comparator list1 list2 collect -TAKE FROM LIST1 (HANDLES TWO CASES) +NOW TAKE FROM LIST1 (PRIORITY STABILITY) #true (merge01) comparator - (cdr) list1 + (!) list1 list2 - (cons) (car) list1 collect + (cons) (1) list1 collect (null?) value ========= @@ -80,28 +55,47 @@ TAKE FROM LIST1 (HANDLES TWO CASES) (002) "reverse" list (sort) comparator jumble -PREPARE JUMBLE AND PERFORM MERGE PASSES -> EXTRACT +PREPARE JUMBLE AND PERFORM MERGE PASSES #true -(car) (sort02) comparator (sort01) jumble +(sort03) comparator (sort02) comparator (sort01) jumble (sort01) jumble -PREPARED JUMBLE +PREPARE JUMBLE #true -(map) list1a jumble +(map) "list" jumble (sort02) comparator jumble -WHEN ZERO LISTS THEN NIL +EMPTY JUMBLE (null?) jumble nil (sort02) comparator jumble -WHEN ONE LIST THEN ALREADY SORTED -(null?) (cdr) jumble +ONE LIST JUMBLE +(null?) (!) jumble jumble (sort02) comparator jumble -REPEATEDLY MERGE ALONG LENGTH +PERFORM MERGE PASS #true -(sort02) comparator - (cons) (merge) comparator (car) jumble (cadr) jumble - (sort02) comparator (cddr) jumble +(cons) (merge) comparator (1) jumble (1) (!) jumble + (sort02) comparator (!) (!) jumble + +(sort03) comparator jumble +EMPTY JUMBLE +(null?) jumble +nil + +(sort03) comparator jumble +ONE LIST JUMBLE +(null?) (!) jumble +(1) jumble + +(sort03) comparator jumble +PERFORM MERGE PASS AND RESTART +#true +(sort03) comparator (sort02) comparator jumble + +(main) +ENTRY POINT +#true +(002) "display" (sort) ">" (010) "list" 4 3 5 6 8 7 1 2 9 diff --git a/Task/Sorting-algorithms-Pancake-sort/EasyLang/sorting-algorithms-pancake-sort.easy b/Task/Sorting-algorithms-Pancake-sort/EasyLang/sorting-algorithms-pancake-sort.easy index 24657b1535..e346d94ad2 100644 --- a/Task/Sorting-algorithms-Pancake-sort/EasyLang/sorting-algorithms-pancake-sort.easy +++ b/Task/Sorting-algorithms-Pancake-sort/EasyLang/sorting-algorithms-pancake-sort.easy @@ -1,5 +1,5 @@ global a[] . -proc flip n . . +proc flip n . for i = 1 to n div 2 swap a[i] a[n - i + 1] . @@ -17,7 +17,7 @@ func[] minmax n . . return [ pmin pmax ] . -proc pcsort n dir . . +proc pcsort n dir . if n = 1 return . diff --git a/Task/Sorting-algorithms-Patience-sort/EasyLang/sorting-algorithms-patience-sort.easy b/Task/Sorting-algorithms-Patience-sort/EasyLang/sorting-algorithms-patience-sort.easy new file mode 100644 index 0000000000..adc571cbce --- /dev/null +++ b/Task/Sorting-algorithms-Patience-sort/EasyLang/sorting-algorithms-patience-sort.easy @@ -0,0 +1,29 @@ +proc patience_sort &nums[] . + for num in nums[] + for p to len piles[][] + if num >= piles[p][len piles[p][]] + piles[p][] &= num + break 1 + . + . + if p > len piles[][] : piles[][] &= [ num ] + . + for i to len nums[] + dest = 1 + for p = 2 to len piles[][] + if piles[p][1] < piles[dest][1] : dest = p + . + nums[i] = piles[dest][1] + for j = 2 to len piles[dest][] + piles[dest][j - 1] = piles[dest][j] + . + len piles[dest][] -1 + if len piles[dest][] = 0 + swap piles[dest][] piles[$][] + len piles[][] -1 + . + . +. +nums[] = [ 10 6 -30 9 18 1 -20 ] +patience_sort nums[] +print nums[] diff --git a/Task/Sorting-algorithms-Patience-sort/Rust/sorting-algorithms-patience-sort.rs b/Task/Sorting-algorithms-Patience-sort/Rust/sorting-algorithms-patience-sort.rs new file mode 100644 index 0000000000..c4f1dbc87a --- /dev/null +++ b/Task/Sorting-algorithms-Patience-sort/Rust/sorting-algorithms-patience-sort.rs @@ -0,0 +1,95 @@ +use std::cmp::Ordering; +use std::collections::BinaryHeap; + +// We define a custom Pile struct instead of using Stack +#[derive(Clone, Eq, PartialEq)] +struct Pile { + values: Vec, +} + +impl Pile { + fn new(value: T) -> Self { + let mut values = Vec::new(); + values.push(value); + Pile { values } + } + + fn push(&mut self, value: T) { + self.values.push(value); + } + + fn pop(&mut self) -> Option { + self.values.pop() + } + + fn top(&self) -> Option<&T> { + self.values.last() + } + + fn is_empty(&self) -> bool { + self.values.is_empty() + } +} + +// For binary heap ordering (min-heap) +impl Ord for Pile { + fn cmp(&self, other: &Self) -> Ordering { + // Reverse the ordering for min-heap + other.top().cmp(&self.top()) + } +} + +impl PartialOrd for Pile { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +fn patience_sort(slice: &mut [T]) { + let mut piles: Vec> = Vec::new(); + + // Sort into piles + for item in slice.iter().cloned() { + // Find the pile to insert into + let idx = match piles.binary_search_by(|pile| { + if let Some(top) = pile.top() { + top.cmp(&item) + } else { + Ordering::Greater // Should not happen + } + }) { + Ok(idx) => idx, // Found a pile with the same top value + Err(idx) => idx, // Position where we should insert new pile + }; + + if idx < piles.len() { + piles[idx].push(item); + } else { + piles.push(Pile::new(item)); + } + } + + // Convert to BinaryHeap for efficient merging + let mut heap = BinaryHeap::from(piles); + + // Merge piles + for item_slot in slice.iter_mut() { + if let Some(mut smallest_pile) = heap.pop() { + if let Some(top) = smallest_pile.pop() { + *item_slot = top; + + if !smallest_pile.is_empty() { + heap.push(smallest_pile); + } + } + } + } + + assert!(heap.is_empty()); +} + +fn main() { + let mut a = [4, 65, 2, -31, 0, 99, 83, 782, 1]; + patience_sort(&mut a); + println!("{:?}", a); +} diff --git a/Task/Sorting-algorithms-Patience-sort/Zig/sorting-algorithms-patience-sort.zig b/Task/Sorting-algorithms-Patience-sort/Zig/sorting-algorithms-patience-sort.zig new file mode 100644 index 0000000000..e53cf138df --- /dev/null +++ b/Task/Sorting-algorithms-Patience-sort/Zig/sorting-algorithms-patience-sort.zig @@ -0,0 +1,138 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const ArrayList = std.ArrayList; +const PriorityQueue = std.PriorityQueue; + +// Pile structure to represent a stack of items +fn Pile(comptime T: type) type { + return struct { + values: ArrayList(T), + + const Self = @This(); + + fn init(allocator: Allocator) Self { + return Self{ + .values = ArrayList(T).init(allocator), + }; + } + + fn deinit(self: *Self) void { + self.values.deinit(); + } + + fn push(self: *Self, value: T) !void { + try self.values.append(value); + } + + fn pop(self: *Self) ?T { + if (self.values.items.len == 0) return null; + return self.values.pop(); + } + + fn top(self: *const Self) ?T { + if (self.values.items.len == 0) return null; + return self.values.items[self.values.items.len - 1]; + } + + fn isEmpty(self: *const Self) bool { + return self.values.items.len == 0; + } + }; +} + +// Compare function for priority queue (min-heap) +fn pileGreaterThan(comptime T: type) type { + return struct { + pub fn compare(context: void, a: *const Pile(T), b: *const Pile(T)) std.math.Order { + _ = context; + const a_top = a.top() orelse return .lt; + const b_top = b.top() orelse return .gt; + return if (a_top > b_top) .lt else if (a_top < b_top) .gt else .eq; + } + }; +} + +// Patience sort implementation +fn patienceSort(comptime T: type, allocator: Allocator, slice: []T) !void { + const PileT = Pile(T); + var piles = ArrayList(*PileT).init(allocator); + defer { + // Clean up all piles regardless of how we exit the function + for (piles.items) |pile| { + pile.deinit(); + allocator.destroy(pile); + } + piles.deinit(); + } + + // Sort into piles + for (slice) |item| { + // Try to find an existing pile to add to + var added = false; + for (piles.items) |pile| { + if (pile.top()) |top| { + if (top > item) { + try pile.push(item); + added = true; + break; + } + } + } + + // If no suitable pile found, create a new one + if (!added) { + var new_pile = try allocator.create(PileT); + errdefer allocator.destroy(new_pile); + + new_pile.* = PileT.init(allocator); + errdefer new_pile.deinit(); + + try new_pile.push(item); + try piles.append(new_pile); + } + } + + // Create a priority queue for efficient merging + var queue = PriorityQueue(*PileT, void, pileGreaterThan(T).compare).init(allocator, {}); + defer queue.deinit(); + + // Add all piles to the priority queue + for (piles.items) |pile| { + try queue.add(pile); + } + + // Merge piles back into the original slice + var i: usize = 0; + while (queue.count() > 0) { + const smallest_pile = queue.remove(); + if (smallest_pile.pop()) |value| { + slice[i] = value; + i += 1; + + if (!smallest_pile.isEmpty()) { + try queue.add(smallest_pile); + } + } + } + + std.debug.assert(i == slice.len); +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + var a = [_]i32{ 4, 65, 2, -31, 0, 99, 83, 782, 1 }; + try patienceSort(i32, allocator, &a); + + const stdout = std.io.getStdOut().writer(); + try stdout.print("Sorted array: ", .{}); + for (a, 0..) |value, i| { + try stdout.print("{}", .{value}); + if (i < a.len - 1) { + try stdout.print(", ", .{}); + } + } + try stdout.print("\n", .{}); +} diff --git a/Task/Sorting-algorithms-Permutation-sort/EasyLang/sorting-algorithms-permutation-sort.easy b/Task/Sorting-algorithms-Permutation-sort/EasyLang/sorting-algorithms-permutation-sort.easy index fa9ff44ab4..eedd40067d 100644 --- a/Task/Sorting-algorithms-Permutation-sort/EasyLang/sorting-algorithms-permutation-sort.easy +++ b/Task/Sorting-algorithms-Permutation-sort/EasyLang/sorting-algorithms-permutation-sort.easy @@ -1,18 +1,11 @@ global perm[] . -proc nextperm . a[] . +proc nextperm &a[] &k . n = len perm[] k = n - 1 - while k >= 1 and perm[k + 1] <= perm[k] - k -= 1 - . - if k = 0 - a[] = [ ] - return - . + while k >= 1 and perm[k + 1] <= perm[k] : k -= 1 + if k = 0 : return l = n - while perm[l] <= perm[k] - l -= 1 - . + while perm[l] <= perm[k] : l -= 1 swap perm[l] perm[k] swap a[l] a[k] k += 1 @@ -23,22 +16,18 @@ proc nextperm . a[] . n -= 1 . . -proc perminit . a[] . - for i to len a[] - perm[] &= i - . +proc perminit &a[] . + for i to len a[] : perm[] &= i . -proc permsort . a[] . +proc permsort &a[] . perminit a[] repeat for i = 2 to len a[] - if a[i - 1] > a[i] - break 1 - . + if a[i - 1] > a[i] : break 1 . until i > len a[] - nextperm a[] - if len a[] = 0 + nextperm a[] more + if more = 0 print "error" break 1 . diff --git a/Task/Sorting-algorithms-Quicksort/EasyLang/sorting-algorithms-quicksort.easy b/Task/Sorting-algorithms-Quicksort/EasyLang/sorting-algorithms-quicksort.easy index 7ddf5cf8ad..6dec150579 100644 --- a/Task/Sorting-algorithms-Quicksort/EasyLang/sorting-algorithms-quicksort.easy +++ b/Task/Sorting-algorithms-Quicksort/EasyLang/sorting-algorithms-quicksort.easy @@ -1,19 +1,19 @@ -proc qsort left right . d[] . - if left >= right - return - . - mid = left - for i = left + 1 to right - if d[i] < d[left] - mid += 1 - swap d[i] d[mid] +proc qsort left right &d[] . + if left < right + piv = d[left] + mid = left + for i = left + 1 to right + if d[i] < piv + mid += 1 + swap d[i] d[mid] + . . + swap d[left] d[mid] + qsort left mid - 1 d[] + qsort mid + 1 right d[] . - swap d[left] d[mid] - qsort left mid - 1 d[] - qsort mid + 1 right d[] . -proc sort . d[] . +proc sort &d[] . qsort 1 len d[] d[] . d[] = [ 29 4 72 44 55 26 27 77 92 5 ] diff --git a/Task/Sorting-algorithms-Quicksort/K/sorting-algorithms-quicksort-8.k b/Task/Sorting-algorithms-Quicksort/K/sorting-algorithms-quicksort-8.k index 38d72b5d2a..d4a77e73e9 100644 --- a/Task/Sorting-algorithms-Quicksort/K/sorting-algorithms-quicksort-8.k +++ b/Task/Sorting-algorithms-Quicksort/K/sorting-algorithms-quicksort-8.k @@ -1 +1,2 @@ t@@.k then return 0; end; return 1 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -qSort: procedure expose @.; a.1=1; parse arg b.1; $= 1 /*access @.; get @. size; pivot.*/ - if inOrder(b.1) then return /*Array already in order? Return*/ - do while $\==0; L= a.$; t= b.$; $= $ - 1; if t<2 then iterate - H= L + t - 1; ?= L + t % 2 - if @.H<@.L then if @.?<@.H then do; p= @.H; @.H= @.L; end - else if @.?>@.L then p= @.L - else do; p= @.?; @.?= @.L; end - else if @.?<@.L then p=@.L - else if @.?>@.H then do; p= @.H; @.H= @.L; end - else do; p= @.?; @.?= @.L; end - j= L+1; k= h - do forever - do j=j while j<=k & @.j<=p; end /*a teeny─tiny loop.*/ - do k=k by -1 while j< k & @.k>=p; end /*another " " */ - if j>=k then leave /*segment finished? */ - _= @.j; @.j= @.k; @.k= _ /*swap J&K elements.*/ - end /*forever*/ - $= $ + 1 - k= j - 1; @.L= @.k; @.k= p - if j<=? then do; a.$= j; b.$= H-j+1; $= $+1; a.$= L; b.$= k-L; end - else do; a.$= L; b.$= k-L; $= $+1; a.$= j; b.$= H-j+1; end - end /*while $¬==0*/ - return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -show@: w= length(#); do j=1 for #; say 'element' right(j,w) arg(1)":" @.j; end - say copies('▒', maxL + w + 22) /*display a separator (between outputs)*/ - return -/*──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/ -gen@: @.=; maxL=0 /*assign a default value for the array.*/ - @.1 = " Rivers that form part of a (USA) state's border " /*this value is adjusted later to include a prefix & suffix.*/ - @.2 = '=' /*this value is expanded later. */ - @.3 = "Perdido River Alabama, Florida" - @.4 = "Chattahoochee River Alabama, Georgia" - @.5 = "Tennessee River Alabama, Kentucky, Mississippi, Tennessee" - @.6 = "Colorado River Arizona, California, Nevada, Baja California (Mexico)" - @.7 = "Mississippi River Arkansas, Illinois, Iowa, Kentucky, Minnesota, Mississippi, Missouri, Tennessee, Louisiana, Wisconsin" - @.8 = "St. Francis River Arkansas, Missouri" - @.9 = "Poteau River Arkansas, Oklahoma" - @.10 = "Arkansas River Arkansas, Oklahoma" - @.11 = "Red River (Mississippi watershed) Arkansas, Oklahoma, Texas" - @.12 = "Byram River Connecticut, New York" - @.13 = "Pawcatuck River Connecticut, Rhode Island and Providence Plantations" - @.14 = "Delaware River Delaware, New Jersey, New York, Pennsylvania" - @.15 = "Potomac River District of Columbia, Maryland, Virginia, West Virginia" - @.16 = "St. Marys River Florida, Georgia" - @.17 = "Chattooga River Georgia, South Carolina" - @.18 = "Tugaloo River Georgia, South Carolina" - @.19 = "Savannah River Georgia, South Carolina" - @.20 = "Snake River Idaho, Oregon, Washington" - @.21 = "Wabash River Illinois, Indiana" - @.22 = "Ohio River Illinois, Indiana, Kentucky, Ohio, West Virginia" - @.23 = "Great Miami River (mouth only) Indiana, Ohio" - @.24 = "Des Moines River Iowa, Missouri" - @.25 = "Big Sioux River Iowa, South Dakota" - @.26 = "Missouri River Kansas, Iowa, Missouri, Nebraska, South Dakota" - @.27 = "Tug Fork River Kentucky, Virginia, West Virginia" - @.28 = "Big Sandy River Kentucky, West Virginia" - @.29 = "Pearl River Louisiana, Mississippi" - @.30 = "Sabine River Louisiana, Texas" - @.31 = "Monument Creek Maine, New Brunswick (Canada)" - @.32 = "St. Croix River Maine, New Brunswick (Canada)" - @.33 = "Piscataqua River Maine, New Hampshire" - @.34 = "St. Francis River Maine, Quebec (Canada)" - @.35 = "St. John River Maine, Quebec (Canada)" - @.36 = "Pocomoke River Maryland, Virginia" - @.37 = "Palmer River Massachusetts, Rhode Island and Providence Plantations" - @.38 = "Runnins River Massachusetts, Rhode Island and Providence Plantations" - @.39 = "Montreal River Michigan (upper peninsula), Wisconsin" - @.40 = "Detroit River Michigan, Ontario (Canada)" - @.41 = "St. Clair River Michigan, Ontario (Canada)" - @.42 = "St. Marys River Michigan, Ontario (Canada)" - @.43 = "Brule River Michigan, Wisconsin" - @.44 = "Menominee River Michigan, Wisconsin" - @.45 = "Red River of the North Minnesota, North Dakota" - @.46 = "Bois de Sioux River Minnesota, North Dakota, South Dakota" - @.47 = "Pigeon River Minnesota, Ontario (Canada)" - @.48 = "Rainy River Minnesota, Ontario (Canada)" - @.49 = "St. Croix River Minnesota, Wisconsin" - @.50 = "St. Louis River Minnesota, Wisconsin" - @.51 = "Halls Stream New Hampshire, Canada" - @.52 = "Salmon Falls River New Hampshire, Maine" - @.53 = "Connecticut River New Hampshire, Vermont" - @.54 = "Arthur Kill New Jersey, New York (tidal strait)" - @.55 = "Kill Van Kull New Jersey, New York (tidal strait)" - @.56 = "Hudson River (lower part only) New Jersey, New York" - @.57 = "Rio Grande New Mexico, Texas, Tamaulipas (Mexico), Nuevo Leon (Mexico), Coahuila de Zaragoza (Mexico), Chihuahua (Mexico)" - @.58 = "Niagara River New York, Ontario (Canada)" - @.59 = "St. Lawrence River New York, Ontario (Canada)" - @.60 = "Poultney River New York, Vermont" - @.61 = "Catawba River North Carolina, South Carolina" - @.62 = "Blackwater River North Carolina, Virginia" - @.63 = "Columbia River Oregon, Washington" - do #=1 until @.#=='' /*find how many entries in array, and */ - maxL=max(maxL, length(@.#)) /* also find the maximum width entry.*/ - end /*#*/; #= #-1 /*adjust the highest element number. */ - @.1= center(@.1, maxL, '-') /* " " header information. */ - @.2= copies(@.2, maxL) /* " " " separator. */ - return +/*REXX*/ + a = '4 65 2 -31 0 99 83 782 1' + do i = 1 to words(a) + queue word(a, i) + end + call quickSort + parse pull item + do queued() + call charout ,item', ' + parse pull item + end + say item + exit + +quickSort: procedure +/* In classic Rexx, arguments are passed by value, not by reference so stems + cannot be passed as arguments nor used as return values. Putting their + contents on the external data queue is a way to bypass this issue. */ + + /* construct the input stem */ + arr.0 = queued() + do i = 1 to arr.0 + parse pull arr.i + end + less.0 = 0 + pivotList.0 = 0 + more.0 = 0 + if arr.0 <= 1 then do + if arr.0 = 1 then + queue arr.1 + return + end + else do + pivot = arr.1 + do i = 1 to arr.0 + item = arr.i + select + when item < pivot then do + j = less.0 + 1 + less.j = item + less.0 = j + end + when item > pivot then do + j = more.0 + 1 + more.j = item + more.0 = j + end + otherwise + j = pivotList.0 + 1 + pivotList.j = item + pivotList.0 = j + end + end + end + /* recursive call to sort the less. stem */ + do i = 1 to less.0 + queue less.i + end + if queued() > 0 then do + call quickSort + less.0 = queued() + do i = 1 to less.0 + parse pull less.i + end + end + /* recursive call to sort the more. stem */ + do i = 1 to more.0 + queue more.i + end + if queued() > 0 then do + call quickSort + more.0 = queued() + do i = 1 to more.0 + parse pull more.i + end + end + /* put the contents of all 3 stems on the queue in order */ + do i = 1 to less.0 + queue less.i + end + do i = 1 to pivotList.0 + queue pivotList.i + end + do i = 1 to more.0 + queue more.i + end + return diff --git a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-2.rexx b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-2.rexx index 609b0364fb..5b58ec3e8d 100644 --- a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-2.rexx +++ b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-2.rexx @@ -1,87 +1,24 @@ -/*REXX*/ - a = '4 65 2 -31 0 99 83 782 1' - do i = 1 to words(a) - queue word(a, i) - end - call quickSort - parse pull item - do queued() - call charout ,item', ' - parse pull item - end - say item - exit - -quickSort: procedure -/* In classic Rexx, arguments are passed by value, not by reference so stems - cannot be passed as arguments nor used as return values. Putting their - contents on the external data queue is a way to bypass this issue. */ - - /* construct the input stem */ - arr.0 = queued() - do i = 1 to arr.0 - parse pull arr.i - end - less.0 = 0 - pivotList.0 = 0 - more.0 = 0 - if arr.0 <= 1 then do - if arr.0 = 1 then - queue arr.1 - return - end - else do - pivot = arr.1 - do i = 1 to arr.0 - item = arr.i - select - when item < pivot then do - j = less.0 + 1 - less.j = item - less.0 = j - end - when item > pivot then do - j = more.0 + 1 - more.j = item - more.0 = j - end - otherwise - j = pivotList.0 + 1 - pivotList.j = item - pivotList.0 = j - end - end - end - /* recursive call to sort the less. stem */ - do i = 1 to less.0 - queue less.i - end - if queued() > 0 then do - call quickSort - less.0 = queued() - do i = 1 to less.0 - parse pull less.i - end - end - /* recursive call to sort the more. stem */ - do i = 1 to more.0 - queue more.i - end - if queued() > 0 then do - call quickSort - more.0 = queued() - do i = 1 to more.0 - parse pull more.i - end - end - /* put the contents of all 3 stems on the queue in order */ - do i = 1 to less.0 - queue less.i - end - do i = 1 to pivotList.0 - queue pivotList.i - end - do i = 1 to more.0 - queue more.i - end - return +Elegant: +procedure expose stem. +push 1 stem.0 +do while queued() > 0 + pull l r + if l < r then do + m = (l+r)%2; p = stem.m; i = l-1; j = r+1 + do forever + do until stem.j <= p + j = j-1 + end + do until stem.i >= p + i = i+1 + end + if i < j then do + t = stem.i; stem.i = stem.j; stem.j = t + end + else + leave + end + push l j; push j+1 r + end +end +return diff --git a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-3.rexx b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-3.rexx index 5b58ec3e8d..4b7e097a83 100644 --- a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-3.rexx +++ b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-3.rexx @@ -1,24 +1,20 @@ -Elegant: +Recursive: procedure expose stem. -push 1 stem.0 -do while queued() > 0 - pull l r - if l < r then do - m = (l+r)%2; p = stem.m; i = l-1; j = r+1 - do forever - do until stem.j <= p - j = j-1 - end - do until stem.i >= p - i = i+1 - end - if i < j then do - t = stem.i; stem.i = stem.j; stem.j = t - end - else - leave - end - push l j; push j+1 r +arg l r +m = (l+r)%2; p = stem.m +i = l; j = r +do while i <= j + do i = i while stem.i < p + end + do j = j by -1 while stem.j > p + end + if i <= j then do + t = stem.i; stem.i = stem.j; stem.j = t + i = i+1; j = j-1 end end +if l < j then + call Recursive l j +if i < r then + call Recursive i r return diff --git a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-4.rexx b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-4.rexx index 4b7e097a83..a35b358c85 100644 --- a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-4.rexx +++ b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-4.rexx @@ -1,20 +1,56 @@ -Recursive: +Optimized: procedure expose stem. -arg l r -m = (l+r)%2; p = stem.m -i = l; j = r -do while i <= j - do i = i while stem.i < p - end - do j = j by -1 while stem.j > p - end - if i <= j then do - t = stem.i; stem.i = stem.j; stem.j = t - i = i+1; j = j-1 +n = stem.0; s = 1; sl.1 = 1; sr.1 = n +do until s = 0 + l = sl.s; r = sr.s; s = s-1 + do until l >= r + if r-l < 11 then do + do i = l+1 to r + a = stem.i + do j=i-1 by -1 to l while stem.j > a + k = j+1; stem.k = stem.j + end + k = j+1; stem.k = a + end + if s = 0 then + leave + l = sl.s; r = sr.s; s = s-1 + end + else do + m = (l+r)%2 + if stem.l > stem.m then do + t = stem.l; stem.l = stem.m; stem.m = t + end + if stem.l > stem.r then do + t = stem.l; stem.l = stem.r; stem.r = t + end + if stem.m > stem.r then do + t = stem.m; stem.m = stem.r; stem.r = t + end + i = l; j = r; p = stem.m + do until i > j + do i = i while stem.i < p + end + do j = j by -1 while stem.j > p + end + if i <= j then do + t = stem.i; stem.i = stem.j; stem.j = t + i = i+1; j = j-1 + end + end + if j-l < r-i then do + if i < r then do + s = s+1; sl.s = i; sr.s = r + end + r = j + end + else do + if l < j then do + s = s+1; sl.s = l; sr.s = j + end + l = i + end + end end end -if l < j then - call Recursive l j -if i < r then - call Recursive i r return diff --git a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-5.rexx b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-5.rexx index a35b358c85..ce394a34f1 100644 --- a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-5.rexx +++ b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-5.rexx @@ -1,10 +1,204 @@ +include Settings + +say 'QUICKSORT - 4 Mar 2025' +say version +say +numeric digits 9 +arg n v +if n = '' then n = 10 +if v = '' then v = 1 +show = (n > 0); n = Abs(n) +say 'Timing Version' v 'for' n 'random numbers' +call Generate +if show then call ShowSave +if v = 0 | v = 1 then do + call Time 'r'; call Save2Stack; say 'Save2Stack' format(time('e'),3,3) 'seconds' + call Time 'r'; call Quicksort; say 'Quicksort ' format(time('e'),3,3) 'seconds' + call Time 'r'; call Stack2Stem; say 'Stack2Stem' format(time('e'),3,3) 'seconds' + if show then call ShowStem +end +if v = 0 | v = 2 then do + call Save2Stem + call Time 'r'; call Elegant; say 'Elegant' format(time('e'),3,3) 'seconds' + if show then call ShowStem +end +if v = 0 | v = 3 then do + call Save2Stem + call Time 'r'; call Recursive 1 n; say 'Recursive' format(time('e'),3,3) 'seconds' + if show then call ShowStem +end +if v = 0 | v = 4 then do + call Save2Stem + call Time 'r'; call Optimized; say 'Optimized' format(time('e'),3,3) 'seconds' + if show then call ShowStem +end +say +exit + +Generate: +do x = 1 to n + save.x = 10000*Random(0,9999)+Random(0,9999) +end +save.0 = n +return + +ShowSave: +do x = 1 to 5 + say x save.x +end +do x = n-4 to n + say x save.x +end +say +return + +ShowStem: +do x = 1 to 5 + say x stem.x +end +do x = n-4 to n + say x stem.x +end +say +return + +Save2Stem: +do x = 0 to n + stem.x = save.x +end +return + +Save2Stack: +do x = 1 to n + queue save.x +end +return + +Quicksort: procedure +arr.0 = queued() +do i = 1 to arr.0 + parse pull arr.i +end +less.0 = 0 +pivotList.0 = 0 +more.0 = 0 +if arr.0 <= 1 then do + if arr.0 = 1 then + queue arr.1 + return +end +else do + pivot = arr.1 + do i = 1 to arr.0 + item = arr.i + select + when item < pivot then do + j = less.0 + 1 + less.j = item + less.0 = j + end + when item > pivot then do + j = more.0 + 1 + more.j = item + more.0 = j + end + otherwise + j = pivotList.0 + 1 + pivotList.j = item + pivotList.0 = j + end + end +end +do i = 1 to less.0 + queue less.i +end +if queued() > 0 then do + call quickSort + less.0 = queued() + do i = 1 to less.0 + parse pull less.i + end +end +do i = 1 to more.0 + queue more.i +end +if queued() > 0 then do + call quickSort + more.0 = queued() + do i = 1 to more.0 + parse pull more.i + end +end +do i = 1 to less.0 + queue less.i +end +do i = 1 to pivotList.0 + queue pivotList.i +end +do i = 1 to more.0 + queue more.i +end +return + +Stack2Stem: +do x = 1 to n + parse pull stem.x +end +return + +Elegant: +procedure expose stem. +push 1 stem.0 +do while queued() > 0 + pull l r + if l < r then do + m = (l+r)%2; p = stem.m; i = l-1; j = r+1 + do forever + do until stem.j <= p + j = j-1 + end + do until stem.i >= p + i = i+1 + end + if i < j then do + t = stem.i; stem.i = stem.j; stem.j = t + end + else + leave + end + push l j; push j+1 r + end +end +return + +Recursive: +procedure expose stem. +arg l r +m = (l+r)%2; p = stem.m +i = l; j = r +do while i <= j + do i = i while stem.i < p + end + do j = j by -1 while stem.j > p + end + if i <= j then do + t = stem.i; stem.i = stem.j; stem.j = t + i = i+1; j = j-1 + end +end +if l < j then + call Recursive l j +if i < r then + call Recursive i r +return + Optimized: procedure expose stem. n = stem.0; s = 1; sl.1 = 1; sr.1 = n do until s = 0 l = sl.s; r = sr.s; s = s-1 do until l >= r - if r-l < 11 then do + if r-l < 20 then do do i = l+1 to r a = stem.i do j=i-1 by -1 to l while stem.j > a @@ -54,3 +248,5 @@ do until s = 0 end end return + +include Abend diff --git a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-6.rexx b/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-6.rexx deleted file mode 100644 index daf32e907d..0000000000 --- a/Task/Sorting-algorithms-Quicksort/REXX/sorting-algorithms-quicksort-6.rexx +++ /dev/null @@ -1,73 +0,0 @@ -numeric digits 9 -parse version version; say version Digits() 'digits' -arg n v -if n = '' then n = 10 -if v = '' then v = 1 -show = (n > 0); n = Abs(n) -say 'Quicksort: Timing Version' v 'for' n 'random numbers' -call Generate -if show then call ShowSave -select - when v = 1 then do - call Save2Stem - call Time 'r'; call Qsort n; say 'Qsort' format(time('e'),3,3) 'seconds' - if show then call ShowStem - end - when v = 2 then do - call Time 'r'; call Save2Stack; say 'Save2Stack' format(time('e'),3,3) 'seconds' - call Time 'r'; call Quicksort; say 'Quicksort ' format(time('e'),3,3) 'seconds' - call Time 'r'; call Stack2Stem; say 'Stack2Stem' format(time('e'),3,3) 'seconds' - if show then call ShowStem - end - when v = 3 then do - call Save2Stem - call Time 'r'; call Elegant; say 'Elegant' format(time('e'),3,3) 'seconds' - if show then call ShowStem - end - when v = 4 then do - call Save2Stem - call Time 'r'; call Recursive 1 n; say 'Recursive' format(time('e'),3,3) 'seconds' - if show then call ShowStem - end - when v = 5 then do - call Save2Stem - call Time 'r'; call Optimized; say 'Optimized' format(time('e'),3,3) 'seconds' - if show then call ShowStem - end - otherwise nop -end -say -exit - -Generate: -do x = 1 to n - save.x = 10000*Random(0,9999)+Random(0,9999) -end -save.0 = n -return - -ShowSave: -do x = 1 to 5 - say x save.x -end -do x = n-4 to n - say x save.x -end -return - -ShowStem: -do x = 1 to 5 - say x stem.x -end -do x = n-4 to n - say x stem.x -end -return - -Save2Stem: -do x = 0 to n - stem.x = save.x -end -return - -/* Sorting procedures follow, not shown here */ diff --git a/Task/Sorting-algorithms-Radix-sort/EasyLang/sorting-algorithms-radix-sort.easy b/Task/Sorting-algorithms-Radix-sort/EasyLang/sorting-algorithms-radix-sort.easy index 71f9c57887..c13423805d 100644 --- a/Task/Sorting-algorithms-Radix-sort/EasyLang/sorting-algorithms-radix-sort.easy +++ b/Task/Sorting-algorithms-Radix-sort/EasyLang/sorting-algorithms-radix-sort.easy @@ -1,18 +1,14 @@ -proc sort . d[] . +proc sort &d[] . # radix = 10 radix = 256 - max = 0 + max = -1 / 0 for di = 1 to len d[] - if d[di] > max - max = d[di] - . + max = higher d[di] max . len buck[][] radix pos = 1 while pos <= max - for i = 1 to radix - len buck[i][] 0 - . + for i = 1 to radix : len buck[i][] 0 for di = 1 to len d[] h = d[di] div pos mod radix + 1 buck[h][] &= d[di] diff --git a/Task/Sorting-algorithms-Radix-sort/JavaScript/sorting-algorithms-radix-sort.js b/Task/Sorting-algorithms-Radix-sort/JavaScript/sorting-algorithms-radix-sort.js new file mode 100644 index 0000000000..9ec9b38028 --- /dev/null +++ b/Task/Sorting-algorithms-Radix-sort/JavaScript/sorting-algorithms-radix-sort.js @@ -0,0 +1,60 @@ +// Radix sort comparator for 32-bit two's complement integers +class RadixTest { + constructor(bit) { + this.bit = bit; // bit position [0..31] to examine + } + + // function call operator (simulated with a method) + test(value) { + if (this.bit === 31) { // sign bit + return value < 0; // negative int to left partition + } else { + return !(value & (1 << this.bit)); // 0 bit to left partition + } + } +} + +// Helper function to partition an array in place +function partition(arr, start, end, radixTest) { + let i = start - 1; + + for (let j = start; j < end; j++) { + if (radixTest.test(arr[j])) { + i++; + // Swap arr[i] and arr[j] + [arr[i], arr[j]] = [arr[j], arr[i]]; + } + } + return i + 1; +} + +// Least significant digit radix sort +function lsdRadixSort(arr) { + for (let lsb = 0; lsb < 32; ++lsb) { // least-significant-bit + const radixTest = new RadixTest(lsb); + partition(arr, 0, arr.length, radixTest); + } +} + +// Most significant digit radix sort (recursive) +function msdRadixSort(arr, start = 0, end = arr.length, msb = 31) { + if (start < end -1 && msb >= 0) { // changed (first != last) to (start < end-1) for easier indexing + const radixTest = new RadixTest(msb); + let mid = partition(arr, start, end, radixTest); + msb--; // decrement most-significant-bit + msdRadixSort(arr, start, mid, msb); // sort left partition + msdRadixSort(arr, mid, end, msb); // sort right partition + } +} + +// test radix_sort +function main() { + let data = [170, 45, 75, -90, -802, 24, 2, 66]; + + lsdRadixSort(data); + // msdRadixSort(data); + + console.log(data.join(" ")); +} + +main(); diff --git a/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort.rs b/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-1.rs similarity index 80% rename from Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort.rs rename to Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-1.rs index eff59ff502..c6aeb4717a 100644 --- a/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort.rs +++ b/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-1.rs @@ -6,13 +6,11 @@ fn merge(in1: &[i32], in2: &[i32], out: &mut [i32]) { // least significant digit radix sort fn radix_sort(data: &mut [i32]) { - for bit in 0..31 { - // types of small and big is Vec. - // It will be infered from the next call of merge function. + for bit in 0..i32::BITS - 1 { let (small, big): (Vec<_>, Vec<_>) = data.iter().partition(|&&x| (x >> bit) & 1 == 0); merge(&small, &big, data); } - // last bit is sign + // lastly, handle the sign bit let (negative, positive): (Vec<_>, Vec<_>) = data.iter().partition(|&&x| x < 0); merge(&negative, &positive, data); } diff --git a/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-2.rs b/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-2.rs new file mode 100644 index 0000000000..4f4fe5a551 --- /dev/null +++ b/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-2.rs @@ -0,0 +1,24 @@ +fn radix_sort(arr: &mut [u32]) { + let mut buf = vec![0; arr.len()]; + + // Optional: Reduce the amount of iterations by finding the max value bit + let max_bit = u32::BITS - arr.iter().max().map(|t| t.leading_zeros()).unwrap_or(0); + + for bit in 0..max_bit { + // Manual implementation of partition with only one buffer array + let mut a = 0; + let mut b = 0; + + for i in 0..arr.len() { + if arr[i] >> bit & 1 == 0 { + arr[a] = arr[i]; + a += 1; + } else { + buf[b] = arr[i]; + b += 1; + } + } + + arr[a..].copy_from_slice(&buf[..b]); + } +} diff --git a/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-3.rs b/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-3.rs new file mode 100644 index 0000000000..134ee19285 --- /dev/null +++ b/Task/Sorting-algorithms-Radix-sort/Rust/sorting-algorithms-radix-sort-3.rs @@ -0,0 +1,40 @@ +fn radix_sort(arr: &mut [i32]) { + let mut buf = vec![0; arr.len()]; + + // Optional: Reduce the number of iterations by finding the max value bit + let max_bit = arr.iter().fold(0, |acc, x| { + let bits = if x.is_negative() { + i32::BITS - x.leading_ones() // Negative msb is always 1 so leading_ones() >= 1 + } else { + i32::BITS - x.leading_zeros() // Positive/zero msb is always 0 so leading_zeros() >= 1 + }; + + core::cmp::max(acc, bits) + }); + let sign_bit = i32::BITS - 1; + + // Manual implementation of partition with only one buffer array + let mut partition = |bit: u32| { + let mut a = 0; + let mut b = 0; + + for i in 0..arr.len() { + // Flip the sign bit before comparing so negatives are always ordered before positives + if (arr[i] ^ i32::MIN) >> bit & 1 == 0 { + arr[a] = arr[i]; + a += 1; + } else { + buf[b] = arr[i]; + b += 1; + } + } + + arr[a..].copy_from_slice(&buf[..b]); + }; + + // This will not duplicate work because max_bits <= sign_bit therefore bit < sign_bit + for bit in 0..max_bit { + partition(bit); + } + partition(sign_bit); +} diff --git a/Task/Sorting-algorithms-Selection-sort/EasyLang/sorting-algorithms-selection-sort.easy b/Task/Sorting-algorithms-Selection-sort/EasyLang/sorting-algorithms-selection-sort.easy index 36082f6d15..38cda3ad29 100644 --- a/Task/Sorting-algorithms-Selection-sort/EasyLang/sorting-algorithms-selection-sort.easy +++ b/Task/Sorting-algorithms-Selection-sort/EasyLang/sorting-algorithms-selection-sort.easy @@ -1,10 +1,6 @@ -proc sort . d[] . - for i = 1 to len d[] - 1 - for j = i + 1 to len d[] - if d[j] < d[i] - swap d[j] d[i] - . - . +proc sort &d[] . + for i = 1 to len d[] - 1 : for j = i + 1 to len d[] + if d[j] < d[i] : swap d[j] d[i] . . data[] = [ 29 4 72 44 55 26 27 77 92 5 ] diff --git a/Task/Sorting-algorithms-Shell-sort/EasyLang/sorting-algorithms-shell-sort.easy b/Task/Sorting-algorithms-Shell-sort/EasyLang/sorting-algorithms-shell-sort.easy index 81c18775a5..857b2c90d5 100644 --- a/Task/Sorting-algorithms-Shell-sort/EasyLang/sorting-algorithms-shell-sort.easy +++ b/Task/Sorting-algorithms-Shell-sort/EasyLang/sorting-algorithms-shell-sort.easy @@ -1,4 +1,4 @@ -proc shellsort . a[] . +proc shellsort &a[] . inc = len a[] div 2 while inc > 0 for i = inc to len a[] diff --git a/Task/Sorting-algorithms-Sleep-sort/JavaScript/sorting-algorithms-sleep-sort-1.js b/Task/Sorting-algorithms-Sleep-sort/JavaScript/sorting-algorithms-sleep-sort-1.js index a030ead4be..0fcca43ba1 100644 --- a/Task/Sorting-algorithms-Sleep-sort/JavaScript/sorting-algorithms-sleep-sort-1.js +++ b/Task/Sorting-algorithms-Sleep-sort/JavaScript/sorting-algorithms-sleep-sort-1.js @@ -1,5 +1,5 @@ -Array.prototype.timeoutSort = function (f) { - this.forEach(function (n) { - setTimeout(function () { f(n) }, 5 * n) - }); -} +Object.defineProperty(Array.prototype, "timeoutSort", { + value(f) { + this.forEach(n => setTimeout(() => f(n), 5 * n)) + } +}) diff --git a/Task/Sorting-algorithms-Sleep-sort/JavaScript/sorting-algorithms-sleep-sort-2.js b/Task/Sorting-algorithms-Sleep-sort/JavaScript/sorting-algorithms-sleep-sort-2.js index 7fbd5cac3e..e9e6fe998d 100644 --- a/Task/Sorting-algorithms-Sleep-sort/JavaScript/sorting-algorithms-sleep-sort-2.js +++ b/Task/Sorting-algorithms-Sleep-sort/JavaScript/sorting-algorithms-sleep-sort-2.js @@ -1 +1 @@ -[1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0].timeoutSort(function(n) { document.write(n + '
'); }) +[1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0].timeoutSort(n => document.write(n + '
')) diff --git a/Task/Sorting-algorithms-Stooge-sort/EasyLang/sorting-algorithms-stooge-sort.easy b/Task/Sorting-algorithms-Stooge-sort/EasyLang/sorting-algorithms-stooge-sort.easy index 09be1a07d4..cd0b4f10d6 100644 --- a/Task/Sorting-algorithms-Stooge-sort/EasyLang/sorting-algorithms-stooge-sort.easy +++ b/Task/Sorting-algorithms-Stooge-sort/EasyLang/sorting-algorithms-stooge-sort.easy @@ -1,7 +1,5 @@ -proc stsort left right . d[] . - if d[left] > d[right] - swap d[left] d[right] - . +proc stsort left right &d[] . + if d[left] > d[right] : swap d[left] d[right] if right - left + 1 > 2 t = (right - left + 1) div 3 stsort left right - t d[] @@ -9,8 +7,6 @@ proc stsort left right . d[] . stsort left right - t d[] . . -for i = 1 to 100 - d[] &= random 1000 -. +for i = 1 to 100 : d[] &= random 1000 stsort 1 len d[] d[] print d[] diff --git a/Task/Sorting-algorithms-Strand-sort/EasyLang/sorting-algorithms-strand-sort.easy b/Task/Sorting-algorithms-Strand-sort/EasyLang/sorting-algorithms-strand-sort.easy index 484f6e4117..0e46dafbb8 100644 --- a/Task/Sorting-algorithms-Strand-sort/EasyLang/sorting-algorithms-strand-sort.easy +++ b/Task/Sorting-algorithms-Strand-sort/EasyLang/sorting-algorithms-strand-sort.easy @@ -1,4 +1,4 @@ -proc merge . a[] b[] . +proc merge &a[] &b[] . a = 1 ; b = 1 while a <= len a[] and b <= len b[] if a[a] < b[b] @@ -19,7 +19,7 @@ proc merge . a[] b[] . . swap a[] r[] . -proc strand . a[] s[] . +proc strand &a[] &s[] . s[] = [ a[1] ] for i = 2 to len a[] if a[i] > s[$] @@ -30,7 +30,7 @@ proc strand . a[] s[] . . swap a[] an[] . -proc strandsort . a[] . +proc strandsort &a[] . strand a[] out[] while len a[] > 0 strand a[] b[] diff --git a/Task/Sorting-algorithms-Strand-sort/FreeBASIC/sorting-algorithms-strand-sort.basic b/Task/Sorting-algorithms-Strand-sort/FreeBASIC/sorting-algorithms-strand-sort.basic new file mode 100644 index 0000000000..363a614554 --- /dev/null +++ b/Task/Sorting-algorithms-Strand-sort/FreeBASIC/sorting-algorithms-strand-sort.basic @@ -0,0 +1,100 @@ +Sub strandSort(bs() As Long) + Dim As Long subList() + Dim As Long results() + Dim As Long i, j, k + Dim As Long lb = LBound(bs), ub = UBound(bs) + + ' Initialize results array with zero elements + ReDim results(-1) + + While ub >= lb + ReDim subList(0) + subList(0) = bs(lb) + + ' Remove the first element + For i = lb To ub - 1 + bs(i) = bs(i + 1) + Next + ReDim Preserve bs(ub - 1) + ub -= 1 + + ' Extract sorted subsequence + For i = lb To ub + If bs(i) >= subList(UBound(subList)) Then + ReDim Preserve subList(UBound(subList) + 1) + subList(UBound(subList)) = bs(i) + + ' Remove the element + For j = i To ub - 1 + bs(j) = bs(j + 1) + Next + ReDim Preserve bs(ub - 1) + ub -= 1 + i -= 1 + End If + Next + + ' Merge lists - but only if results has elements + If UBound(results) >= 0 Then + ReDim As Long merged(UBound(results) + UBound(subList) + 1) + i = 0 + j = 0 + k = 0 + + While i <= UBound(results) And j <= UBound(subList) + If results(i) < subList(j) Then + merged(k) = results(i) + i += 1 + Else + merged(k) = subList(j) + j += 1 + End If + k += 1 + Wend + + While i <= UBound(results) + merged(k) = results(i) + i += 1 + k += 1 + Wend + + While j <= UBound(subList) + merged(k) = subList(j) + j += 1 + k += 1 + Wend + + ReDim results(UBound(merged)) + For i = 0 To UBound(merged) + results(i) = merged(i) + Next + Else + ' If results is empty, just copy subList to results + ReDim results(UBound(subList)) + For i = 0 To UBound(subList) + results(i) = subList(i) + Next + End If + Wend + + ' Copy results back to bs + ReDim bs(UBound(results)) + For i = 0 To UBound(results) + bs(i) = results(i) + Next +End Sub + +'--- Main Program --- +Dim As Long i +Dim As Long array(14) = {-5,-3, 0,-7, 5, 2, 3, 6,-6,-1, 1,-2, 4, 7,-4} +Dim As Long a = LBound(array), b = UBound(array) + +Print "unsort "; +For i = a To b : Print Using "####"; array(i); : Next i + +strandSort(array()) ' sort the array + +Print !"\n sort "; +For i = a To b : Print Using "####"; array(i); : Next i + +Sleep diff --git a/Task/Sorting-algorithms-Strand-sort/M2000-Interpreter/sorting-algorithms-strand-sort.m2000 b/Task/Sorting-algorithms-Strand-sort/M2000-Interpreter/sorting-algorithms-strand-sort.m2000 new file mode 100644 index 0000000000..9068a2ded2 --- /dev/null +++ b/Task/Sorting-algorithms-Strand-sort/M2000-Interpreter/sorting-algorithms-strand-sort.m2000 @@ -0,0 +1,68 @@ +module Strand_sort{ + function strand_sort(aa as array) { + function mergelist(sa, sb) { + flush ' empty current stack + variant v, g + integer L=3 + while len(sa) and len(sb) + if L=1 else stack sa {read v} + if L=2 else stack sb {read g} + if vL then + stack a { + shift i ' get i_th item as top + over ' copy one + read g ' read in a variant + shiftback i ' send back to i + } + L=i + end if + if g > v then + stack a { + shift i + drop + } + data g + v = g + else + i++ + end if + end while + =[] + } + + a=stack(aa) + out = strand(&a) + while len(a) + out = mergelist(out, strand(&a)) + end while + =array(out) + } + m = (1, 6, 3, 2, 1, 7, 5, 3) + Print m + Print strand_sort(m) + m = ("aa", "cc", "bb", "a1") + Print m + Print strand_sort(m) +} +Strand_sort diff --git a/Task/Sorting-algorithms-Strand-sort/Rust/sorting-algorithms-strand-sort.rs b/Task/Sorting-algorithms-Strand-sort/Rust/sorting-algorithms-strand-sort.rs new file mode 100644 index 0000000000..f94c7a0317 --- /dev/null +++ b/Task/Sorting-algorithms-Strand-sort/Rust/sorting-algorithms-strand-sort.rs @@ -0,0 +1,153 @@ +use std::fmt; + +struct Link { + value: i32, + next: Option>, +} + +impl Link { + fn new(value: i32, next: Option>) -> Self { + Link { value, next } + } +} + +impl fmt::Display for Link { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "[{}", self.value)?; + + let mut current = &self.next; + while let Some(link) = current { + write!(f, " {}", link.value)?; + current = &link.next; + } + + write!(f, "]") + } +} + +fn link_ints(s: &[i32]) -> Option> { + if s.is_empty() { + None + } else { + Some(Box::new(Link::new(s[0], link_ints(&s[1..])))) + } +} + +fn strand_sort(mut a: Option>) -> Option> { + let mut result: Option> = None; + + while let Some(mut head) = a { + // Take the first element for our sublist + a = head.next.take(); + + // Build sublist + let mut sublist = Some(head); + let mut sublist_tail = sublist.as_mut().unwrap(); + + // Process the remaining elements in the original list + let mut current = a; + a = None; + + // Start building a new 'a' list + let mut new_a = None; + let mut new_a_tail_ptr: *mut Option> = &mut new_a; + + while let Some(mut node) = current { + current = node.next.take(); + + if node.value > sublist_tail.value { + // Append to sublist + sublist_tail.next = Some(node); + sublist_tail = sublist_tail.next.as_mut().unwrap(); + } else { + // Add to the new 'a' list + unsafe { + *new_a_tail_ptr = Some(node); + new_a_tail_ptr = &mut (*new_a_tail_ptr).as_mut().unwrap().next; + } + } + } + + a = new_a; + + // If result is empty, set it to the sublist + if result.is_none() { + result = sublist; + continue; + } + + // Merge sublist with result + result = merge(result, sublist); + } + + result +} + +fn merge(list1: Option>, list2: Option>) -> Option> { + match (list1, list2) { + (None, list2) => list2, + (list1, None) => list1, + (Some(mut head1), Some(mut head2)) => { + // Start with the smaller value + let mut result; + let mut current; + + if head1.value <= head2.value { + result = Some(head1); + current = result.as_mut().unwrap(); + match current.next.take() { + Some(next) => head1 = next, + None => { + current.next = Some(head2); + return result; + } + } + } else { + result = Some(head2); + current = result.as_mut().unwrap(); + match current.next.take() { + Some(next) => head2 = next, + None => { + current.next = Some(head1); + return result; + } + } + } + + // Merge the rest + loop { + if head1.value <= head2.value { + current.next = Some(head1); + current = current.next.as_mut().unwrap(); + match current.next.take() { + Some(next) => head1 = next, + None => { + current.next = Some(head2); + break; + } + } + } else { + current.next = Some(head2); + current = current.next.as_mut().unwrap(); + match current.next.take() { + Some(next) => head2 = next, + None => { + current.next = Some(head1); + break; + } + } + } + } + + result + } + } +} + +fn main() { + let a = link_ints(&[170, 45, 75, -90, -802, 24, 2, 66]); + println!("before: {}", a.as_ref().map_or("None".to_string(), |link| link.to_string())); + + let b = strand_sort(a); + println!("after: {}", b.as_ref().map_or("None".to_string(), |link| link.to_string())); +} diff --git a/Task/Sorting-algorithms-Strand-sort/Zig/sorting-algorithms-strand-sort.zig b/Task/Sorting-algorithms-Strand-sort/Zig/sorting-algorithms-strand-sort.zig new file mode 100644 index 0000000000..1056faa5d4 --- /dev/null +++ b/Task/Sorting-algorithms-Strand-sort/Zig/sorting-algorithms-strand-sort.zig @@ -0,0 +1,190 @@ +const std = @import("std"); + +const Link = struct { + value: i32, + next: ?*Link, + + fn new(allocator: std.mem.Allocator, value: i32, next: ?*Link) !*Link { + const link = try allocator.create(Link); + link.* = .{ .value = value, .next = next }; + return link; + } + + pub fn format( + self: *const Link, + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = fmt; + _ = options; + + try writer.print("[{}", .{self.value}); + + var current = self.next; + while (current) |link| { + try writer.print(" {}", .{link.value}); + current = link.next; + } + + try writer.print("]", .{}); + } +}; + +// Function to free all nodes in a linked list +fn freeList(allocator: std.mem.Allocator, list: ?*Link) void { + var current = list; + while (current) |node| { + const next = node.next; + allocator.destroy(node); + current = next; + } +} + +fn linkInts(allocator: std.mem.Allocator, s: []const i32) !?*Link { + if (s.len == 0) { + return null; + } else { + return try Link.new(allocator, s[0], try linkInts(allocator, s[1..])); + } +} + +fn strandSort(allocator: std.mem.Allocator, a: ?*Link) !?*Link { + var result: ?*Link = null; + var current_a = a; + + while (current_a) |head| { + // Take the first element for our sublist + current_a = head.next; + head.next = null; + + // Build sublist + const sublist: ?*Link = head; + var sublist_tail = sublist.?; + + // Process the remaining elements in the original list + var current = current_a; + current_a = null; + + // Start building a new 'a' list + var new_a: ?*Link = null; + var new_a_tail: ?*Link = null; + + while (current) |node| { + current = node.next; + node.next = null; + + if (node.value > sublist_tail.value) { + // Append to sublist + sublist_tail.next = node; + sublist_tail = node; + } else { + // Add to the new 'a' list + if (new_a == null) { + new_a = node; + new_a_tail = node; + } else { + new_a_tail.?.next = node; + new_a_tail = node; + } + } + } + + current_a = new_a; + + // If result is empty, set it to the sublist + if (result == null) { + result = sublist; + continue; + } + + // Merge sublist with result + result = try merge(allocator, result, sublist); + } + + return result; +} + +fn merge(allocator: std.mem.Allocator, list1: ?*Link, list2: ?*Link) !?*Link { + _ = allocator; // Allocator is not needed here, but keeping for consistency + + if (list1 == null) return list2; + if (list2 == null) return list1; + + var head1 = list1.?; + var head2 = list2.?; + + // Start with the smaller value + var result: ?*Link = null; + var current: *Link = undefined; + + if (head1.value <= head2.value) { + result = head1; + current = head1; + head1 = head1.next orelse { + current.next = head2; + return result; + }; + } else { + result = head2; + current = head2; + head2 = head2.next orelse { + current.next = head1; + return result; + }; + } + + // Merge the rest + while (true) { + if (head1.value <= head2.value) { + current.next = head1; + current = head1; + head1 = head1.next orelse { + current.next = head2; + break; + }; + } else { + current.next = head2; + current = head2; + head2 = head2.next orelse { + current.next = head1; + break; + }; + } + } + + return result; +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer { + const deinit_status = gpa.deinit(); + if (deinit_status == .leak) @panic("MEMORY LEAK"); + } + + const array = [_]i32{ 170, 45, 75, -90, -802, 24, 2, 66 }; + const a = try linkInts(allocator, &array); + + const stdout = std.io.getStdOut().writer(); + try stdout.print("before: ", .{}); + if (a) |link| { + try stdout.print("{}", .{link}); + } else { + try stdout.print("None", .{}); + } + try stdout.print("\n", .{}); + + const b = try strandSort(allocator, a); + try stdout.print("after: ", .{}); + if (b) |link| { + try stdout.print("{}", .{link}); + } else { + try stdout.print("None", .{}); + } + try stdout.print("\n", .{}); + + // Free memory + freeList(allocator, b); +} diff --git a/Task/Spelling-of-ordinal-numbers/JavaScript/spelling-of-ordinal-numbers.js b/Task/Spelling-of-ordinal-numbers/JavaScript/spelling-of-ordinal-numbers.js new file mode 100644 index 0000000000..c9cca19f12 --- /dev/null +++ b/Task/Spelling-of-ordinal-numbers/JavaScript/spelling-of-ordinal-numbers.js @@ -0,0 +1,163 @@ +// Equivalent data structures for Java's arrays and map +const nums = [ + "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", + "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" +]; + +const tens = ["zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]; + +// Map for irregular ordinal endings (like Java's static initializer block) +const ordinalMap = { + "one": "first", + "two": "second", + "three": "third", + "five": "fifth", + "eight": "eighth", + "nine": "ninth", + "twelve": "twelfth" + // Note: twenty, thirty, etc. are handled by the 'y' -> 'ieth' rule +}; + +/** + * Recursive helper function to convert a number to its cardinal English spelling. + * Handles positive integers up to quintillions. + * Note: JavaScript numbers are 64-bit floats (IEEE 754). Integers are safe up to + * Number.MAX_SAFE_INTEGER (2^53 - 1, approx 9 quadrillion). Very large numbers + * beyond this might lose precision or require BigInt. The test cases provided + * fit within the safe integer range. + * @param {number} n - The number to convert. + * @returns {string} The English spelling of the number. + */ +function numToStringHelper(n) { + if (n < 0) { + // Handle negative numbers recursively + return "negative " + numToStringHelper(-n); + } + if (n <= 19) { + // Numbers 0-19 directly from the nums array + return nums[n]; + } + if (n <= 99) { + // Numbers 20-99: combine tens place and (optionally) ones place + // Use Math.floor for integer division equivalent + const ten = tens[Math.floor(n / 10)]; + const rest = n % 10; + return ten + (rest > 0 ? "-" + numToStringHelper(rest) : ""); + } + + let label = ""; + let factor = 0; + + // Determine the scale (hundred, thousand, million, etc.) + // Using number literals for factors + if (n <= 999) { + label = "hundred"; + factor = 100; + } else if (n <= 999999) { + label = "thousand"; + factor = 1000; + } else if (n <= 999999999) { + label = "million"; + factor = 1000000; + } else if (n <= 999999999999) { + label = "billion"; + factor = 1000000000; // 1e9 + } else if (n <= 999999999999999) { + label = "trillion"; + factor = 1000000000000; // 1e12 + } else if (n <= 999999999999999999) { // Approaching JS safe integer limit + label = "quadrillion"; + factor = 1000000000000000; // 1e15 + } else { // Numbers beyond this may need BigInt for perfect accuracy + label = "quintillion"; + factor = 1000000000000000000; // 1e18 + } + + // Recursively spell the parts + // Use Math.floor for integer division equivalent + const highPart = numToStringHelper(Math.floor(n / factor)); + const lowPart = n % factor; + + return highPart + " " + label + (lowPart > 0 ? " " + numToStringHelper(lowPart) : ""); +} + +/** + * Converts a number to its cardinal English spelling (e.g., 123 -> "one hundred twenty-three"). + * Public facing function that calls the helper. + * @param {number} n - The number to convert. + * @returns {string} The English spelling of the number. + */ +function numToString(n) { + // Ensure input is a number + n = Number(n); + // Handle the base case of 0 explicitly for clarity, though helper handles it. + if (n === 0) { + return nums[0]; // "zero" + } + return numToStringHelper(n); +} + + +/** + * Converts a number to its ordinal English spelling (e.g., 1 -> "first", 123 -> "one hundred twenty-third"). + * @param {number} n - The number to convert. + * @returns {string} The ordinal English spelling. + */ +function toOrdinal(n) { + // Get the cardinal spelling first + const spelling = numToString(n); + + // Split the spelling into words + const parts = spelling.split(' '); + + // Get the last word, which determines the ordinal ending + const lastWord = parts[parts.length - 1]; + + let replacement = ""; + + // Check if the last word is hyphenated (e.g., "twenty-three") + if (lastWord.includes('-')) { + const lastSplit = lastWord.split('-'); // ["twenty", "three"] + const base = lastSplit[0]; // "twenty" + const lastPart = lastSplit[1]; // "three" + let ordinalLastPart = ""; + + // Apply ordinal rules to the part after the hyphen + if (ordinalMap.hasOwnProperty(lastPart)) { + ordinalLastPart = ordinalMap[lastPart]; // irregular: three -> third + } else if (lastPart.endsWith('y')) { + // This case shouldn't happen after a hyphen (e.g., "sixty-twenty"), + // but included for robustness matching the Java code. + ordinalLastPart = lastPart.slice(0, -1) + "ieth"; + } else { + ordinalLastPart = lastPart + "th"; // regular: four -> fourth + } + replacement = `${base}-${ordinalLastPart}`; // "twenty-third" + + } else { + // Handle non-hyphenated last words + if (ordinalMap.hasOwnProperty(lastWord)) { + replacement = ordinalMap[lastWord]; // irregular: one -> first, two -> second + } else if (lastWord.endsWith('y')) { + replacement = lastWord.slice(0, -1) + "ieth"; // twenty -> twentieth, thirty -> thirtieth + } else { + replacement = lastWord + "th"; // seven -> seventh, hundred -> hundredth + } + } + + // Replace the last word in the parts array + parts[parts.length - 1] = replacement; + + // Join the parts back together + return parts.join(' '); +} + +// --- Main execution / Testing --- +// Equivalent to the Java main method's test loop +const testNumbers = [0, 1, 2, 3, 4, 5, 11, 12, 13, 19, 20, 21, 22, 23, 65, 99, 100, 101, 272, 23456, 8007006005004003]; + +console.log("--- Ordinal Number Spelling (JavaScript) ---"); +testNumbers.forEach(test => { + // Use template literals for easy string formatting + console.log(`${test} = ${toOrdinal(test)}`); +}); diff --git a/Task/Sphenic-numbers/Mathematica/sphenic-numbers.math b/Task/Sphenic-numbers/Mathematica/sphenic-numbers.math new file mode 100644 index 0000000000..ded24f8c8b --- /dev/null +++ b/Task/Sphenic-numbers/Mathematica/sphenic-numbers.math @@ -0,0 +1,3 @@ +Select[Select[{#,Catenate@MapApply[ConstantArray,FactorInteger[#]]}&/@Range[999],Last/*Length/*EqualTo[3]],Last/*DuplicateFreeQ][[All,1]] + +Select[Partition[Select[Select[{#,Catenate@MapApply[ConstantArray,FactorInteger[#]]}&/@Range[9999],Last/*Length/*EqualTo[3]],Last/*DuplicateFreeQ][[All,1]],3,1],MatchQ[#-First[#],{0,1,2}]&] diff --git a/Task/Spinning-rod-animation-Text/EasyLang/spinning-rod-animation-text.easy b/Task/Spinning-rod-animation-Text/EasyLang/spinning-rod-animation-text.easy index f5e8d8b029..bb7db3f84a 100644 --- a/Task/Spinning-rod-animation-Text/EasyLang/spinning-rod-animation-text.easy +++ b/Task/Spinning-rod-animation-Text/EasyLang/spinning-rod-animation-text.easy @@ -1,9 +1,8 @@ c$[] = strchars "🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘" -textsize 60 -move 20 30 +gtextsize 60 on timer ind = (ind + 1) mod1 len c$[] - text c$[ind] + gtext 20 30 c$[ind] timer 0.25 . timer 0 diff --git a/Task/Spiral-matrix/EasyLang/spiral-matrix.easy b/Task/Spiral-matrix/EasyLang/spiral-matrix.easy index 3f5bbef5f1..3062f93b49 100644 --- a/Task/Spiral-matrix/EasyLang/spiral-matrix.easy +++ b/Task/Spiral-matrix/EasyLang/spiral-matrix.easy @@ -1,4 +1,4 @@ -proc mkspiral n . t[] . +proc mkspiral n &t[] . subr side for i to l ind += d @@ -23,10 +23,8 @@ proc mkspiral n . t[] . . n = 5 mkspiral n t[] -numfmt 0 3 +numfmt 3 0 for i to n * n write t[i] - if i mod n = 0 - print "" - . + if i mod n = 0 : print "" . diff --git a/Task/Spiral-matrix/Uiua/spiral-matrix.uiua b/Task/Spiral-matrix/Uiua/spiral-matrix.uiua new file mode 100644 index 0000000000..98c96b6118 --- /dev/null +++ b/Task/Spiral-matrix/Uiua/spiral-matrix.uiua @@ -0,0 +1,5 @@ +Spiral ← ⍥(⊂+-⊃(⟜⇡⧻|⊢⊢|⍉⇌))×₂-₁⟜[[-₁ⁿ₂]] + +Spiral 1 +Spiral 4 +Spiral 5 diff --git a/Task/Split-a-character-string-based-on-change-of-character/C/split-a-character-string-based-on-change-of-character.c b/Task/Split-a-character-string-based-on-change-of-character/C/split-a-character-string-based-on-change-of-character-1.c similarity index 100% rename from Task/Split-a-character-string-based-on-change-of-character/C/split-a-character-string-based-on-change-of-character.c rename to Task/Split-a-character-string-based-on-change-of-character/C/split-a-character-string-based-on-change-of-character-1.c diff --git a/Task/Split-a-character-string-based-on-change-of-character/C/split-a-character-string-based-on-change-of-character-2.c b/Task/Split-a-character-string-based-on-change-of-character/C/split-a-character-string-based-on-change-of-character-2.c new file mode 100644 index 0000000000..77384ae201 --- /dev/null +++ b/Task/Split-a-character-string-based-on-change-of-character/C/split-a-character-string-based-on-change-of-character-2.c @@ -0,0 +1,32 @@ +#include + +void split(const char *src, char *dst) { + const char *src_tmp = src; + char *dst_tmp = dst; + + while (*src_tmp != '\0') { + int i = 0; + + // scan for the next change of character occurrence + while (*(src_tmp + ++i) == *src_tmp) + ; + + // copy the sequence of repeated characters to the destination buffer + snprintf(dst_tmp, i + 1, "%s", src_tmp); + + // add a comma or null character (if end of string) to the destination + // buffer and advance both the source and destination pointers + snprintf(dst_tmp += i, 3, "%s", *(src_tmp += i) == '\0' ? "\0" : ", "); + dst_tmp += 2; + } +} + +int main(void) { + const char *str = "gHHH5YY++///\\"; + char out[100]; // must be large enough to hold the result + + split(str, out); + printf("%s\n", out); + + return 0; +} diff --git a/Task/Split-a-character-string-based-on-change-of-character/Crystal/split-a-character-string-based-on-change-of-character.cr b/Task/Split-a-character-string-based-on-change-of-character/Crystal/split-a-character-string-based-on-change-of-character.cr new file mode 100644 index 0000000000..c220eb738f --- /dev/null +++ b/Task/Split-a-character-string-based-on-change-of-character/Crystal/split-a-character-string-based-on-change-of-character.cr @@ -0,0 +1,6 @@ +["gHHH5YY++///\\", + "aaabbbaaabcdeef" +].each do |s| + puts s + puts " -> " + s.scan(/(.)\1*/).flatten.join(", ") +end diff --git a/Task/Split-a-character-string-based-on-change-of-character/Emacs-Lisp/split-a-character-string-based-on-change-of-character.l b/Task/Split-a-character-string-based-on-change-of-character/Emacs-Lisp/split-a-character-string-based-on-change-of-character.l new file mode 100644 index 0000000000..9f040ca42e --- /dev/null +++ b/Task/Split-a-character-string-based-on-change-of-character/Emacs-Lisp/split-a-character-string-based-on-change-of-character.l @@ -0,0 +1,29 @@ +(defun get-char-values () + "List ascii values of chars in buffer named test-string." + (let ((my-chars) + (current-point 1)) + (with-current-buffer "test-string" + (while (char-after current-point) + (push (char-after current-point) my-chars) + (setq current-point (1+ current-point))) + (nreverse my-chars)))) + + (defun show-chars (ascii-values) + "Show characters from VALUES." + (let* ((first-char (nth 0 ascii-values)) + (current-char) + (current-position 1) + (first-element t) + (separator ", ")) + (when first-element + (setq first-element nil) + (setq previous-char first-char) + (insert first-char)) + (while (< current-position (length ascii-values)) + (setq current-char (nth current-position ascii-values)) + (if (equal current-char previous-char) + (insert current-char) + (insert separator) + (insert current-char)) + (setq previous-char current-char) + (setq current-position (1+ current-position))))) diff --git a/Task/Split-a-character-string-based-on-change-of-character/M2000-Interpreter/split-a-character-string-based-on-change-of-character.m2000 b/Task/Split-a-character-string-based-on-change-of-character/M2000-Interpreter/split-a-character-string-based-on-change-of-character.m2000 index 1eb9e6cfeb..7e182618c6 100644 --- a/Task/Split-a-character-string-based-on-change-of-character/M2000-Interpreter/split-a-character-string-based-on-change-of-character.m2000 +++ b/Task/Split-a-character-string-based-on-change-of-character/M2000-Interpreter/split-a-character-string-based-on-change-of-character.m2000 @@ -19,3 +19,27 @@ Module PrintParts(splitthis$) { } } PrintParts "gHHH5YY++///\" +' version 13 of M2000 Interpreter - old program run as is. +' [] get the current stack as object and leave an empty stack as current stack, +' array([]) empty the stack object (a linked linst) making a tuple (of variant type). +' #str$(", ") extract from array all items render as string and place between the ", " string - or a space by default, without argument. + +MODULE PrintParts(splitthis AS STRING) { + IF LEN(splitthis)=0 THEN PRINT : EXIT + STRING m, p + LONG c, i + STACK NEW { + FOR i=1 TO LEN(splitthis) + p=mid$(splitthis,i,1) + IF m<>p THEN + IF c>0 THEN DATA STRING$(m, c) + m=p : c=1 + ELSE + c++ + END IF + NEXT + IF c>0 THEN DATA STRING$(m, c) + PRINT ARRAY([])#STR$(", ") + } +} +PrintParts "gHHH5YY++///\" diff --git a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-1.rs b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-1.rs index 23740c561c..d7ad86f9dd 100644 --- a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-1.rs +++ b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-1.rs @@ -1,22 +1,52 @@ -fn splitter(string: &str) -> String { - let chars: Vec<_> = string.chars().collect(); - let mut result = Vec::new(); - let mut last_mismatch = 0; - for i in 0..chars.len() { - if chars.len() == 1 { - return chars[0..1].iter().collect(); - } - if i > 0 && chars[i-1] != chars[i] { - let temp_result: String = chars[last_mismatch..i].iter().collect(); - result.push(temp_result); - last_mismatch = i; - } - if i == chars.len() - 1 { - let temp_result: String = chars[last_mismatch..chars.len()].iter().collect(); - result.push(temp_result); +trait RosettaExt { + fn split_duplicates(&self) -> SplitDuplicates; +} + +impl RosettaExt for &str { + fn split_duplicates(&self) -> SplitDuplicates { + SplitDuplicates { string: self } + } +} + +struct SplitDuplicates<'a> { + string: &'a str, +} + +impl<'a> Iterator for SplitDuplicates<'a> { + type Item = &'a str; + + fn next(&mut self) -> Option { + if self.string.is_empty() { + None + } else { + // We want to keep track of the char boundaries when we split + let mut chars = self.string.char_indices(); + let mut l = chars.next()?; + + for r in chars { + // Compare characters; if they don't match, split + if l.1 != r.1 { + let (ret, rem) = self.string.split_at(r.0); + self.string = rem; + + return Some(ret); + } + l = r; + } + + // No more characters to compare, return the remaining string slice + let ret = self.string; + + // Exhaust string slice + self.string = &self.string[self.string.len()..]; + + Some(ret) } } - result.join(", ") +} + +fn splitter(s: &str) -> String { + s.split_duplicates().collect::>().join(", ") } fn main() { diff --git a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-2.rs b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-2.rs index 7504e9e9cf..ee68117974 100644 --- a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-2.rs +++ b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-2.rs @@ -1,20 +1,2 @@ -use itertools::Itertools; - -pub fn split_text(s: &str) -> Vec { - let mut r = Vec::new(); - for (_, group) in &s.chars().into_iter().group_by(|e| *e) { - r.push(group.map(|e| e.to_string()).join("")); - } - r -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_splitting_text() { - assert_eq!(split_text("gHHH5YY++///\\"), vec!["g", "HHH", "5", "YY", "++", "///", "\\"]); - assert!(split_text("").is_empty()); - } -} +[dependencies] +itertools = { version = "0.14", features = ["use_alloc"] } diff --git a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-3.rs b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-3.rs new file mode 100644 index 0000000000..b5883d4df3 --- /dev/null +++ b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-3.rs @@ -0,0 +1,14 @@ +use itertools::Itertools; + +fn split_text(s: &str) -> String { + let mut r = Vec::new(); + for (_, group) in &s.chars().chunk_by(|e| *e) { + r.push(group.collect::()) + } + + r.join(", ") +} + +fn main() { + println!("output string: {}", split_text("gHHH5YY++///\\")); +} diff --git a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-4.rs b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-4.rs new file mode 100644 index 0000000000..7469bec903 --- /dev/null +++ b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-4.rs @@ -0,0 +1,2 @@ +[dependencies] +itertools = { version = "0.14", default-features = false } diff --git a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-5.rs b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-5.rs new file mode 100644 index 0000000000..49b4c2e4cf --- /dev/null +++ b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-5.rs @@ -0,0 +1,9 @@ +use itertools::Itertools; + +fn main() { + print!("output string: "); + for i in "gHHH5YY++///\\".split_duplicates().intersperse(", ") { + print!("{i}"); + } + println!(); +} diff --git a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-6.rs b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-6.rs new file mode 100644 index 0000000000..24e18fd2d6 --- /dev/null +++ b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-6.rs @@ -0,0 +1,9 @@ +#![feature(iter_intersperse)] + +fn main() { + print!("output string: "); + for i in "gHHH5YY++///\\".split_duplicates().intersperse(", ") { + print!("{i}"); + } + println!(); +} diff --git a/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-7.rs b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-7.rs new file mode 100644 index 0000000000..88f393c64b --- /dev/null +++ b/Task/Split-a-character-string-based-on-change-of-character/Rust/split-a-character-string-based-on-change-of-character-7.rs @@ -0,0 +1,5 @@ +#![feature(iter_intersperse)] +use itertools::Itertools; + +Iterator::intersperse(r#"gHHH5YY++///\"#.split_duplicates(), ", "); +Itertools::intersperse(r#"gHHH5YY++///\"#.split_duplicates(), ", "); diff --git a/Task/Square-form-factorization/Python/square-form-factorization.py b/Task/Square-form-factorization/Python/square-form-factorization.py new file mode 100644 index 0000000000..b27f52a88a --- /dev/null +++ b/Task/Square-form-factorization/Python/square-form-factorization.py @@ -0,0 +1,110 @@ +from math import sqrt, gcd + +M = [1, 3, 5, 7, 11] +UINT64_MAX = 18446744073709551615 + +def isqrt(n: int): + return int(sqrt(n)) + +def squfof(n: int): + if n % 2 == 0: + return 2 + + h = int(sqrt(n) + 0.5) + + if h ** 2 == n: + return h + + for m in M: + if m > 1 and n % m == 0: + return m + + if n > UINT64_MAX / m: + break + + mn = m * n + r = isqrt(mn) + + if r ** 2 > mn: + r -= 1 + + rn = r + + b = r + a = 1 + h = ((rn + b) // a) * a - b + c = (mn - h * h) // a + + for i in range(2, 4 * isqrt(2 * r)): + a, c = c, a + q = (rn + b) // a + t = b + b = q * a - b + c += q * (t - b) + + if i % 2 == 0: + r = int(sqrt(c) + 0.5) + + if r ** 2 == c: + q = (rn - b) // r + v = q * r + b + w = (mn - v * v) // r + + u = r + + while True: + w, u = u, w + r = v + q = (rn + v) // u + v = q * u - v + + if v == r: + break + + w += q * (r - v) + + h = gcd(n, u) + + if h != 1: + return h + + return 1 + +data = [ + 2501, + 12851, + 13289, + 75301, + 120787, + 967009, + 997417, + 7091569, + 13290059, + 42854447, + 223553581, + 2027651281, + 11111111111, + 100895598169, + 1002742628021, + 60012462237239, + 287129523414791, + 9007199254740931, + 11111111111111111, + 314159265358979323, + 384307168202281507, + 419244183493398773, + 658812288346769681, + 922337203685477563, + 1000000000000000127, + 1152921505680588799, + 1537228672809128917, + 4611686018427387877 +] + +print("N f N/f") +print("======================================") + +for n in data: + f = squfof(n) + res = 'fail' if f == 1 else f'{f:<10} {n // f}' + print(f'{n:<22} {res}') diff --git a/Task/Square-form-factorization/REXX/square-form-factorization.rexx b/Task/Square-form-factorization/REXX/square-form-factorization.rexx index e4f6277927..cb88ddad6f 100644 --- a/Task/Square-form-factorization/REXX/square-form-factorization.rexx +++ b/Task/Square-form-factorization/REXX/square-form-factorization.rexx @@ -1,54 +1,94 @@ -/*REXX pgm factors an integer using Daniel Shanks' (1917-1996) square form factorization*/ -numeric digits 100 /*ensure enough decimal digits.*/ -call dMults 1,3,5,7,11,3*5,3*7,3*11,5*7,5*11,7*11, 3*5*7, 3*5*11, 3*7*11, 5*7*11, 3*5*7*11 -call dTests 2501, 12851, 13289, 75301, 120787, 967009, 997417, 7091569, 13290059, , - 42854447, 223553581, 2027651281, 11111111111, 100895598169, 1002742628021, , - 60012462237239, 287129523414791, 9007199254740931, 11111111111111111, , - 314159265358979323, 384307168202281507, 419244183493398773, , - 658812288346769681, 922337203685477563, 1000000000000000127, , - 1152921505680588799, 1537228672809128917, 4611686018427387877 - w= length( commas(!.$) ) /*the max width of test numbers*/ - do tests=1 for !.0; n= !.tests; nc= commas(n) - f= ssff(n); fc= commas(f); wf= length(fc); if f\==0 then nf= commas(n%f) - if f\==0 then do; nfc= commas(n%f); wnfc= length(nfc); end - if f ==0 then _= " (Shank's square form factor failed.)" - else _= ' factors are: ' right( fc, max(w%2 , wf ) ) " and " , - right(nfc, max(w%2+4, wnfc) ) - say right(nc, w+5) _ - end /*tests*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? -dMults: @.$= 0; do j=1 for arg(); @.j= arg(j); @.$=max(@.$, @.j); end; @.0=j-1; return -dTests: !.$= 0; do j=1 for arg(); !.j= arg(j); !.$=max(!.$, !.j); end; !.0=j-1; return -gcd: procedure; parse arg x,y; do until _==0; _= x // y; x= y; y= _; end; return x -/*──────────────────────────────────────────────────────────────────────────────────────*/ -iSqrt: procedure; parse arg x; r=0; q=1; do while q<=x; q=q*4; end - do while q>1; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q; end; end - return r -/*──────────────────────────────────────────────────────────────────────────────────────*/ -ssff: procedure expose @.; parse arg n; n= abs(n); er= '***error***' - s= iSqrt(n); if s**2==n then return s; big= 2**digits() - do #=1 for @.0; k= @.# /*get a # from the list of low factors*/ - if n>big/k then do; say er 'number is too large: ' commas(k); exit 8; end - d= n*k; po= iSqrt(d); p= po - pprev= po; QQ= d - po*po - qprev= 1; BB= iSqrt(s+s)*6 - do i=2 while i=BB then iterate - b= (po-p)%r; p= b*r + p - pprev= p; qprev= r - QQ= (d - pprev*pprev)%qprev - do until p==pprev; pprev= p - b= (po+p)%QQ; q= QQ; p= b*QQ - p - QQ= qprev + b*(pprev-p); qprev= q - end /*until*/ - r= gcd(n, qprev) - if r\==1 then if r\==n then return r - end /*#*/ - return 0 +-- 8 May 2025 +include Settings +numeric digits 40 + +say 'SQUARE FORM FACTORIZATION' +say version +say +call TestNumbers +call Selected +call Randomized +exit + +TestNumbers: +procedure expose test. +t = '2501 12851 13289 75301 120787 967009 997417 7091569 13290059', + '42854447 223553581 2027651281 11111111111 100895598169 1002742628021', + '60012462237239 287129523414791 9007199254740931 11111111111111111', + '314159265358979323 384307168202281507 419244183493398773', + '658812288346769681 922337203685477563 1000000000000000127', + '1152921505680588799 1537228672809128917 4611686018427387877' +do i = 1 to Words(t) + test.i = Word(t,i) +end +test.0 = i-1 +return + +Selected: +procedure expose mult. test. glob. +call Time('r') +say 'Find a factor for 28 selected numbers...' +do t = 1 for test.0 + n = test.t + call Time('r') + f = Squfof(n) + if f = 0 then + u = 'failed' + else + u = f 'x' n/f + say Format(Time('e'),3,3)'s Squfof ' n '('Xpon(n)+1 'digits) =' u + call Time('r') + f = Pollardrho(n) + if f = 0 then + u = 'failed' + else + u = f 'x' n/f + say Format(Time('e'),3,3)'s Pollard' n '('Xpon(n)+1 'digits) =' u + if n < 1e17 then do + call Time('r') + f = Trialdiv(n); u = f 'x' n/f + say Format(Time('e'),3,3)'s Trial ' n '('Xpon(n)+1 'digits) =' u + end + say +end +say +return + +Randomized: +procedure expose mult. glob. +say 'Find a factor for 28 random numbers...' +x = 0 +do until x = 28 + n = (Right(Randu(),Randu(1,10))||Right(Randu(),Randu(1,10))||Right(Randu(),Randu(1,10)))/1 + if Pos(Right(n,1),05) > 0 | Even(n) | Digitsum(n)//3 = 0 then + iterate + call Time('r') + f = Squfof(n) + if f = 0 then + u = 'failed' + else + u = f 'x' n/f + say Format(Time('e'),3,3)'s Squfof ' n '('Xpon(n)+1 'digits) =' u + if n < 1e24 then do + call Time('r') + f = Pollardrho(n) + if f = 0 then + u = 'failed' + else + u = f 'x' n/f + say Format(Time('e'),3,3)'s Pollard' n '('Xpon(n)+1 'digits) =' u + end + if n < 1e17 then do + call Time('r') + f = Trialdiv(n); u = f 'x' n/f + say Format(Time('e'),3,3)'s Trial ' n '('Xpon(n)+1 'digits) =' u + end + say + x = x+1 +end +say +return + +include Numbers +include Functions +include Abend diff --git a/Task/Square-free-integers/EasyLang/square-free-integers.easy b/Task/Square-free-integers/EasyLang/square-free-integers.easy index 72647835ea..841902cb00 100644 --- a/Task/Square-free-integers/EasyLang/square-free-integers.easy +++ b/Task/Square-free-integers/EasyLang/square-free-integers.easy @@ -6,7 +6,7 @@ fastfunc square_free n . . return 1 . -proc run lo hi show . . +proc run lo hi show . print "From " & lo & " to " & hi & ":" for i = lo to hi if square_free i = 1 diff --git a/Task/Square-free-integers/PL-I-80/square-free-integers.pli b/Task/Square-free-integers/PL-I-80/square-free-integers.pli index d58642d4b3..931b27a43d 100644 --- a/Task/Square-free-integers/PL-I-80/square-free-integers.pli +++ b/Task/Square-free-integers/PL-I-80/square-free-integers.pli @@ -40,11 +40,11 @@ end report_number_found; /* return true if n has no square divisors other than 1 */ square_free: proc (n) returns (bit(1)); dcl (n, i, sq) fixed bin; - i = 2; + i = 3; sq = i * i; do while (sq <= n); - if (mod(n, sq) = 0) then return (false); - i = i + 1; + if (mod(n, sq) = 0) then return (false); + i = i + 2; sq = i * i; end; return (true); diff --git a/Task/Square-free-integers/REXX/square-free-integers.rexx b/Task/Square-free-integers/REXX/square-free-integers.rexx index 80bf992397..f6bb555df9 100644 --- a/Task/Square-free-integers/REXX/square-free-integers.rexx +++ b/Task/Square-free-integers/REXX/square-free-integers.rexx @@ -1,35 +1,80 @@ -/*REXX program displays square─free numbers (integers > 1) up to a specified limit. */ -numeric digits 20 /*be able to handle larger numbers. */ -parse arg LO HI . /*obtain optional arguments from the CL*/ -if LO=='' | LO=="," then LO= 1 /*Not specified? Then use the default.*/ -if HI=='' | HI=="," then HI= 145 /* " " " " " " */ -sw= linesize() - 1 /*use one less than a full line. */ -# = 0 /*count of square─free numbers found. */ -$= /*variable that holds a line of numbers*/ - do j=LO to abs(HI) /*process all integers between LO & HI.*/ - if \isSquareFree(j) then iterate /*Not square─free? Then skip this #. */ - #= # + 1 /*bump the count of square─free numbers*/ - if HI<0 then iterate /*Only counting 'em? Then look for more*/ - if length($ || j)1; q= q % 4; _= x - r - q; r= r % 2 - if _>=0 then do; x= _; r= r + q; end - end /*while q>1*/ - return r /*R is the integer square root of X. */ +say 'SQUARE-FREE INTEGERS - 6 Mar 2025' +say version +say +numeric digits 5 +call Show 1,145 +numeric digits 15 +call Show 1000000000000,1000000000145 +numeric digits 10 +call Count1 1000000 +call Count2 1000000 +exit + +Show: +call Time('r') +arg xx,yy +say 'Square-free integers between' xx 'and' yy +r = Length(yy)+1; n = 0 +do i = xx to yy + if Squarefree(i) then do + n = n+1 + call Charout ,Right(i,r) + if n//10 = 0 then + say + end +end +say +say Format(Time('e'),,3) 'seconds' +say +return + +Count1: +call Time('r') +arg xx +say 'Number of square-free integers <= 10^n' +say 'Direct method' +say '--------------' +say Left('n',4) Right('count',6) +say '--------------' +n = 0; e = 1 +do i = 1 to xx + if i >= 1'E'e then do + say Left('10^'e,5) Right(n,8) + e = e+1 + end + if Squarefree(i) then + n = n+1 +end +say '--------------' +say Format(Time('e'),,3) 'seconds' +say +return + +Count2: +call Time('r') +arg xx +call Squarefrees xx +say 'Number of square-free integers <= 10^n' +say 'Sieve method' +say '--------------' +say Left('n',4) Right('count',6) +say '--------------' +n = 0; e = 1 +do i = 1 to xx + if i >= 1'E'e then do + say Left('10^'e,5) Right(n,8) + e = e+1 + end + if squa.flag.i then + n = n+1 +end +say '--------------' +say Format(Time('e'),,3) 'seconds' +return + +include Numbers +include Sequences +include Functions +include Abend diff --git a/Task/Stable-marriage-problem/EasyLang/stable-marriage-problem.easy b/Task/Stable-marriage-problem/EasyLang/stable-marriage-problem.easy index 476d4eeef6..54cc1b7c80 100644 --- a/Task/Stable-marriage-problem/EasyLang/stable-marriage-problem.easy +++ b/Task/Stable-marriage-problem/EasyLang/stable-marriage-problem.easy @@ -10,7 +10,7 @@ func finds name$[] s$ . . . . -proc read . . +proc read . s$ = input s$ = s$ for m to n @@ -35,7 +35,7 @@ len meng[] n len weng[] n len wcand[][] n # -proc engagements . . +proc engagements . print "Engagements:" for m to n w = 1 @@ -93,20 +93,20 @@ proc engagements . . . engagements # -proc showcouples . . +proc showcouples . print "Couples:" for w to n print " " & wnam$[w] & " + " & mnam$[weng[w]] . print "" . -proc swapw a b . . +proc swapw a b . print wnam$[a] & " and " & wnam$[b] & " swap their partners" print "" swap weng[a] weng[b] swap meng[weng[a]] meng[weng[b]] . -proc checkstable . . +proc checkstable . for m to n w = meng[m] for w1 to n diff --git a/Task/Stack-traces/Crystal/stack-traces.cr b/Task/Stack-traces/Crystal/stack-traces.cr new file mode 100644 index 0000000000..65ff100a45 --- /dev/null +++ b/Task/Stack-traces/Crystal/stack-traces.cr @@ -0,0 +1,15 @@ +def method1 + method2 +end + +def method2 + puts caller.join("\n") +end + +def method0 + method1 +end + +puts "-------" +method0 +puts "-------" diff --git a/Task/Stack-traces/Uxntal/stack-traces.uxnatl b/Task/Stack-traces/Uxntal/stack-traces.uxnatl new file mode 100644 index 0000000000..481d2799aa --- /dev/null +++ b/Task/Stack-traces/Uxntal/stack-traces.uxnatl @@ -0,0 +1,51 @@ +%\n { 0a } +%\s { 20 } +%\0 { 00 } +%DBG { [ LIT2 -True -System/debug ] DEO } +%newline { [ LIT2 \n -Console/write ] DEO } + +|1 @True +|0e @System/debug $1 +|18 @Console/write $1 + +|100 + +foo +DBG + +BRK + +@foo ( -- ) + #c0de + ;msgs/foo print/dbg + DBG newline + bar + JMP2r + +@bar ( -- ) + #cafe + ;msgs/bar print/dbg + DBG newline + baz + JMP2r + +@baz ( -- ) + #f00d + ;msgs/baz print/dbg + DBG newline + JMP2r + +@print/str ( str* -- ) + LDAk .Console/write DEO + INC2 LDAk ?/str + POP2 JMP2r + +@print/dbg ( str* -- ) + ;msgs/inside /str + ( str* ) !/str + +@msgs [ + &inside "Inside \s "of: \s \0 + &foo "foo. \n \0 + &bar "bar. \n \0 + &baz "baz. \n \0 ] diff --git a/Task/Stack/68000-Assembly/stack-1.68000 b/Task/Stack/68000-Assembly/stack-1.68000 index 8e778da8e3..a2efe823dd 100644 --- a/Task/Stack/68000-Assembly/stack-1.68000 +++ b/Task/Stack/68000-Assembly/stack-1.68000 @@ -1,2 +1,3 @@ -LEA userStack,A0 ;initialize the user stack, points to a memory address in user RAM. Only do this once! -MOVEM.L D0-D3,-(A0) ;moves the full 32 bits of registers D0,D1,D2,D3 into the address pointed by A0, with pre-decrement +LEA userStack,A0 ;initialize the user stack, points to a memory address in user RAM. Only do this once! +MOVEM.L D0-D3,-(A0) ;moves the full 32 bits of registers D0,D1,D2,D3 into the address pointed by A0, + ;with pre-decrement diff --git a/Task/Stack/Ballerina/stack-1.ballerina b/Task/Stack/Ballerina/stack-1.ballerina new file mode 100644 index 0000000000..70a1ee5ea9 --- /dev/null +++ b/Task/Stack/Ballerina/stack-1.ballerina @@ -0,0 +1,15 @@ +import ballerina/io; + +public function main() { + int[] stack = []; + stack.push(1); + stack.push(2); + io:println("Stack contains ", stack); + io:println("Number of elements in stack = ", stack.length()); + int item = stack.pop(); + io:println(item, " popped from the stack"); + io:println("Last element is now ", stack[stack.length() - 1]); + stack.removeAll(); + io:println("Stack cleared"); + io:println("Is stack now empty? ", stack.length() == 0 ? "yes" : "no"); +} diff --git a/Task/Stack/Ballerina/stack-2.ballerina b/Task/Stack/Ballerina/stack-2.ballerina new file mode 100644 index 0000000000..19641de2d8 --- /dev/null +++ b/Task/Stack/Ballerina/stack-2.ballerina @@ -0,0 +1,53 @@ +import ballerina/io; + +class Stack { + private any[] s = []; + + function push(any a) { + self.s.push(a); + } + + function length() returns int { + return self.s.length(); + } + + function isEmpty() returns boolean { + return self.length() == 0; + } + + function pop() returns any? { + if !self.isEmpty() { + return self.s.pop(); + } + return (); + } + + function peek() returns any? { + if !self.isEmpty() { + return self.s[self.length() - 1]; + } + return (); + } + + function clear() { + self.s.removeAll(); + } + + function toString() returns string { + return self.s.toString(); + } +} + +public function main() { + Stack s = new; + s.push(1); + s.push(2); + io:println("Stack contains ", s); + io:println("Number of elements in stack = ", s.length()); + any item = s.pop(); + io:println(item, " popped from the stack"); + io:println("Last element is now ", s.peek()); + s.clear(); + io:println("Stack cleared"); + io:println("Is stack now empty? ", s.isEmpty() ? "yes" : "no"); +} diff --git a/Task/Stack/C/stack-1.c b/Task/Stack/C/stack-1.c index a8e4a1dd7c..bf4fc16a09 100644 --- a/Task/Stack/C/stack-1.c +++ b/Task/Stack/C/stack-1.c @@ -2,33 +2,37 @@ #include /* to read expanded code, run through cpp | indent -st */ -#define DECL_STACK_TYPE(type, name) \ +#define DECL_STACK_TYPE(type, name) \ typedef struct stk_##name##_t{type *buf; size_t alloc,len;}*stk_##name; \ -stk_##name stk_##name##_create(size_t init_size) { \ - stk_##name s; if (!init_size) init_size = 4; \ - s = malloc(sizeof(struct stk_##name##_t)); \ - if (!s) return 0; \ - s->buf = malloc(sizeof(type) * init_size); \ - if (!s->buf) { free(s); return 0; } \ - s->len = 0, s->alloc = init_size; \ - return s; } \ -int stk_##name##_push(stk_##name s, type item) { \ - type *tmp; \ - if (s->len >= s->alloc) { \ - tmp = realloc(s->buf, s->alloc*2*sizeof(type)); \ - if (!tmp) return -1; s->buf = tmp; \ - s->alloc *= 2; } \ - s->buf[s->len++] = item; \ - return s->len; } \ -type stk_##name##_pop(stk_##name s) { \ - type tmp; \ - if (!s->len) abort(); \ - tmp = s->buf[--s->len]; \ - if (s->len * 2 <= s->alloc && s->alloc >= 8) { \ - s->alloc /= 2; \ - s->buf = realloc(s->buf, s->alloc * sizeof(type));} \ - return tmp; } \ -void stk_##name##_delete(stk_##name s) { \ + \ +stk_##name stk_##name##_create(size_t init_size) { \ + stk_##name s; if (!init_size) init_size = 4; \ + s = malloc(sizeof(struct stk_##name##_t)); \ + if (!s) return 0; \ + s->buf = malloc(sizeof(type) * init_size); \ + if (!s->buf) { free(s); return 0; } \ + s->len = 0, s->alloc = init_size; \ + return s; } \ + \ +int stk_##name##_push(stk_##name s, type item) { \ + type *tmp; \ + if (s->len >= s->alloc) { \ + tmp = realloc(s->buf, s->alloc*2*sizeof(type)); \ + if (!tmp) return -1; s->buf = tmp; \ + s->alloc *= 2; } \ + s->buf[s->len++] = item; \ + return s->len; } \ + \ +type stk_##name##_pop(stk_##name s) { \ + type tmp; \ + if (!s->len) abort(); \ + tmp = s->buf[--s->len]; \ + if (s->len * 2 <= s->alloc && s->alloc >= 8) { \ + s->alloc /= 2; \ + s->buf = realloc(s->buf, s->alloc * sizeof(type));} \ + return tmp; } \ + \ +void stk_##name##_delete(stk_##name s) { \ free(s->buf); free(s); } #define stk_empty(s) (!(s)->len) diff --git a/Task/Stack/EasyLang/stack.easy b/Task/Stack/EasyLang/stack.easy index f0ac75cdc2..187e06459f 100644 --- a/Task/Stack/EasyLang/stack.easy +++ b/Task/Stack/EasyLang/stack.easy @@ -1,12 +1,10 @@ stack[] = [ ] -proc push v . . +proc push v . stack[] &= v . func pop . lng = len stack[] - if lng = 0 - return 0 - . + if lng = 0 : return 0 / 0 r = stack[lng] len stack[] -1 return r diff --git a/Task/Stair-climbing-puzzle/EasyLang/stair-climbing-puzzle.easy b/Task/Stair-climbing-puzzle/EasyLang/stair-climbing-puzzle.easy index afa43455fb..bbec793fc5 100644 --- a/Task/Stair-climbing-puzzle/EasyLang/stair-climbing-puzzle.easy +++ b/Task/Stair-climbing-puzzle/EasyLang/stair-climbing-puzzle.easy @@ -7,7 +7,7 @@ func step . return 0 . . -proc step_up . . +proc step_up . while step = 0 step_up . diff --git a/Task/Start-from-a-main-routine/EasyLang/start-from-a-main-routine.easy b/Task/Start-from-a-main-routine/EasyLang/start-from-a-main-routine.easy index 048d3ce437..502b4c8879 100644 --- a/Task/Start-from-a-main-routine/EasyLang/start-from-a-main-routine.easy +++ b/Task/Start-from-a-main-routine/EasyLang/start-from-a-main-routine.easy @@ -1,4 +1,4 @@ -proc main . . +proc main . print "Hello from main!" . main diff --git a/Task/State-name-puzzle/JavaScript/state-name-puzzle.js b/Task/State-name-puzzle/JavaScript/state-name-puzzle.js new file mode 100644 index 0000000000..35970b4883 --- /dev/null +++ b/Task/State-name-puzzle/JavaScript/state-name-puzzle.js @@ -0,0 +1,76 @@ +const states = ["Alabama", "Alaska", "Arizona", "Arkansas", + "California", "Colorado", "Connecticut", + "Delaware", + "Florida", "Georgia", "Hawaii", + "Idaho", "Illinois", "Indiana", "Iowa", + "Kansas", "Kentucky", "Louisiana", + "Maine", "Maryland", "Massachusetts", "Michigan", + "Minnesota", "Mississippi", "Missouri", "Montana", + "Nebraska", "Nevada", "New Hampshire", "New Jersey", + "New Mexico", "New York", "North Carolina", "North Dakota", + "Ohio", "Oklahoma", "Oregon", + "Pennsylvania", "Rhode Island", + "South Carolina", "South Dakota", "Tennessee", "Texas", + "Utah", "Vermont", "Virginia", + "Washington", "West Virginia", "Wisconsin", "Wyoming"]; + +function play(states) { + console.log(states.length, "states:"); + + // get list of unique state names + const set = new Set(states); + + // make parallel arrays for unique state names and letter histograms + const s = Array.from(set); + const h = Array(s.length).fill().map(() => Array(26).fill(0)); + + // fill histograms + s.forEach((state, i) => { + for (const c of state) { + const charCode = c.toLowerCase().charCodeAt(0) - 'a'.charCodeAt(0); + if (charCode >= 0 && charCode < 26) { + h[i][charCode]++; + } + } + }); + + // use map to find matches. map key is sum of histograms of + // two different states. map value is indexes of the two states. + const m = new Map(); + + for (let i1 = 0; i1 < h.length; i1++) { + const h1 = h[i1]; + for (let i2 = i1 + 1; i2 < h.length; i2++) { + // sum histograms + const b = Array(26).fill(0); + for (let i = 0; i < 26; i++) { + b[i] = h1[i] + h[i2][i]; + } + + const k = b.join(','); // make key from buffer + + // Check for existing pairs with the same histogram sum + if (m.has(k)) { + const pairs = m.get(k); + // Check each pair against current pair + for (const pair of pairs) { + if (i1 !== pair.i1 && i1 !== pair.i2 && i2 !== pair.i1 && i2 !== pair.i2) { + console.log(`${s[i1]}, ${s[i2]} = ${s[pair.i1]}, ${s[pair.i2]}`); + } + } + } else { + m.set(k, []); + } + + // store this pair in the map whether printed or not + m.get(k).push({ i1, i2 }); + } + } +} + +function main() { + play(states); + play([...states, "New Kory", "Wen Kory", "York New", "Kory New", "New Kory"]); +} + +main(); diff --git a/Task/Statistics-Basic/Ballerina/statistics-basic.ballerina b/Task/Statistics-Basic/Ballerina/statistics-basic.ballerina new file mode 100644 index 0000000000..9ab74931d9 --- /dev/null +++ b/Task/Statistics-Basic/Ballerina/statistics-basic.ballerina @@ -0,0 +1,44 @@ +import ballerina/io; +import ballerina/random; + +function mean(float[] a) returns float { + return float:sum(...a) / a.length(); +} + +function popStdDev(float[] a) returns float { + float m = mean(a); + var sumSq = function(float total, float next) returns float { + return total + next * next; + }; + return (a.reduce(sumSq, 0.0) / a.length() - m * m).sqrt(); +} + +function repeat(string s, int times) returns string { + string r = ""; + foreach int i in 1...times { r += s; } + return r; +} + +public function main() { + foreach int i in [100, 1000, 10000] { + float[] a = []; + a.setLength(i); + foreach int j in 0..(e*10).floor(); + sums[f] += 1; + } + foreach int j in 0...8 { + sums[j] = ((sums[j] / scale).round()); + io:println(` 0.${j} - 0.${j+1}: `, repeat("*", sums[j])); + } + sums[9] = 100 - int:sum(...sums.slice(0, 9)); + io:println(" 0.9 - 1.0: ", repeat("*", sums[9]), "\n"); + } +} diff --git a/Task/Statistics-Basic/EasyLang/statistics-basic.easy b/Task/Statistics-Basic/EasyLang/statistics-basic.easy index d0ce26771f..c3518514b1 100644 --- a/Task/Statistics-Basic/EasyLang/statistics-basic.easy +++ b/Task/Statistics-Basic/EasyLang/statistics-basic.easy @@ -1,24 +1,18 @@ global list[] . -proc mklist n . . +proc mklist n . list[] = [ ] - for i = 1 to n - list[] &= randomf - . + for i = 1 to n : list[] &= randomf . func mean . - for v in list[] - sum += v - . + for v in list[] : sum += v return sum / len list[] . func stddev . avg = mean - for v in list[] - squares += (avg - v) * (avg - v) - . + for v in list[] : squares += (avg - v) * (avg - v) return sqrt (squares / len list[]) . -proc histo . . +proc histo . len hist[] 10 for v in list[] ind = floor (v * 10) + 1 @@ -30,8 +24,8 @@ proc histo . . print v & " " & s$ . . -numfmt 4 5 -proc stats size . . +numfmt 5 4 +proc stats size . mklist size print "Size: " & size print "Mean: " & mean diff --git a/Task/Steffensens-method/EasyLang/steffensens-method.easy b/Task/Steffensens-method/EasyLang/steffensens-method.easy index 0dddcc4f9c..e27cf9fd42 100644 --- a/Task/Steffensens-method/EasyLang/steffensens-method.easy +++ b/Task/Steffensens-method/EasyLang/steffensens-method.easy @@ -28,18 +28,16 @@ func aitken p0 . func steffAitken p0 tol maxiter . for i to maxiter p = aitken p0 - if abs (p - p0) < tol - return p - . + if abs (p - p0) < tol : return p p0 = p . return number "nan" . for i to 11 - numfmt 1 0 + numfmt 0 1 write "t0 = " & t0 & " : " t = steffAitken t0 0.00000001 1000 - numfmt 3 0 + numfmt 0 3 if t <> t # nan print "no answer" diff --git a/Task/Steffensens-method/Rust/steffensens-method.rs b/Task/Steffensens-method/Rust/steffensens-method.rs new file mode 100644 index 0000000000..855b016f7b --- /dev/null +++ b/Task/Steffensens-method/Rust/steffensens-method.rs @@ -0,0 +1,69 @@ +use std::f64; + +fn aitken(f: fn(f64) -> f64, p0: f64) -> f64 { + let p1 = f(p0); + let p2 = f(p1); + let p1m0 = p1 - p0; + p0 - p1m0 * p1m0 / (p2 - 2.0 * p1 + p0) +} + +fn steffensen_aitken(f: fn(f64) -> f64, pinit: f64, tol: f64, maxiter: i32) -> f64 { + let mut p0 = pinit; + let mut p = aitken(f, p0); + let mut iter = 1; + while (p - p0).abs() > tol && iter < maxiter { + p0 = p; + p = aitken(f, p0); + iter += 1; + } + if (p - p0).abs() > tol { + f64::NAN + } else { + p + } +} + +fn de_casteljau(c0: f64, c1: f64, c2: f64, t: f64) -> f64 { + let s = 1.0 - t; + let c01 = s * c0 + t * c1; + let c12 = s * c1 + t * c2; + s * c01 + t * c12 +} + +fn x_convex_left_parabola(t: f64) -> f64 { + de_casteljau(2.0, -8.0, 2.0, t) +} + +fn y_convex_right_parabola(t: f64) -> f64 { + de_casteljau(1.0, 2.0, 3.0, t) +} + +fn implicit_equation(x: f64, y: f64) -> f64 { + 5.0 * x * x + y - 5.0 +} + +fn f(t: f64) -> f64 { + let x = x_convex_left_parabola(t); + let y = y_convex_right_parabola(t); + implicit_equation(x, y) + t +} + +fn main() { + let mut t0 = 0.0; + for _i in 0..11 { + print!("t0 = {:.1} : ", t0); + let t = steffensen_aitken(f, t0, 0.00000001, 1000); + if t.is_nan() { + println!("no answer"); + } else { + let x = x_convex_left_parabola(t); + let y = y_convex_right_parabola(t); + if implicit_equation(x, y).abs() <= 0.000001 { + println!("intersection at ({}, {})", x, y); + } else { + println!("spurious solution"); + } + } + t0 += 0.1; + } +} diff --git a/Task/Stem-and-leaf-plot/EasyLang/stem-and-leaf-plot.easy b/Task/Stem-and-leaf-plot/EasyLang/stem-and-leaf-plot.easy index c931ab42d8..503f34c6ca 100644 --- a/Task/Stem-and-leaf-plot/EasyLang/stem-and-leaf-plot.easy +++ b/Task/Stem-and-leaf-plot/EasyLang/stem-and-leaf-plot.easy @@ -1,24 +1,19 @@ -proc sort . d[] . - for i = 1 to len d[] - 1 - for j = i + 1 to len d[] - if d[j] < d[i] - swap d[j] d[i] - . - . +proc sort &d[] . + for i = 1 to len d[] - 1 : for j = i + 1 to len d[] + if d[j] < d[i] : swap d[j] d[i] . . x[] = [ 12 127 28 42 39 113 42 18 44 118 44 37 113 124 37 48 127 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 114 126 53 114 96 25 109 7 31 141 46 13 27 43 117 116 27 7 68 40 31 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116 146 ] sort x[] -numfmt 0 2 +numfmt 2 0 i = x[1] div 10 - 1 for j = 1 to len x[] d = x[j] div 10 while d > i i += 1 - if j > 1 - print "" - . + if j > 1 : print "" write i & " |" . write x[j] mod 10 . +print "" diff --git a/Task/Stem-and-leaf-plot/Uiua/stem-and-leaf-plot.uiua b/Task/Stem-and-leaf-plot/Uiua/stem-and-leaf-plot.uiua index 1feac8d08e..726fd51097 100644 --- a/Task/Stem-and-leaf-plot/Uiua/stem-and-leaf-plot.uiua +++ b/Task/Stem-and-leaf-plot/Uiua/stem-and-leaf-plot.uiua @@ -6,5 +6,5 @@ 27 106 33 117 116 111 40 119 47 105 57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116] -°⊏⊕(□⊏⍏.◿10)⌊÷10. +°⊏⊕(□⍆◿10)⌊⊸÷10 ∵◇(&p$"_ | _"⬚@ ↙¯2°⋕⊙/$"_ _") diff --git a/Task/Stern-Brocot-sequence/EasyLang/stern-brocot-sequence.easy b/Task/Stern-Brocot-sequence/EasyLang/stern-brocot-sequence.easy index 47fda5ad77..790fbb9b7a 100644 --- a/Task/Stern-Brocot-sequence/EasyLang/stern-brocot-sequence.easy +++ b/Task/Stern-Brocot-sequence/EasyLang/stern-brocot-sequence.easy @@ -1,5 +1,5 @@ global sb[] . -proc sternbrocot n . . +proc sternbrocot n . sb[] = [ 1 1 ] pos = 2 repeat diff --git a/Task/Strassens-algorithm/00-TASK.txt b/Task/Strassens-algorithm/00-TASK.txt index 1ebb38df9e..6c275f7943 100644 --- a/Task/Strassens-algorithm/00-TASK.txt +++ b/Task/Strassens-algorithm/00-TASK.txt @@ -18,3 +18,5 @@ While practical implementations of Strassen's algorithm usually switch to standa :* [[wp:Strassen algorithm|Wikipedia article]]

+ + diff --git a/Task/Strassens-algorithm/C++/strassens-algorithm.cpp b/Task/Strassens-algorithm/C++/strassens-algorithm.cpp new file mode 100644 index 0000000000..27e94e3bb6 --- /dev/null +++ b/Task/Strassens-algorithm/C++/strassens-algorithm.cpp @@ -0,0 +1,248 @@ +#include +#include +#include +#include +#include +#include + +class Matrix { +public: + std::vector> data; + size_t rows; + size_t cols; + + Matrix(const std::vector>& data) : data(data) { + rows = data.size(); + cols = (rows > 0) ? data[0].size() : 0; + } + + size_t getRows() const { + return rows; + } + + size_t getCols() const { + return cols; + } + + void validateDimensions(const Matrix& other) const { + if (getRows() != other.getRows() || getCols() != other.getCols()) { + throw std::runtime_error("Matrices must have the same dimensions."); + } + } + + void validateMultiplication(const Matrix& other) const { + if (getCols() != other.getRows()) { + throw std::runtime_error("Cannot multiply these matrices."); + } + } + + void validateSquarePowerOfTwo() const { + if (getRows() != getCols()) { + throw std::runtime_error("Matrix must be square."); + } + if (getRows() == 0 || (getRows() & (getRows() - 1)) != 0) { + throw std::runtime_error("Size of matrix must be a power of two."); + } + } + + Matrix operator+(const Matrix& other) const { + validateDimensions(other); + + std::vector> result_data(rows, std::vector(cols)); + for (size_t i = 0; i < rows; ++i) { + for (size_t j = 0; j < cols; ++j) { + result_data[i][j] = data[i][j] + other.data[i][j]; + } + } + + return Matrix(result_data); + } + + Matrix operator-(const Matrix& other) const { + validateDimensions(other); + + std::vector> result_data(rows, std::vector(cols)); + for (size_t i = 0; i < rows; ++i) { + for (size_t j = 0; j < cols; ++j) { + result_data[i][j] = data[i][j] - other.data[i][j]; + } + } + + return Matrix(result_data); + } + + Matrix operator*(const Matrix& other) const { + validateMultiplication(other); + + std::vector> result_data(rows, std::vector(other.cols)); + for (size_t i = 0; i < rows; ++i) { + for (size_t j = 0; j < other.cols; ++j) { + double sum = 0.0; + for (size_t k = 0; k < other.rows; ++k) { + sum += data[i][k] * other.data[k][j]; + } + result_data[i][j] = sum; + } + } + + return Matrix(result_data); + } + + friend std::ostream& operator<<(std::ostream& os, const Matrix& matrix) { + for (const auto& row : matrix.data) { + os << "["; + for (size_t i = 0; i < row.size(); ++i) { + os << row[i]; + if (i < row.size() - 1) { + os << ", "; + } + } + os << "]" << std::endl; + } + return os; + } + + std::string toStringWithPrecision(size_t p) const { + std::stringstream ss; + ss << std::fixed << std::setprecision(p); + double pow = std::pow(10.0, p); + + for (const auto& row : data) { + ss << "["; + for (size_t i = 0; i < row.size(); ++i) { + double r = std::round(row[i] * pow) / pow; + std::string formatted = ss.str(); + ss.str(std::string()); + ss << r; + formatted = ss.str(); + + if (formatted == "-0") { + ss.str(std::string()); + ss << "0"; + formatted = ss.str(); + } + + ss.str(std::string()); + ss << formatted; + + if (i < row.size() - 1) { + ss << ", "; + } + } + ss << "]" << std::endl; + + } + return ss.str(); + } + + static std::array, 4> params(size_t r, size_t c) { + return { + {{{0, r, 0, c, 0, 0}}, + {{0, r, c, 2 * c, 0, c}}, + {{r, 2 * r, 0, c, r, 0}}, + {{r, 2 * r, c, 2 * c, r, c}}} + }; + } + + std::array toQuarters() const { + size_t r = getRows() / 2; + size_t c = getCols() / 2; + auto p = Matrix::params(r, c); + std::array quarters = { + Matrix(std::vector>(r, std::vector(c, 0.0))), + Matrix(std::vector>(r, std::vector(c, 0.0))), + Matrix(std::vector>(r, std::vector(c, 0.0))), + Matrix(std::vector>(r, std::vector(c, 0.0))) + }; + + for (size_t k = 0; k < 4; ++k) { + std::vector> q_data(r, std::vector(c)); + for (size_t i = p[k][0]; i < p[k][1]; ++i) { + for (size_t j = p[k][2]; j < p[k][3]; ++j) { + q_data[i - p[k][4]][j - p[k][5]] = data[i][j]; + } + } + quarters[k] = Matrix(q_data); + } + + return quarters; + } + + static Matrix fromQuarters(const std::array& q) { + size_t r = q[0].getRows(); + size_t c = q[0].getCols(); + auto p = Matrix::params(r, c); + size_t rows = r * 2; + size_t cols = c * 2; + + std::vector> m_data(rows, std::vector(cols, 0.0)); + + for (size_t k = 0; k < 4; ++k) { + for (size_t i = p[k][0]; i < p[k][1]; ++i) { + for (size_t j = p[k][2]; j < p[k][3]; ++j) { + m_data[i][j] = q[k].data[i - p[k][4]][j - p[k][5]]; + } + } + } + + return Matrix(m_data); + } + + Matrix strassen(const Matrix& other) const { + validateSquarePowerOfTwo(); + other.validateSquarePowerOfTwo(); + if (getRows() != other.getRows() || getCols() != other.getCols()) { + throw std::runtime_error("Matrices must be square and of equal size for Strassen multiplication."); + } + + if (getRows() == 1) { + return *this * other; + } + + auto qa = toQuarters(); + auto qb = other.toQuarters(); + + Matrix p1 = (qa[1] - qa[3]).strassen(qb[2] + qb[3]); + Matrix p2 = (qa[0] + qa[3]).strassen(qb[0] + qb[3]); + Matrix p3 = (qa[0] - qa[2]).strassen(qb[0] + qb[1]); + Matrix p4 = (qa[0] + qa[1]).strassen(qb[3]); + Matrix p5 = qa[0].strassen(qb[1] - qb[3]); + Matrix p6 = qa[3].strassen(qb[2] - qb[0]); + Matrix p7 = (qa[2] + qa[3]).strassen(qb[0]); + + std::array q = { + Matrix(std::vector>(qa[0].getRows(), std::vector(qa[0].getCols(), 0.0))), + Matrix(std::vector>(qa[0].getRows(), std::vector(qa[0].getCols(), 0.0))), + Matrix(std::vector>(qa[0].getRows(), std::vector(qa[0].getCols(), 0.0))), + Matrix(std::vector>(qa[0].getRows(), std::vector(qa[0].getCols(), 0.0))) + }; + + q[0] = p1 + p2 - p4 + p6; + q[1] = p4 + p5; + q[2] = p6 + p7; + q[3] = p2 - p3 + p5 - p7; + + return Matrix::fromQuarters(q); + } +}; + +int main() { + Matrix a({ {1.0, 2.0}, {3.0, 4.0} }); + Matrix b({ {5.0, 6.0}, {7.0, 8.0} }); + Matrix c({ {1.0, 1.0, 1.0, 1.0}, {2.0, 4.0, 8.0, 16.0}, {3.0, 9.0, 27.0, 81.0}, {4.0, 16.0, 64.0, 256.0} }); + Matrix d({ {4.0, -3.0, 4.0 / 3.0, -1.0 / 4.0}, {-13.0 / 3.0, 19.0 / 4.0, -7.0 / 3.0, 11.0 / 24.0}, {3.0 / 2.0, -2.0, 7.0 / 6.0, -1.0 / 4.0}, {-1.0 / 6.0, 1.0 / 4.0, -1.0 / 6.0, 1.0 / 24.0} }); + Matrix e({ {1.0, 2.0, 3.0, 4.0}, {5.0, 6.0, 7.0, 8.0}, {9.0, 10.0, 11.0, 12.0}, {13.0, 14.0, 15.0, 16.0} }); + Matrix f({ {1.0, 0.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 0.0, 1.0} }); + + std::cout << "Using 'normal' matrix multiplication:" << std::endl; + std::cout << " a * b = " << a * b << std::endl; + std::cout << " c * d = " << (c * d).toStringWithPrecision(6) << std::endl; + std::cout << " e * f = " << e * f << std::endl; + + std::cout << "\nUsing 'Strassen' matrix multiplication:" << std::endl; + std::cout << " a * b = " << a.strassen(b) << std::endl; + std::cout << " c * d = " << c.strassen(d).toStringWithPrecision(6) << std::endl; + std::cout << " e * f = " << e.strassen(f) << std::endl; + + return 0; +} diff --git a/Task/Strassens-algorithm/C-sharp/strassens-algorithm.cs b/Task/Strassens-algorithm/C-sharp/strassens-algorithm.cs new file mode 100644 index 0000000000..bc170318d1 --- /dev/null +++ b/Task/Strassens-algorithm/C-sharp/strassens-algorithm.cs @@ -0,0 +1,323 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +class Matrix +{ + public List> data; + public int rows; + public int cols; + + public Matrix(List> data) + { + this.data = data; + rows = data.Count; + cols = (rows > 0) ? data[0].Count : 0; + } + + public int GetRows() + { + return rows; + } + + public int GetCols() + { + return cols; + } + + public void ValidateDimensions(Matrix other) + { + if (GetRows() != other.GetRows() || GetCols() != other.GetCols()) + { + throw new InvalidOperationException("Matrices must have the same dimensions."); + } + } + + public void ValidateMultiplication(Matrix other) + { + if (GetCols() != other.GetRows()) + { + throw new InvalidOperationException("Cannot multiply these matrices."); + } + } + + public void ValidateSquarePowerOfTwo() + { + if (GetRows() != GetCols()) + { + throw new InvalidOperationException("Matrix must be square."); + } + if (GetRows() == 0 || (GetRows() & (GetRows() - 1)) != 0) + { + throw new InvalidOperationException("Size of matrix must be a power of two."); + } + } + + public static Matrix operator +(Matrix a, Matrix b) + { + a.ValidateDimensions(b); + + List> resultData = new List>(); + for (int i = 0; i < a.rows; ++i) + { + List row = new List(); + for (int j = 0; j < a.cols; ++j) + { + row.Add(a.data[i][j] + b.data[i][j]); + } + resultData.Add(row); + } + + return new Matrix(resultData); + } + + public static Matrix operator -(Matrix a, Matrix b) + { + a.ValidateDimensions(b); + + List> resultData = new List>(); + for (int i = 0; i < a.rows; ++i) + { + List row = new List(); + for (int j = 0; j < a.cols; ++j) + { + row.Add(a.data[i][j] - b.data[i][j]); + } + resultData.Add(row); + } + + return new Matrix(resultData); + } + + public static Matrix operator *(Matrix a, Matrix b) + { + a.ValidateMultiplication(b); + + List> resultData = new List>(); + for (int i = 0; i < a.rows; ++i) + { + List row = new List(); + for (int j = 0; j < b.cols; ++j) + { + double sum = 0.0; + for (int k = 0; k < b.rows; ++k) + { + sum += a.data[i][k] * b.data[k][j]; + } + row.Add(sum); + } + resultData.Add(row); + } + + return new Matrix(resultData); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + foreach (var row in data) + { + sb.Append("["); + for (int i = 0; i < row.Count; ++i) + { + sb.Append(row[i]); + if (i < row.Count - 1) + { + sb.Append(", "); + } + } + sb.AppendLine("]"); + } + return sb.ToString(); + } + + public string ToStringWithPrecision(int p) + { + StringBuilder sb = new StringBuilder(); + double pow = Math.Pow(10.0, p); + + foreach (var row in data) + { + sb.Append("["); + for (int i = 0; i < row.Count; ++i) + { + double r = Math.Round(row[i] * pow) / pow; + string formatted = r.ToString($"F{p}"); + + if (formatted == "-0" + (p > 0 ? "." + new string('0', p) : "")) + { + formatted = "0" + (p > 0 ? "." + new string('0', p) : ""); + } + + sb.Append(formatted); + + if (i < row.Count - 1) + { + sb.Append(", "); + } + } + sb.AppendLine("]"); + } + return sb.ToString(); + } + + private static int[,] GetParams(int r, int c) + { + return new int[,] + { + {0, r, 0, c, 0, 0}, + {0, r, c, 2 * c, 0, c}, + {r, 2 * r, 0, c, r, 0}, + {r, 2 * r, c, 2 * c, r, c} + }; + } + + public Matrix[] ToQuarters() + { + int r = GetRows() / 2; + int c = GetCols() / 2; + int[,] p = GetParams(r, c); + Matrix[] quarters = new Matrix[4]; + + for (int k = 0; k < 4; ++k) + { + List> qData = new List>(); + for (int i = 0; i < r; i++) + { + List row = new List(); + for (int j = 0; j < c; j++) + { + row.Add(0.0); + } + qData.Add(row); + } + + for (int i = p[k, 0]; i < p[k, 1]; ++i) + { + for (int j = p[k, 2]; j < p[k, 3]; ++j) + { + qData[i - p[k, 4]][j - p[k, 5]] = data[i][j]; + } + } + quarters[k] = new Matrix(qData); + } + + return quarters; + } + + public static Matrix FromQuarters(Matrix[] q) + { + int r = q[0].GetRows(); + int c = q[0].GetCols(); + int[,] p = GetParams(r, c); + int rows = r * 2; + int cols = c * 2; + + List> mData = new List>(); + for (int i = 0; i < rows; i++) + { + List row = new List(); + for (int j = 0; j < cols; j++) + { + row.Add(0.0); + } + mData.Add(row); + } + + for (int k = 0; k < 4; ++k) + { + for (int i = p[k, 0]; i < p[k, 1]; ++i) + { + for (int j = p[k, 2]; j < p[k, 3]; ++j) + { + mData[i][j] = q[k].data[i - p[k, 4]][j - p[k, 5]]; + } + } + } + + return new Matrix(mData); + } + + public Matrix Strassen(Matrix other) + { + ValidateSquarePowerOfTwo(); + other.ValidateSquarePowerOfTwo(); + if (GetRows() != other.GetRows() || GetCols() != other.GetCols()) + { + throw new InvalidOperationException("Matrices must be square and of equal size for Strassen multiplication."); + } + + if (GetRows() == 1) + { + return this * other; + } + + Matrix[] qa = ToQuarters(); + Matrix[] qb = other.ToQuarters(); + + Matrix p1 = (qa[1] - qa[3]).Strassen(qb[2] + qb[3]); + Matrix p2 = (qa[0] + qa[3]).Strassen(qb[0] + qb[3]); + Matrix p3 = (qa[0] - qa[2]).Strassen(qb[0] + qb[1]); + Matrix p4 = (qa[0] + qa[1]).Strassen(qb[3]); + Matrix p5 = qa[0].Strassen(qb[1] - qb[3]); + Matrix p6 = qa[3].Strassen(qb[2] - qb[0]); + Matrix p7 = (qa[2] + qa[3]).Strassen(qb[0]); + + Matrix[] q = new Matrix[4]; + + q[0] = p1 + p2 - p4 + p6; + q[1] = p4 + p5; + q[2] = p6 + p7; + q[3] = p2 - p3 + p5 - p7; + + return FromQuarters(q); + } +} + +class Program +{ + static void Main(string[] args) + { + Matrix a = new Matrix(new List> { new List { 1.0, 2.0 }, new List { 3.0, 4.0 } }); + Matrix b = new Matrix(new List> { new List { 5.0, 6.0 }, new List { 7.0, 8.0 } }); + Matrix c = new Matrix(new List> + { + new List { 1.0, 1.0, 1.0, 1.0 }, + new List { 2.0, 4.0, 8.0, 16.0 }, + new List { 3.0, 9.0, 27.0, 81.0 }, + new List { 4.0, 16.0, 64.0, 256.0 } + }); + Matrix d = new Matrix(new List> + { + new List { 4.0, -3.0, 4.0 / 3.0, -1.0 / 4.0 }, + new List { -13.0 / 3.0, 19.0 / 4.0, -7.0 / 3.0, 11.0 / 24.0 }, + new List { 3.0 / 2.0, -2.0, 7.0 / 6.0, -1.0 / 4.0 }, + new List { -1.0 / 6.0, 1.0 / 4.0, -1.0 / 6.0, 1.0 / 24.0 } + }); + Matrix e = new Matrix(new List> + { + new List { 1.0, 2.0, 3.0, 4.0 }, + new List { 5.0, 6.0, 7.0, 8.0 }, + new List { 9.0, 10.0, 11.0, 12.0 }, + new List { 13.0, 14.0, 15.0, 16.0 } + }); + Matrix f = new Matrix(new List> + { + new List { 1.0, 0.0, 0.0, 0.0 }, + new List { 0.0, 1.0, 0.0, 0.0 }, + new List { 0.0, 0.0, 1.0, 0.0 }, + new List { 0.0, 0.0, 0.0, 1.0 } + }); + + Console.WriteLine("Using 'normal' matrix multiplication:"); + Console.WriteLine($" a * b = {a * b}"); + Console.WriteLine($" c * d = {(c * d).ToStringWithPrecision(6)}"); + Console.WriteLine($" e * f = {e * f}"); + + Console.WriteLine("\nUsing 'Strassen' matrix multiplication:"); + Console.WriteLine($" a * b = {a.Strassen(b)}"); + Console.WriteLine($" c * d = {c.Strassen(d).ToStringWithPrecision(6)}"); + Console.WriteLine($" e * f = {e.Strassen(f)}"); + } +} diff --git a/Task/Strassens-algorithm/Java/strassens-algorithm.java b/Task/Strassens-algorithm/Java/strassens-algorithm.java new file mode 100644 index 0000000000..9fed8e2eb4 --- /dev/null +++ b/Task/Strassens-algorithm/Java/strassens-algorithm.java @@ -0,0 +1,281 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +class Matrix { + public List> data; + public int rows; + public int cols; + + public Matrix(List> data) { + this.data = data; + rows = data.size(); + cols = (rows > 0) ? data.get(0).size() : 0; + } + + public int getRows() { + return rows; + } + + public int getCols() { + return cols; + } + + public void validateDimensions(Matrix other) { + if (getRows() != other.getRows() || getCols() != other.getCols()) { + throw new RuntimeException("Matrices must have the same dimensions."); + } + } + + public void validateMultiplication(Matrix other) { + if (getCols() != other.getRows()) { + throw new RuntimeException("Cannot multiply these matrices."); + } + } + + public void validateSquarePowerOfTwo() { + if (getRows() != getCols()) { + throw new RuntimeException("Matrix must be square."); + } + if (getRows() == 0 || (getRows() & (getRows() - 1)) != 0) { + throw new RuntimeException("Size of matrix must be a power of two."); + } + } + + public Matrix add(Matrix other) { + validateDimensions(other); + + List> resultData = new ArrayList<>(); + for (int i = 0; i < rows; ++i) { + List row = new ArrayList<>(); + for (int j = 0; j < cols; ++j) { + row.add(data.get(i).get(j) + other.data.get(i).get(j)); + } + resultData.add(row); + } + + return new Matrix(resultData); + } + + public Matrix subtract(Matrix other) { + validateDimensions(other); + + List> resultData = new ArrayList<>(); + for (int i = 0; i < rows; ++i) { + List row = new ArrayList<>(); + for (int j = 0; j < cols; ++j) { + row.add(data.get(i).get(j) - other.data.get(i).get(j)); + } + resultData.add(row); + } + + return new Matrix(resultData); + } + + public Matrix multiply(Matrix other) { + validateMultiplication(other); + + List> resultData = new ArrayList<>(); + for (int i = 0; i < rows; ++i) { + List row = new ArrayList<>(); + for (int j = 0; j < other.cols; ++j) { + double sum = 0.0; + for (int k = 0; k < other.rows; ++k) { + sum += data.get(i).get(k) * other.data.get(k).get(j); + } + row.add(sum); + } + resultData.add(row); + } + + return new Matrix(resultData); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (List row : data) { + sb.append("["); + for (int i = 0; i < row.size(); ++i) { + sb.append(row.get(i)); + if (i < row.size() - 1) { + sb.append(", "); + } + } + sb.append("]\n"); + } + return sb.toString(); + } + + public String toStringWithPrecision(int p) { + StringBuilder sb = new StringBuilder(); + double pow = Math.pow(10.0, p); + + for (List row : data) { + sb.append("["); + for (int i = 0; i < row.size(); ++i) { + double r = Math.round(row.get(i) * pow) / pow; + String formatted = String.format("%." + p + "f", r); + + if (formatted.equals("-0" + (p > 0 ? "." + "0".repeat(p) : ""))) { + formatted = "0" + (p > 0 ? "." + "0".repeat(p) : ""); + } + + sb.append(formatted); + + if (i < row.size() - 1) { + sb.append(", "); + } + } + sb.append("]\n"); + } + return sb.toString(); + } + + private static int[][] getParams(int r, int c) { + return new int[][] { + {0, r, 0, c, 0, 0}, + {0, r, c, 2 * c, 0, c}, + {r, 2 * r, 0, c, r, 0}, + {r, 2 * r, c, 2 * c, r, c} + }; + } + + public Matrix[] toQuarters() { + int r = getRows() / 2; + int c = getCols() / 2; + int[][] p = getParams(r, c); + Matrix[] quarters = new Matrix[4]; + + for (int k = 0; k < 4; ++k) { + List> qData = new ArrayList<>(); + for (int i = 0; i < r; i++) { + List row = new ArrayList<>(); + for (int j = 0; j < c; j++) { + row.add(0.0); + } + qData.add(row); + } + + for (int i = p[k][0]; i < p[k][1]; ++i) { + for (int j = p[k][2]; j < p[k][3]; ++j) { + qData.get(i - p[k][4]).set(j - p[k][5], data.get(i).get(j)); + } + } + quarters[k] = new Matrix(qData); + } + + return quarters; + } + + public static Matrix fromQuarters(Matrix[] q) { + int r = q[0].getRows(); + int c = q[0].getCols(); + int[][] p = getParams(r, c); + int rows = r * 2; + int cols = c * 2; + + List> mData = new ArrayList<>(); + for (int i = 0; i < rows; i++) { + List row = new ArrayList<>(); + for (int j = 0; j < cols; j++) { + row.add(0.0); + } + mData.add(row); + } + + for (int k = 0; k < 4; ++k) { + for (int i = p[k][0]; i < p[k][1]; ++i) { + for (int j = p[k][2]; j < p[k][3]; ++j) { + mData.get(i).set(j, q[k].data.get(i - p[k][4]).get(j - p[k][5])); + } + } + } + + return new Matrix(mData); + } + + public Matrix strassen(Matrix other) { + validateSquarePowerOfTwo(); + other.validateSquarePowerOfTwo(); + if (getRows() != other.getRows() || getCols() != other.getCols()) { + throw new RuntimeException("Matrices must be square and of equal size for Strassen multiplication."); + } + + if (getRows() == 1) { + return this.multiply(other); + } + + Matrix[] qa = toQuarters(); + Matrix[] qb = other.toQuarters(); + + Matrix p1 = qa[1].subtract(qa[3]).strassen(qb[2].add(qb[3])); + Matrix p2 = qa[0].add(qa[3]).strassen(qb[0].add(qb[3])); + Matrix p3 = qa[0].subtract(qa[2]).strassen(qb[0].add(qb[1])); + Matrix p4 = qa[0].add(qa[1]).strassen(qb[3]); + Matrix p5 = qa[0].strassen(qb[1].subtract(qb[3])); + Matrix p6 = qa[3].strassen(qb[2].subtract(qb[0])); + Matrix p7 = qa[2].add(qa[3]).strassen(qb[0]); + + Matrix[] q = new Matrix[4]; + + q[0] = p1.add(p2).subtract(p4).add(p6); + q[1] = p4.add(p5); + q[2] = p6.add(p7); + q[3] = p2.subtract(p3).add(p5).subtract(p7); + + return fromQuarters(q); + } +} + +public class Main{ + public static void main(String[] args) { + List> aData = new ArrayList<>(); + aData.add(Arrays.asList(1.0, 2.0)); + aData.add(Arrays.asList(3.0, 4.0)); + Matrix a = new Matrix(aData); + + List> bData = new ArrayList<>(); + bData.add(Arrays.asList(5.0, 6.0)); + bData.add(Arrays.asList(7.0, 8.0)); + Matrix b = new Matrix(bData); + + List> cData = new ArrayList<>(); + cData.add(Arrays.asList(1.0, 1.0, 1.0, 1.0)); + cData.add(Arrays.asList(2.0, 4.0, 8.0, 16.0)); + cData.add(Arrays.asList(3.0, 9.0, 27.0, 81.0)); + cData.add(Arrays.asList(4.0, 16.0, 64.0, 256.0)); + Matrix c = new Matrix(cData); + + List> dData = new ArrayList<>(); + dData.add(Arrays.asList(4.0, -3.0, 4.0 / 3.0, -1.0 / 4.0)); + dData.add(Arrays.asList(-13.0 / 3.0, 19.0 / 4.0, -7.0 / 3.0, 11.0 / 24.0)); + dData.add(Arrays.asList(3.0 / 2.0, -2.0, 7.0 / 6.0, -1.0 / 4.0)); + dData.add(Arrays.asList(-1.0 / 6.0, 1.0 / 4.0, -1.0 / 6.0, 1.0 / 24.0)); + Matrix d = new Matrix(dData); + + List> eData = new ArrayList<>(); + eData.add(Arrays.asList(1.0, 2.0, 3.0, 4.0)); + eData.add(Arrays.asList(5.0, 6.0, 7.0, 8.0)); + eData.add(Arrays.asList(9.0, 10.0, 11.0, 12.0)); + eData.add(Arrays.asList(13.0, 14.0, 15.0, 16.0)); + Matrix e = new Matrix(eData); + + List> fData = new ArrayList<>(); + fData.add(Arrays.asList(1.0, 0.0, 0.0, 0.0)); + fData.add(Arrays.asList(0.0, 1.0, 0.0, 0.0)); + fData.add(Arrays.asList(0.0, 0.0, 1.0, 0.0)); + fData.add(Arrays.asList(0.0, 0.0, 0.0, 1.0)); + Matrix f = new Matrix(fData); + + System.out.println("Using 'normal' matrix multiplication:"); + System.out.println(" a * b = " + a.multiply(b)); + System.out.println(" c * d = " + c.multiply(d).toStringWithPrecision(6)); + System.out.println(" e * f = " + e.multiply(f)); + + System.out.println("\nUsing 'Strassen' matrix multiplication:"); + System.out.println(" a * b = " + a.strassen(b)); + System.out.println(" c * d = " + c.strassen(d).toStringWithPrecision(6)); + System.out.println(" e * f = " + e.strassen(f)); + } +} diff --git a/Task/Strassens-algorithm/JavaScript/strassens-algorithm-1.js b/Task/Strassens-algorithm/JavaScript/strassens-algorithm-1.js new file mode 100644 index 0000000000..6448ff9755 --- /dev/null +++ b/Task/Strassens-algorithm/JavaScript/strassens-algorithm-1.js @@ -0,0 +1,318 @@ +/** + * Represents the dimensions of a matrix. + * @typedef {object} Shape + * @property {number} rows - Number of rows. + * @property {number} cols - Number of columns. + */ + +/** + * A matrix implemented as a wrapper around a 2D array. + */ +class Matrix { + /** + * Creates a Matrix instance. + * @param {number[][]} data - A 2D array representing the matrix data. + */ + constructor(data = []) { + if (!Array.isArray(data) || (data.length > 0 && !Array.isArray(data[0]))) { + throw new Error("Matrix data must be a 2D array."); + } + // Basic check for consistent row lengths + if (data.length > 1) { + const firstLen = data[0].length; + if (!data.every(row => row.length === firstLen)) { + throw new Error("Matrix rows must have consistent lengths."); + } + } + this.data = data; + } + + /** + * Gets the dimensions (shape) of the matrix. + * @returns {Shape} An object with rows and cols properties. + */ + get shape() { + const rows = this.data.length; + const cols = rows > 0 ? this.data[0].length : 0; + return { rows, cols }; + } + + /** + * Creates a new Matrix assembled from nested blocks of matrices. + * @param {Matrix[][]} blocks - A 2D array of Matrix objects. + * @returns {Matrix} A new Matrix assembled from the blocks. + * @static + */ + static block(blocks) { + const newMatrixData = []; + for (const hblock of blocks) { + if (!hblock || hblock.length === 0) continue; + const numRowsInBlock = hblock[0].shape.rows; // Assume consistent rows within a hblock + + for (let i = 0; i < numRowsInBlock; i++) { + let newRow = []; + for (const matrix of hblock) { + if (matrix.data[i]) { // Check if row exists + newRow = newRow.concat(matrix.data[i]); + } else { + // Handle potential inconsistencies if needed, maybe throw error or fill? + console.warn("Inconsistent row count during block assembly"); + } + } + newMatrixData.push(newRow); + } + } + return new Matrix(newMatrixData); + } + + /** + * Performs naive matrix multiplication (dot product). + * @param {Matrix} b - The matrix to multiply with. + * @returns {Matrix} The resulting matrix product. + */ + dot(b) { + if (!(b instanceof Matrix)) { + throw new Error("Argument must be a Matrix instance."); + } + const aShape = this.shape; + const bShape = b.shape; + + if (aShape.cols !== bShape.rows) { + throw new Error(`Matrices incompatible for multiplication: ${aShape.cols} cols != ${bShape.rows} rows`); + } + + const resultData = []; + for (let i = 0; i < aShape.rows; i++) { + resultData[i] = []; + for (let j = 0; j < bShape.cols; j++) { + let sum = 0; + for (let k = 0; k < aShape.cols; k++) { + sum += this.data[i][k] * b.data[k][j]; + } + resultData[i][j] = sum; + } + } + return new Matrix(resultData); + } + + /** + * Multiplies this matrix by another matrix (using naive multiplication). + * Equivalent to Python's __matmul__. + * @param {Matrix} b - The matrix to multiply with. + * @returns {Matrix} The resulting matrix product. + */ + multiply(b) { + return this.dot(b); + } + + /** + * Adds another matrix to this matrix. + * Equivalent to Python's __add__. + * @param {Matrix} b - The matrix to add. + * @returns {Matrix} The resulting matrix sum. + */ + add(b) { + if (!(b instanceof Matrix)) { + throw new Error("Argument must be a Matrix instance."); + } + const aShape = this.shape; + const bShape = b.shape; + + if (aShape.rows !== bShape.rows || aShape.cols !== bShape.cols) { + throw new Error("Matrices must have the same shape for addition."); + } + + const resultData = this.data.map((row, i) => + row.map((val, j) => val + b.data[i][j]) + ); + return new Matrix(resultData); + } + + /** + * Subtracts another matrix from this matrix. + * Equivalent to Python's __sub__. + * @param {Matrix} b - The matrix to subtract. + * @returns {Matrix} The resulting matrix difference. + */ + subtract(b) { + if (!(b instanceof Matrix)) { + throw new Error("Argument must be a Matrix instance."); + } + const aShape = this.shape; + const bShape = b.shape; + + if (aShape.rows !== bShape.rows || aShape.cols !== bShape.cols) { + throw new Error("Matrices must have the same shape for subtraction."); + } + + const resultData = this.data.map((row, i) => + row.map((val, j) => val - b.data[i][j]) + ); + return new Matrix(resultData); + } + + /** + * Helper function to slice the matrix data. + * @param {number} rowStart - Starting row index (inclusive). + * @param {number} rowEnd - Ending row index (exclusive). + * @param {number} colStart - Starting column index (inclusive). + * @param {number} colEnd - Ending column index (exclusive). + * @returns {Matrix} A new Matrix containing the sliced data. + * @private // Indicates intended internal use + */ + _slice(rowStart, rowEnd, colStart, colEnd) { + const slicedData = this.data.slice(rowStart, rowEnd) + .map(row => row.slice(colStart, colEnd)); + return new Matrix(slicedData); + } + + /** + * Performs matrix multiplication using Strassen's algorithm. + * Requires square matrices whose dimensions are powers of 2. + * @param {Matrix} b - The matrix to multiply with. + * @returns {Matrix} The resulting matrix product. + */ + strassen(b) { + if (!(b instanceof Matrix)) { + throw new Error("Argument must be a Matrix instance."); + } + const aShape = this.shape; + const bShape = b.shape; + + if (aShape.rows !== aShape.cols) { + throw new Error("Matrix must be square for Strassen's algorithm."); + } + if (aShape.rows !== bShape.rows || aShape.cols !== bShape.cols) { + throw new Error("Matrices must have the same shape for Strassen's algorithm."); + } + // Check if dimension is a power of 2 + if (aShape.rows === 0 || (aShape.rows & (aShape.rows - 1)) !== 0) { + throw new Error("Matrix dimension must be a power of 2 for Strassen's algorithm."); + } + + if (aShape.rows === 1) { + return this.dot(b); // Base case + } + + const n = aShape.rows; + const p = n / 2; // Partition size + + // Partition matrices + const a11 = this._slice(0, p, 0, p); + const a12 = this._slice(0, p, p, n); + const a21 = this._slice(p, n, 0, p); + const a22 = this._slice(p, n, p, n); + + const b11 = b._slice(0, p, 0, p); + const b12 = b._slice(0, p, p, n); + const b21 = b._slice(p, n, 0, p); + const b22 = b._slice(p, n, p, n); + + // Recursive calls (Strassen's 7 multiplications) + const m1 = (a11.add(a22)).strassen(b11.add(b22)); + const m2 = (a21.add(a22)).strassen(b11); + const m3 = a11.strassen(b12.subtract(b22)); + const m4 = a22.strassen(b21.subtract(b11)); + const m5 = (a11.add(a12)).strassen(b22); + const m6 = (a21.subtract(a11)).strassen(b11.add(b12)); + const m7 = (a12.subtract(a22)).strassen(b21.add(b22)); + + // Combine results + const c11 = m1.add(m4).subtract(m5).add(m7); + const c12 = m3.add(m5); + const c21 = m2.add(m4); + const c22 = m1.subtract(m2).add(m3).add(m6); + + // Assemble the final matrix from blocks + return Matrix.block([[c11, c12], [c21, c22]]); + } + + /** + * Rounds the elements of the matrix to a specified number of decimal places. + * @param {number} [ndigits=0] - Number of decimal places to round to. If undefined or 0, rounds to the nearest integer. + * @returns {Matrix} A new Matrix with rounded elements. + */ + round(ndigits = 0) { + const factor = Math.pow(10, ndigits); + const roundFn = ndigits > 0 + ? (num) => Math.round((num + Number.EPSILON) * factor) / factor + : (num) => Math.round(num); + + const roundedData = this.data.map(row => + row.map(val => roundFn(val)) + ); + return new Matrix(roundedData); + } + + /** + * Provides a string representation of the matrix. + * @returns {string} The string representation. + */ + toString() { + const rowsStr = this.data.map(row => ` [${row.join(', ')}]`); + return `Matrix([\n${rowsStr.join(',\n')}\n])`; + } +} + +// --- Examples --- + +function examples() { + const a = new Matrix([ + [1, 2], + [3, 4], + ]); + const b = new Matrix([ + [5, 6], + [7, 8], + ]); + const c = new Matrix([ + [1, 1, 1, 1], + [2, 4, 8, 16], + [3, 9, 27, 81], + [4, 16, 64, 256], + ]); + const d = new Matrix([ + [4, -3, 4 / 3, -1 / 4], + [-13 / 3, 19 / 4, -7 / 3, 11 / 24], + [3 / 2, -2, 7 / 6, -1 / 4], + [-1 / 6, 1 / 4, -1 / 6, 1 / 24], + ]); + const e = new Matrix([ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], + [13, 14, 15, 16], + ]); + const f = new Matrix([ // Identity matrix + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1], + ]); + + console.log("Naive matrix multiplication:"); + console.log(` a * b = ${a.multiply(b)}`); // Uses toString implicitly + console.log(` c * d = ${c.multiply(d).round(2)}`); // Round near-zero elements + console.log(` e * f = ${e.multiply(f)}`); + + console.log("\nStrassen's matrix multiplication:"); + console.log(` a * b = ${a.strassen(b)}`); + console.log(` c * d = ${c.strassen(d).round(2)}`); // Round near-zero elements + console.log(` e * f = ${e.strassen(f)}`); + + // Example of addition/subtraction + console.log("\nAddition/Subtraction:"); + const sum_ab = a.add(b); + console.log(` a + b = ${sum_ab}`); + const diff_ba = b.subtract(a); + console.log(` b - a = ${diff_ba}`); + + // Example of block creation (creates a 4x4 matrix from four 2x2 matrices) + console.log("\nBlock Creation:"); + const blocked = Matrix.block([[a, b], [b, a]]); + console.log(` Blocked [a,b],[b,a] = ${blocked}`); + +} + +// Run examples +examples(); diff --git a/Task/Strassens-algorithm/JavaScript/strassens-algorithm-2.js b/Task/Strassens-algorithm/JavaScript/strassens-algorithm-2.js new file mode 100644 index 0000000000..1e6ff77ebf --- /dev/null +++ b/Task/Strassens-algorithm/JavaScript/strassens-algorithm-2.js @@ -0,0 +1,316 @@ +class Matrix { + /** @type {number[][]} */ + data; + /** @type {number} */ + rows; + /** @type {number} */ + cols; + + /** + * @param {number[][]} data The matrix data as a 2D array. + */ + constructor(data) { + if (!Array.isArray(data) || (data.length > 0 && !Array.isArray(data[0]))) { + throw new Error("Input data must be a 2D array."); + } + // Optional: Deep copy to prevent external modifications + this.data = data.map(row => [...row]); + this.rows = data.length; + this.cols = (this.rows > 0) ? (data[0]?.length ?? 0) : 0; // Handle empty rows gracefully + + // Optional: Validate that all rows have the same length + if (this.rows > 0) { + const firstRowLength = this.cols; + for (let i = 1; i < this.rows; i++) { + if (data[i].length !== firstRowLength) { + throw new Error("All rows in the matrix must have the same length."); + } + } + } + } + + /** @returns {number} */ + getRows() { + return this.rows; + } + + /** @returns {number} */ + getCols() { + return this.cols; + } + + /** @param {Matrix} other */ + validateDimensions(other) { + if (this.getRows() !== other.getRows() || this.getCols() !== other.getCols()) { + throw new Error("Matrices must have the same dimensions."); + } + } + + /** @param {Matrix} other */ + validateMultiplication(other) { + if (this.getCols() !== other.getRows()) { + throw new Error(`Cannot multiply matrices: (${this.getRows()}x${this.getCols()}) * (${other.getRows()}x${other.getCols()})`); + } + } + + validateSquarePowerOfTwo() { + if (this.getRows() !== this.getCols()) { + throw new Error("Matrix must be square for this operation."); + } + const n = this.getRows(); + // Check if n is 0 or not a power of two + // (n & (n - 1)) === 0 checks if n is a power of two (or 0) + if (n === 0 || (n & (n - 1)) !== 0) { + throw new Error("Size of matrix must be a power of two for Strassen."); + } + } + + /** + * Adds another matrix to this matrix. + * @param {Matrix} other The matrix to add. + * @returns {Matrix} A new matrix representing the sum. + */ + add(other) { + this.validateDimensions(other); + + const result_data = Array.from({ length: this.rows }, () => Array(this.cols).fill(0.0)); + for (let i = 0; i < this.rows; ++i) { + for (let j = 0; j < this.cols; ++j) { + result_data[i][j] = this.data[i][j] + other.data[i][j]; + } + } + + return new Matrix(result_data); + } + + /** + * Subtracts another matrix from this matrix. + * @param {Matrix} other The matrix to subtract. + * @returns {Matrix} A new matrix representing the difference. + */ + subtract(other) { + this.validateDimensions(other); + + const result_data = Array.from({ length: this.rows }, () => Array(this.cols).fill(0.0)); + for (let i = 0; i < this.rows; ++i) { + for (let j = 0; j < this.cols; ++j) { + result_data[i][j] = this.data[i][j] - other.data[i][j]; + } + } + + return new Matrix(result_data); + } + + /** + * Multiplies this matrix by another matrix (standard algorithm). + * @param {Matrix} other The matrix to multiply by. + * @returns {Matrix} A new matrix representing the product. + */ + multiply(other) { + this.validateMultiplication(other); + + const result_data = Array.from({ length: this.rows }, () => Array(other.cols).fill(0.0)); + for (let i = 0; i < this.rows; ++i) { + for (let j = 0; j < other.cols; ++j) { + let sum = 0.0; + // K loops through columns of 'this' and rows of 'other' + for (let k = 0; k < this.cols; ++k) { + sum += this.data[i][k] * other.data[k][j]; + } + result_data[i][j] = sum; + } + } + + return new Matrix(result_data); + } + + /** + * Returns a string representation of the matrix. + * @returns {string} + */ + toString() { + return this.data.map(row => `[${row.join(', ')}]`).join('\n'); + } + + /** + * Returns a string representation with specified precision, handling rounding and "-0". + * @param {number} p Precision (number of decimal places). + * @returns {string} + */ + toStringWithPrecision(p) { + let resultString = ""; + const pow = Math.pow(10, p); + const zeroString = (0).toFixed(p); + const negZeroString = `-${zeroString}`; + + for (const row of this.data) { + resultString += "["; + for (let i = 0; i < row.length; ++i) { + let val = row[i]; + // Round like C++: round(val * 10^p) / 10^p + let roundedVal = Math.round(val * pow) / pow; + + // Format to fixed precision + let formattedVal = roundedVal.toFixed(p); + + // Handle the "-0.00..." case that toFixed might produce after rounding + if (formattedVal === negZeroString) { + formattedVal = zeroString; + } + + resultString += formattedVal; + if (i < row.length - 1) { + resultString += ", "; + } + } + resultString += "]\n"; // Add newline after each row like C++ example + } + return resultString.trimEnd(); // Remove trailing newline + } + + /** + * Helper function to get quadrant slicing parameters. + * @param {number} r Half rows + * @param {number} c Half columns + * @returns {number[][]} Array of [startRow, endRow, startCol, endCol, offsetRow, offsetCol] + */ + static params(r, c) { + // [startRow, endRow, startCol, endCol, resultOffsetRow, resultOffsetCol] + return [ + [0, r, 0, c, 0, 0], // Top-left quadrant (0) + [0, r, c, 2 * c, 0, c], // Top-right quadrant (1) + [r, 2 * r, 0, c, r, 0], // Bottom-left quadrant (2) + [r, 2 * r, c, 2 * c, r, c] // Bottom-right quadrant (3) + ]; + } + + /** + * Splits the matrix into four equally sized quadrants. + * Assumes matrix dimensions are even. + * @returns {Matrix[]} An array of four matrices [TopLeft, TopRight, BottomLeft, BottomRight]. + */ + toQuarters() { + const r = this.getRows() / 2; + const c = this.getCols() / 2; + if (!Number.isInteger(r) || !Number.isInteger(c)) { + throw new Error("Matrix dimensions must be even for splitting into quarters."); + } + const p = Matrix.params(r, c); + const quarters = Array(4); // Will hold 4 Matrix objects + + for (let k = 0; k < 4; ++k) { + const q_data = Array.from({ length: r }, () => Array(c)); + const [startRow, endRow, startCol, endCol, offsetRow, offsetCol] = p[k]; + for (let i = startRow; i < endRow; ++i) { + for (let j = startCol; j < endCol; ++j) { + // Adjust indices for the smaller quarter matrix + q_data[i - offsetRow][j - offsetCol] = this.data[i][j]; + } + } + quarters[k] = new Matrix(q_data); + } + return quarters; // [TopLeft, TopRight, BottomLeft, BottomRight] + } + + /** + * Creates a new matrix by combining four quadrant matrices. + * @param {Matrix[]} q An array of four matrices [TopLeft, TopRight, BottomLeft, BottomRight]. + * @returns {Matrix} The combined matrix. + */ + static fromQuarters(q) { + if (q.length !== 4) throw new Error("Requires exactly four quadrant matrices."); + // Basic validation: Ensure quadrants have compatible dimensions + const r = q[0].getRows(); + const c = q[0].getCols(); + if (q[1].getRows() !== r || q[1].getCols() !== c || + q[2].getRows() !== r || q[2].getCols() !== c || + q[3].getRows() !== r || q[3].getCols() !== c) { + throw new Error("Quadrant matrices must have the same dimensions."); + } + + const p = Matrix.params(r, c); + const rows = r * 2; + const cols = c * 2; + const m_data = Array.from({ length: rows }, () => Array(cols)); + + for (let k = 0; k < 4; ++k) { + const [startRow, endRow, startCol, endCol, offsetRow, offsetCol] = p[k]; + for (let i = startRow; i < endRow; ++i) { + for (let j = startCol; j < endCol; ++j) { + // Adjust indices to read from the correct quadrant + m_data[i][j] = q[k].data[i - offsetRow][j - offsetCol]; + } + } + } + return new Matrix(m_data); + } + + /** + * Multiplies this matrix by another using Strassen's algorithm. + * Assumes both matrices are square and their size is a power of two. + * @param {Matrix} other The matrix to multiply by. + * @returns {Matrix} The resulting matrix product. + */ + strassen(other) { + this.validateSquarePowerOfTwo(); + other.validateSquarePowerOfTwo(); + if (this.getRows() !== other.getRows()) { // Columns already checked by validateSquarePowerOfTwo + throw new Error("Matrices must be square and of equal size for Strassen multiplication."); + } + + // Base case: If the matrix is 1x1 + if (this.getRows() === 1) { + // Use standard multiplication for the 1x1 case + return this.multiply(other); + } + + // Split matrices into quarters + const qa = this.toQuarters(); // [a11, a12, a21, a22] + const qb = other.toQuarters(); // [b11, b12, b21, b22] + + // Calculate the 7 products recursively (P1 to P7) + const p1 = (qa[1].subtract(qa[3])).strassen(qb[2].add(qb[3])); // p1 = (a12 - a22) * (b21 + b22) + const p2 = (qa[0].add(qa[3])).strassen(qb[0].add(qb[3])); // p2 = (a11 + a22) * (b11 + b22) + const p3 = (qa[0].subtract(qa[2])).strassen(qb[0].add(qb[1])); // p3 = (a11 - a21) * (b11 + b12) + const p4 = (qa[0].add(qa[1])).strassen(qb[3]); // p4 = (a11 + a12) * b22 + const p5 = qa[0].strassen(qb[1].subtract(qb[3])); // p5 = a11 * (b12 - b22) + const p6 = qa[3].strassen(qb[2].subtract(qb[0])); // p6 = a22 * (b21 - b11) + const p7 = (qa[2].add(qa[3])).strassen(qb[0]); // p7 = (a21 + a22) * b11 + + // Calculate the result quarters (C11, C12, C21, C22) + const c11 = p1.add(p2).subtract(p4).add(p6); + const c12 = p4.add(p5); + const c21 = p6.add(p7); + const c22 = p2.subtract(p3).add(p5).subtract(p7); + + // Combine the quarters into the result matrix + return Matrix.fromQuarters([c11, c12, c21, c22]); + } +} + +// --- Main execution (equivalent to C++ main) --- +function main() { + const a = new Matrix([[1.0, 2.0], [3.0, 4.0]]); + const b = new Matrix([[5.0, 6.0], [7.0, 8.0]]); + const c = new Matrix([[1.0, 1.0, 1.0, 1.0], [2.0, 4.0, 8.0, 16.0], [3.0, 9.0, 27.0, 81.0], [4.0, 16.0, 64.0, 256.0]]); + const d = new Matrix([[4.0, -3.0, 4.0 / 3.0, -1.0 / 4.0], [-13.0 / 3.0, 19.0 / 4.0, -7.0 / 3.0, 11.0 / 24.0], [3.0 / 2.0, -2.0, 7.0 / 6.0, -1.0 / 4.0], [-1.0 / 6.0, 1.0 / 4.0, -1.0 / 6.0, 1.0 / 24.0]]); + const e = new Matrix([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0], [13.0, 14.0, 15.0, 16.0]]); + const f = new Matrix([[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]]); // Identity Matrix + + console.log("Using 'normal' matrix multiplication:"); + console.log(` a * b = \n${a.multiply(b).toString()}`); + console.log(`\n c * d = \n${c.multiply(d).toStringWithPrecision(6)}`); // Should be close to identity + console.log(`\n e * f = \n${e.multiply(f).toString()}`); // Should be e + + console.log("\nUsing 'Strassen' matrix multiplication:"); + try { + console.log(` a * b = \n${a.strassen(b).toString()}`); + console.log(`\n c * d = \n${c.strassen(d).toStringWithPrecision(6)}`); // Should be close to identity + console.log(`\n e * f = \n${e.strassen(f).toString()}`); // Should be e + } catch (error) { + console.error("Strassen multiplication failed:", error.message); + } +} + +// Run the main function +main(); diff --git a/Task/Strassens-algorithm/Rust/strassens-algorithm.rs b/Task/Strassens-algorithm/Rust/strassens-algorithm.rs new file mode 100644 index 0000000000..d715f9deea --- /dev/null +++ b/Task/Strassens-algorithm/Rust/strassens-algorithm.rs @@ -0,0 +1,269 @@ +use std::fmt; +use std::ops::{Add, Mul, Sub}; + +#[derive(Debug, Clone)] +struct Matrix { + data: Vec>, + rows: usize, + cols: usize, +} + +impl Matrix { + fn new(data: Vec>) -> Self { + let rows = data.len(); + let cols = if rows > 0 { data[0].len() } else { 0 }; + Matrix { data, rows, cols } + } + + fn rows(&self) -> usize { + self.rows + } + + fn cols(&self) -> usize { + self.cols + } + + fn validate_dimensions(&self, other: &Matrix) { + if self.rows() != other.rows() || self.cols() != other.cols() { + panic!("Matrices must have the same dimensions."); + } + } + + fn validate_multiplication(&self, other: &Matrix) { + if self.cols() != other.rows() { + panic!("Cannot multiply these matrices."); + } + } + + fn validate_square_power_of_two(&self) { + if self.rows() != self.cols() { + panic!("Matrix must be square."); + } + if self.rows() == 0 || (self.rows() & (self.rows() - 1)) != 0 { + panic!("Size of matrix must be a power of two."); + } + } +} + +impl Add for Matrix { + type Output = Self; + + fn add(self, other: Self) -> Self { + self.validate_dimensions(&other); + + let mut result_data = Vec::with_capacity(self.rows()); + for i in 0..self.rows() { + let mut row = Vec::with_capacity(self.cols()); + for j in 0..self.cols() { + row.push(self.data[i][j] + other.data[i][j]); + } + result_data.push(row); + } + + Matrix::new(result_data) + } +} + +impl Sub for Matrix { + type Output = Self; + + fn sub(self, other: Self) -> Self { + self.validate_dimensions(&other); + + let mut result_data = Vec::with_capacity(self.rows()); + for i in 0..self.rows() { + let mut row = Vec::with_capacity(self.cols()); + for j in 0..self.cols() { + row.push(self.data[i][j] - other.data[i][j]); + } + result_data.push(row); + } + + Matrix::new(result_data) + } +} + +impl Mul for Matrix { + type Output = Self; + + fn mul(self, other: Self) -> Self { + self.validate_multiplication(&other); + + let mut result_data = Vec::with_capacity(self.rows()); + for i in 0..self.rows() { + let mut row = Vec::with_capacity(other.cols()); + for j in 0..other.cols() { + let mut sum = 0.0; + for k in 0..other.rows() { + sum += self.data[i][k] * other.data[k][j]; + } + row.push(sum); + } + result_data.push(row); + } + + Matrix::new(result_data) + } +} + +impl fmt::Display for Matrix { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = String::new(); + for row in &self.data { + s.push_str(&format!("{:?}\n", row)); + } + write!(f, "{}", s) + } +} + +impl Matrix { + fn to_string_with_precision(&self, p: usize) -> String { + let mut s = String::new(); + let pow = 10.0_f64.powi(p as i32); + for row in &self.data { + let mut t = Vec::new(); + for &val in row { + let r = (val * pow).round() / pow; + let formatted = format!("{}", r); + if formatted == "-0" { + t.push("0".to_string()); + } else { + t.push(formatted); + } + } + s.push_str(&format!("{:?}\n", t)); + } + s + } + + fn params(r: usize, c: usize) -> [[usize; 6]; 4] { + [ + [0, r, 0, c, 0, 0], + [0, r, c, 2 * c, 0, c], + [r, 2 * r, 0, c, r, 0], + [r, 2 * r, c, 2 * c, r, c], + ] + } + + fn to_quarters(&self) -> [Matrix; 4] { + let r = self.rows() / 2; + let c = self.cols() / 2; + let p = Matrix::params(r, c); + let mut quarters: [Matrix; 4] = [ + Matrix::new(vec![vec![0.0; c]; r]), + Matrix::new(vec![vec![0.0; c]; r]), + Matrix::new(vec![vec![0.0; c]; r]), + Matrix::new(vec![vec![0.0; c]; r]), + ]; + + for k in 0..4 { + let mut q_data = Vec::with_capacity(r); + for i in p[k][0]..p[k][1] { + let mut row = Vec::with_capacity(c); + for j in p[k][2]..p[k][3] { + row.push(self.data[i][j]); + } + q_data.push(row); + } + quarters[k] = Matrix::new(q_data); + } + + quarters + } + + fn from_quarters(q: [Matrix; 4]) -> Matrix { + let r = q[0].rows(); + let c = q[0].cols(); + let p = Matrix::params(r, c); + let rows = r * 2; + let cols = c * 2; + + let mut m_data = vec![vec![0.0; cols]; rows]; + + for k in 0..4 { + for i in p[k][0]..p[k][1] { + for j in p[k][2]..p[k][3] { + m_data[i][j] = q[k].data[i - p[k][4]][j - p[k][5]]; + } + } + } + + Matrix::new(m_data) + } + + fn strassen(&self, other: Matrix) -> Matrix { + self.validate_square_power_of_two(); + other.validate_square_power_of_two(); + if self.rows() != other.rows() || self.cols() != other.cols() { + panic!("Matrices must be square and of equal size for Strassen multiplication."); + } + + if self.rows() == 1 { + return self.clone() * other; + } + + let qa = self.to_quarters(); + let qb = other.to_quarters(); + + let p1 = (qa[1].clone() - qa[3].clone()).strassen(qb[2].clone() + qb[3].clone()); + let p2 = (qa[0].clone() + qa[3].clone()).strassen(qb[0].clone() + qb[3].clone()); + let p3 = (qa[0].clone() - qa[2].clone()).strassen(qb[0].clone() + qb[1].clone()); + let p4 = (qa[0].clone() + qa[1].clone()).strassen(qb[3].clone()); + let p5 = qa[0].clone().strassen(qb[1].clone() - qb[3].clone()); + let p6 = qa[3].clone().strassen(qb[2].clone() - qb[0].clone()); + let p7 = (qa[2].clone() + qa[3].clone()).strassen(qb[0].clone()); + + let mut q: [Matrix; 4] = [ + Matrix::new(vec![vec![0.0; qa[0].cols()]; qa[0].rows()]), + Matrix::new(vec![vec![0.0; qa[0].cols()]; qa[0].rows()]), + Matrix::new(vec![vec![0.0; qa[0].cols()]; qa[0].rows()]), + Matrix::new(vec![vec![0.0; qa[0].cols()]; qa[0].rows()]), + ]; + + q[0] = p1.clone() + p2.clone() - p4.clone() + p6.clone(); + q[1] = p4 + p5.clone(); + q[2] = p6 + p7.clone(); + q[3] = p2 - p3.clone() + p5 - p7; + + Matrix::from_quarters(q) + } +} + +fn main() { + let a = Matrix::new(vec![vec![1.0, 2.0], vec![3.0, 4.0]]); + let b = Matrix::new(vec![vec![5.0, 6.0], vec![7.0, 8.0]]); + let c = Matrix::new(vec![ + vec![1.0, 1.0, 1.0, 1.0], + vec![2.0, 4.0, 8.0, 16.0], + vec![3.0, 9.0, 27.0, 81.0], + vec![4.0, 16.0, 64.0, 256.0], + ]); + let d = Matrix::new(vec![ + vec![4.0, -3.0, 4.0 / 3.0, -1.0 / 4.0], + vec![-13.0 / 3.0, 19.0 / 4.0, -7.0 / 3.0, 11.0 / 24.0], + vec![3.0 / 2.0, -2.0, 7.0 / 6.0, -1.0 / 4.0], + vec![-1.0 / 6.0, 1.0 / 4.0, -1.0 / 6.0, 1.0 / 24.0], + ]); + let e = Matrix::new(vec![ + vec![1.0, 2.0, 3.0, 4.0], + vec![5.0, 6.0, 7.0, 8.0], + vec![9.0, 10.0, 11.0, 12.0], + vec![13.0, 14.0, 15.0, 16.0], + ]); + let f = Matrix::new(vec![ + vec![1.0, 0.0, 0.0, 0.0], + vec![0.0, 1.0, 0.0, 0.0], + vec![0.0, 0.0, 1.0, 0.0], + vec![0.0, 0.0, 0.0, 1.0], + ]); + + println!("Using 'normal' matrix multiplication:"); + println!(" a * b = {}", a.clone() * b.clone()); + println!(" c * d = {}", (c.clone() * d.clone()).to_string_with_precision(6)); + println!(" e * f = {}", e.clone() * f.clone()); + + println!("\nUsing 'Strassen' matrix multiplication:"); + println!(" a * b = {}", a.strassen(b)); + println!(" c * d = {}", c.strassen(d).to_string_with_precision(6)); + println!(" e * f = {}", e.strassen(f)); +} diff --git a/Task/Strassens-algorithm/Zig/strassens-algorithm.zig b/Task/Strassens-algorithm/Zig/strassens-algorithm.zig new file mode 100644 index 0000000000..9297f6eb48 --- /dev/null +++ b/Task/Strassens-algorithm/Zig/strassens-algorithm.zig @@ -0,0 +1,477 @@ +const std = @import("std"); +const fmt = std.fmt; +const ArrayList = std.ArrayList; +const Allocator = std.mem.Allocator; + +const Matrix = struct { + data: ArrayList(ArrayList(f64)), + rows: usize, + cols: usize, + allocator: Allocator, + + pub fn init(allocator: Allocator, data: ArrayList(ArrayList(f64))) !Matrix { + const rows = data.items.len; + const cols = if (rows > 0) data.items[0].items.len else 0; + + return Matrix{ + .data = data, + .rows = rows, + .cols = cols, + .allocator = allocator, + }; + } + + pub fn deinit(self: *Matrix) void { + for (self.data.items) |*row| { + row.deinit(); + } + self.data.deinit(); + } + + pub fn clone(self: Matrix) !Matrix { + var new_data = ArrayList(ArrayList(f64)).init(self.allocator); + try new_data.ensureTotalCapacity(self.rows); + + for (self.data.items) |row| { + var new_row = ArrayList(f64).init(self.allocator); + try new_row.ensureTotalCapacity(self.cols); + try new_row.appendSlice(row.items); + try new_data.append(new_row); + } + + return Matrix{ + .data = new_data, + .rows = self.rows, + .cols = self.cols, + .allocator = self.allocator, + }; + } + + pub fn validateDimensions(self: Matrix, other: Matrix) !void { + if (self.rows != other.rows or self.cols != other.cols) { + return error.DimensionMismatch; + } + } + + pub fn validateMultiplication(self: Matrix, other: Matrix) !void { + if (self.cols != other.rows) { + return error.CannotMultiply; + } + } + + pub fn validateSquarePowerOfTwo(self: Matrix) !void { + if (self.rows != self.cols) { + return error.NotSquare; + } + if (self.rows == 0 or (self.rows & (self.rows - 1)) != 0) { + return error.NotPowerOfTwo; + } + } + + pub fn add(self: Matrix, other: Matrix) !Matrix { + try self.validateDimensions(other); + + var result_data = ArrayList(ArrayList(f64)).init(self.allocator); + try result_data.ensureTotalCapacity(self.rows); + + for (0..self.rows) |i| { + var row = ArrayList(f64).init(self.allocator); + try row.ensureTotalCapacity(self.cols); + + for (0..self.cols) |j| { + try row.append(self.data.items[i].items[j] + other.data.items[i].items[j]); + } + try result_data.append(row); + } + + return try Matrix.init(self.allocator, result_data); + } + + pub fn sub(self: Matrix, other: Matrix) !Matrix { + try self.validateDimensions(other); + + var result_data = ArrayList(ArrayList(f64)).init(self.allocator); + try result_data.ensureTotalCapacity(self.rows); + + for (0..self.rows) |i| { + var row = ArrayList(f64).init(self.allocator); + try row.ensureTotalCapacity(self.cols); + + for (0..self.cols) |j| { + try row.append(self.data.items[i].items[j] - other.data.items[i].items[j]); + } + try result_data.append(row); + } + + return try Matrix.init(self.allocator, result_data); + } + + pub fn mul(self: Matrix, other: Matrix) !Matrix { + try self.validateMultiplication(other); + + var result_data = ArrayList(ArrayList(f64)).init(self.allocator); + try result_data.ensureTotalCapacity(self.rows); + + for (0..self.rows) |i| { + var row = ArrayList(f64).init(self.allocator); + try row.ensureTotalCapacity(other.cols); + + for (0..other.cols) |j| { + var sum: f64 = 0.0; + for (0..self.cols) |k| { + sum += self.data.items[i].items[k] * other.data.items[k].items[j]; + } + try row.append(sum); + } + try result_data.append(row); + } + + return try Matrix.init(self.allocator, result_data); + } + + pub fn format(self: Matrix, comptime _: []const u8, _: fmt.FormatOptions, writer: anytype) !void { + for (self.data.items) |row| { + try writer.print("{any}\n", .{row.items}); + } + } + + pub fn toStringWithPrecision(self: Matrix, p: usize, allocator: Allocator) ![]u8 { + var output = ArrayList(u8).init(allocator); + defer output.deinit(); + + const pow = std.math.pow(f64, 10.0, @as(f64, @floatFromInt(p))); + + for (self.data.items) |row| { + var formatted_row = ArrayList([]const u8).init(allocator); + defer { + for (formatted_row.items) |item| { + allocator.free(item); + } + formatted_row.deinit(); + } + + for (row.items) |val| { + const r = @round(val * pow) / pow; + const formatted = try fmt.allocPrint(allocator, "{d}", .{r}); + + if (std.mem.eql(u8, formatted, "-0")) { + allocator.free(formatted); + try formatted_row.append(try allocator.dupe(u8, "0")); + } else { + try formatted_row.append(formatted); + } + } + + std.debug.print("{any}\n", .{formatted_row.items}); + } + + return output.toOwnedSlice(); + } + + fn params(r: usize, c: usize) [4][6]usize { + return [4][6]usize{ + [_]usize{ 0, r, 0, c, 0, 0 }, + [_]usize{ 0, r, c, 2 * c, 0, c }, + [_]usize{ r, 2 * r, 0, c, r, 0 }, + [_]usize{ r, 2 * r, c, 2 * c, r, c }, + }; + } + + pub fn toQuarters(self: Matrix) ![4]Matrix { + const r = self.rows / 2; + const c = self.cols / 2; + const p = Matrix.params(r, c); + + var quarters: [4]Matrix = undefined; + + for (0..4) |k| { + var q_data = ArrayList(ArrayList(f64)).init(self.allocator); + try q_data.ensureTotalCapacity(r); + + for (p[k][0]..p[k][1]) |i| { + var row = ArrayList(f64).init(self.allocator); + try row.ensureTotalCapacity(c); + + for (p[k][2]..p[k][3]) |j| { + try row.append(self.data.items[i].items[j]); + } + try q_data.append(row); + } + + quarters[k] = try Matrix.init(self.allocator, q_data); + } + + return quarters; + } + + pub fn fromQuarters(q: [4]Matrix, allocator: Allocator) !Matrix { + const r = q[0].rows; + const c = q[0].cols; + const p = Matrix.params(r, c); + const rows = r * 2; + const cols = c * 2; + + var m_data = ArrayList(ArrayList(f64)).init(allocator); + try m_data.ensureTotalCapacity(rows); + + for (0..rows) |_| { + var row = ArrayList(f64).init(allocator); + try row.ensureTotalCapacity(cols); + for (0..cols) |_| { + try row.append(0.0); + } + try m_data.append(row); + } + + for (0..4) |k| { + for (p[k][0]..p[k][1]) |i| { + for (p[k][2]..p[k][3]) |j| { + m_data.items[i].items[j] = q[k].data.items[i - p[k][4]].items[j - p[k][5]]; + } + } + } + + return try Matrix.init(allocator, m_data); + } + + pub fn strassen(self: Matrix, other: Matrix) !Matrix { + try self.validateSquarePowerOfTwo(); + try other.validateSquarePowerOfTwo(); + + if (self.rows != other.rows or self.cols != other.cols) { + return error.InvalidDimensions; + } + + if (self.rows == 1) { + return self.mul(other); + } + + var qa = try self.toQuarters(); + defer for (&qa) |*q| q.deinit(); + + var qb = try other.toQuarters(); + defer for (&qb) |*q| q.deinit(); + + var t1 = try qa[1].sub(qa[3]); + defer t1.deinit(); + var t2 = try qb[2].add(qb[3]); + defer t2.deinit(); + var p1 = try t1.strassen(t2); + defer p1.deinit(); + + var t3 = try qa[0].add(qa[3]); + defer t3.deinit(); + var t4 = try qb[0].add(qb[3]); + defer t4.deinit(); + var p2 = try t3.strassen(t4); + defer p2.deinit(); + + var t5 = try qa[0].sub(qa[2]); + defer t5.deinit(); + var t6 = try qb[0].add(qb[1]); + defer t6.deinit(); + var p3 = try t5.strassen(t6); + defer p3.deinit(); + + var t7 = try qa[0].add(qa[1]); + defer t7.deinit(); + var p4 = try t7.strassen(qb[3]); + defer p4.deinit(); + + var t8 = try qb[1].sub(qb[3]); + defer t8.deinit(); + var p5 = try qa[0].strassen(t8); + defer p5.deinit(); + + var t9 = try qb[2].sub(qb[0]); + defer t9.deinit(); + var p6 = try qa[3].strassen(t9); + defer p6.deinit(); + + var t10 = try qa[2].add(qa[3]); + defer t10.deinit(); + var p7 = try t10.strassen(qb[0]); + defer p7.deinit(); + + var q: [4]Matrix = undefined; + + // q[0] = p1 + p2 - p4 + p6 + var ta = try p1.add(p2); + defer ta.deinit(); + var tb = try ta.sub(p4); + defer tb.deinit(); + q[0] = try tb.add(p6); + + // q[1] = p4 + p5 + q[1] = try p4.add(p5); + + // q[2] = p6 + p7 + q[2] = try p6.add(p7); + + // q[3] = p2 - p3 + p5 - p7 + var tc = try p2.sub(p3); + defer tc.deinit(); + var td = try tc.add(p5); + defer td.deinit(); + q[3] = try td.sub(p7); + + defer for (&q) |*quarter| quarter.deinit(); + + return Matrix.fromQuarters(q, self.allocator); + } +}; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + + const allocator = gpa.allocator(); + + // Matrix A - [1 2; 3 4] + var a_data = ArrayList(ArrayList(f64)).init(allocator); + var a_row1 = ArrayList(f64).init(allocator); + try a_row1.appendSlice(&[_]f64{ 1.0, 2.0 }); + var a_row2 = ArrayList(f64).init(allocator); + try a_row2.appendSlice(&[_]f64{ 3.0, 4.0 }); + try a_data.append(a_row1); + try a_data.append(a_row2); + var a = try Matrix.init(allocator, a_data); + defer a.deinit(); + + // Matrix B - [5 6; 7 8] + var b_data = ArrayList(ArrayList(f64)).init(allocator); + var b_row1 = ArrayList(f64).init(allocator); + try b_row1.appendSlice(&[_]f64{ 5.0, 6.0 }); + var b_row2 = ArrayList(f64).init(allocator); + try b_row2.appendSlice(&[_]f64{ 7.0, 8.0 }); + try b_data.append(b_row1); + try b_data.append(b_row2); + var b = try Matrix.init(allocator, b_data); + defer b.deinit(); + + // Matrix C - 4x4 + var c_data = ArrayList(ArrayList(f64)).init(allocator); + var c_row1 = ArrayList(f64).init(allocator); + try c_row1.appendSlice(&[_]f64{ 1.0, 1.0, 1.0, 1.0 }); + var c_row2 = ArrayList(f64).init(allocator); + try c_row2.appendSlice(&[_]f64{ 2.0, 4.0, 8.0, 16.0 }); + var c_row3 = ArrayList(f64).init(allocator); + try c_row3.appendSlice(&[_]f64{ 3.0, 9.0, 27.0, 81.0 }); + var c_row4 = ArrayList(f64).init(allocator); + try c_row4.appendSlice(&[_]f64{ 4.0, 16.0, 64.0, 256.0 }); + try c_data.append(c_row1); + try c_data.append(c_row2); + try c_data.append(c_row3); + try c_data.append(c_row4); + var c = try Matrix.init(allocator, c_data); + defer c.deinit(); + + // Matrix D - 4x4 + var d_data = ArrayList(ArrayList(f64)).init(allocator); + var d_row1 = ArrayList(f64).init(allocator); + try d_row1.appendSlice(&[_]f64{ 4.0, -3.0, 4.0 / 3.0, -1.0 / 4.0 }); + var d_row2 = ArrayList(f64).init(allocator); + try d_row2.appendSlice(&[_]f64{ -13.0 / 3.0, 19.0 / 4.0, -7.0 / 3.0, 11.0 / 24.0 }); + var d_row3 = ArrayList(f64).init(allocator); + try d_row3.appendSlice(&[_]f64{ 3.0 / 2.0, -2.0, 7.0 / 6.0, -1.0 / 4.0 }); + var d_row4 = ArrayList(f64).init(allocator); + try d_row4.appendSlice(&[_]f64{ -1.0 / 6.0, 1.0 / 4.0, -1.0 / 6.0, 1.0 / 24.0 }); + try d_data.append(d_row1); + try d_data.append(d_row2); + try d_data.append(d_row3); + try d_data.append(d_row4); + var d = try Matrix.init(allocator, d_data); + defer d.deinit(); + + // Matrix E - 4x4 + var e_data = ArrayList(ArrayList(f64)).init(allocator); + var e_row1 = ArrayList(f64).init(allocator); + try e_row1.appendSlice(&[_]f64{ 1.0, 2.0, 3.0, 4.0 }); + var e_row2 = ArrayList(f64).init(allocator); + try e_row2.appendSlice(&[_]f64{ 5.0, 6.0, 7.0, 8.0 }); + var e_row3 = ArrayList(f64).init(allocator); + try e_row3.appendSlice(&[_]f64{ 9.0, 10.0, 11.0, 12.0 }); + var e_row4 = ArrayList(f64).init(allocator); + try e_row4.appendSlice(&[_]f64{ 13.0, 14.0, 15.0, 16.0 }); + try e_data.append(e_row1); + try e_data.append(e_row2); + try e_data.append(e_row3); + try e_data.append(e_row4); + var e = try Matrix.init(allocator, e_data); + defer e.deinit(); + + // Matrix F - Identity 4x4 + var f_data = ArrayList(ArrayList(f64)).init(allocator); + var f_row1 = ArrayList(f64).init(allocator); + try f_row1.appendSlice(&[_]f64{ 1.0, 0.0, 0.0, 0.0 }); + var f_row2 = ArrayList(f64).init(allocator); + try f_row2.appendSlice(&[_]f64{ 0.0, 1.0, 0.0, 0.0 }); + var f_row3 = ArrayList(f64).init(allocator); + try f_row3.appendSlice(&[_]f64{ 0.0, 0.0, 1.0, 0.0 }); + var f_row4 = ArrayList(f64).init(allocator); + try f_row4.appendSlice(&[_]f64{ 0.0, 0.0, 0.0, 1.0 }); + try f_data.append(f_row1); + try f_data.append(f_row2); + try f_data.append(f_row3); + try f_data.append(f_row4); + var f = try Matrix.init(allocator, f_data); + defer f.deinit(); + + const stdout = std.io.getStdOut().writer(); + + try stdout.print("Using 'normal' matrix multiplication:\n", .{}); + + var a_clone = try a.clone(); + defer a_clone.deinit(); + var b_clone = try b.clone(); + defer b_clone.deinit(); + var ab = try a_clone.mul(b_clone); + defer ab.deinit(); + try stdout.print(" a * b = {}\n", .{ab}); + + var c_clone = try c.clone(); + defer c_clone.deinit(); + var d_clone = try d.clone(); + defer d_clone.deinit(); + var cd = try c_clone.mul(d_clone); + defer cd.deinit(); + const cd_str = try cd.toStringWithPrecision(6, allocator); + defer allocator.free(cd_str); + try stdout.print(" c * d = {s}\n", .{cd_str}); + + var e_clone = try e.clone(); + defer e_clone.deinit(); + var f_clone = try f.clone(); + defer f_clone.deinit(); + var ef = try e_clone.mul(f_clone); + defer ef.deinit(); + try stdout.print(" e * f = {}\n", .{ef}); + + try stdout.print("\nUsing 'Strassen' matrix multiplication:\n", .{}); + + var a_clone2 = try a.clone(); + defer a_clone2.deinit(); + var b_clone2 = try b.clone(); + defer b_clone2.deinit(); + var ab_s = try a_clone2.strassen(b_clone2); + defer ab_s.deinit(); + try stdout.print(" a * b = {}\n", .{ab_s}); + + var c_clone2 = try c.clone(); + defer c_clone2.deinit(); + var d_clone2 = try d.clone(); + defer d_clone2.deinit(); + var cd_s = try c_clone2.strassen(d_clone2); + defer cd_s.deinit(); + const cd_s_str = try cd_s.toStringWithPrecision(6, allocator); + defer allocator.free(cd_s_str); + try stdout.print(" c * d = {s}\n", .{cd_s_str}); + + var e_clone2 = try e.clone(); + defer e_clone2.deinit(); + var f_clone2 = try f.clone(); + defer f_clone2.deinit(); + var ef_s = try e_clone2.strassen(f_clone2); + defer ef_s.deinit(); + try stdout.print(" e * f = {}\n", .{ef_s}); +} diff --git a/Task/Stream-merge/Rust/stream-merge.rs b/Task/Stream-merge/Rust/stream-merge.rs new file mode 100644 index 0000000000..fce1392387 --- /dev/null +++ b/Task/Stream-merge/Rust/stream-merge.rs @@ -0,0 +1,81 @@ +use std::cmp::Ordering; + +fn merge2(c1: &[T], c2: &[T], action: F) { + let mut i1 = 0; + let mut i2 = 0; + + while i1 < c1.len() && i2 < c2.len() { + if c1[i1] <= c2[i2] { + action(c1[i1]); + i1 += 1; + } else { + action(c2[i2]); + i2 += 1; + } + } + + while i1 < c1.len() { + action(c1[i1]); + i1 += 1; + } + + while i2 < c2.len() { + action(c2[i2]); + i2 += 1; + } +} + +fn merge_n(action: F, all: &[&[T]]) { + let mut vit: Vec<(usize, usize)> = all.iter().map(|c| (0, c.len())).collect(); + + loop { + let mut done = true; + let mut least: Option = None; + + for (i, &(start, end)) in vit.iter().enumerate() { + if start < end { + if least.is_none() { + least = Some(i); + } else { + if let Some(l) = least { + if all[i][start].cmp(&all[l][vit[l].0]) == Ordering::Less { + least = Some(i); + } + } + } + } + } + + if let Some(l) = least { + if vit[l].0 < vit[l].1 { + done = false; + action(all[l][vit[l].0]); + vit[l].0 += 1; + } + } + + if done { + break; + } + } +} + + +fn display(num: i32) { + print!("{} ", num); +} + +fn main() { + let v1 = vec![0, 3, 6]; + let v2 = vec![1, 4, 7]; + let v3 = vec![2, 5, 8]; + + merge2(&v2, &v1, display); + println!(); + + merge_n(display, &[&v1]); + println!(); + + merge_n(display, &[&v3, &v2, &v1]); + println!(); +} diff --git a/Task/String-concatenation/JavaScript/string-concatenation.js b/Task/String-concatenation/JavaScript/string-concatenation.js index 3763e92eb2..df727c924c 100644 --- a/Task/String-concatenation/JavaScript/string-concatenation.js +++ b/Task/String-concatenation/JavaScript/string-concatenation.js @@ -1,2 +1,2 @@ var s = "hello" -print(s + " there!") +console.log(s + " there!") diff --git a/Task/String-concatenation/Uxntal/string-concatenation.uxnatl b/Task/String-concatenation/Uxntal/string-concatenation.uxnatl index e817d13f27..f65b87d1b5 100644 --- a/Task/String-concatenation/Uxntal/string-concatenation.uxnatl +++ b/Task/String-concatenation/Uxntal/string-concatenation.uxnatl @@ -1,33 +1,32 @@ -|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 +|18 @Console/write |0100 @on-reset ( -> ) ;str3 ;str1 copy-str ;str3 ;str2 append-str ;str3 print-str - #0a .Console/write DEO BRK -@print-str ( str* -: ) - &loop ( -- ) - LDAk .Console/write DEO - INC2 LDAk ?&loop - POP2 JMP2r +@print-str_ ( str* -: ) + LDAk .Console/write DEO + INC2 @print-str LDAk ?print-str_ + POP2 + JMP2r + +@append-str ( dest* src* -: ) + STH2 end-str STH2r + ( >> ) @copy-str ( dest* src* -: ) STH2 &loop ( -- ) LDAkr STH2k STAr INC2 LDAkr STHr INC2r ?&loop - POP2 POP2r JMP2r + POP2 POP2r + JMP2r -@append-str ( dest* src* -: ) - STH2 end-str STH2r copy-str JMP2r - -@end-str ( str* -: str* ) - !&inner - &loop ( -- ) - INC2 &inner LDAk ?&loop +@end-str_ ( str* -: str* ) + INC2 @end-str LDAk ?end-str_ JMP2r @str1 "Uxn 00 -@str2 "tal 00 +@str2 "tal 0a00 @str3 diff --git a/Task/String-length/Crystal/string-length-1.cr b/Task/String-length/Crystal/string-length-1.cr index 9696655917..d16a30f7c5 100644 --- a/Task/String-length/Crystal/string-length-1.cr +++ b/Task/String-length/Crystal/string-length-1.cr @@ -1 +1 @@ -"J̲o̲s̲é̲".bytesize +"J̲o̲s̲é̲".bytesize #=> 13 diff --git a/Task/String-length/Crystal/string-length-2.cr b/Task/String-length/Crystal/string-length-2.cr index 7f7158a89a..0ae6a44f3a 100644 --- a/Task/String-length/Crystal/string-length-2.cr +++ b/Task/String-length/Crystal/string-length-2.cr @@ -1 +1 @@ -"J̲o̲s̲é̲".chars.length +"J̲o̲s̲é̲".size #=> 8 diff --git a/Task/String-length/Crystal/string-length-3.cr b/Task/String-length/Crystal/string-length-3.cr new file mode 100644 index 0000000000..187bd4d6c1 --- /dev/null +++ b/Task/String-length/Crystal/string-length-3.cr @@ -0,0 +1 @@ +"J̲o̲s̲é̲".grapheme_size #=> 4 diff --git a/Task/String-length/Uxntal/string-length.uxnatl b/Task/String-length/Uxntal/string-length.uxnatl new file mode 100644 index 0000000000..0c7ef9a82f --- /dev/null +++ b/Task/String-length/Uxntal/string-length.uxnatl @@ -0,0 +1,31 @@ +%DBG { [ LIT2 01 -System/debug ] DEO } + +|0e @System/debug + +|100 + +@on-reset ( -> ) + ;my-string slen-bytes ( 0007 ) + ;my-string slen-chars ( 0005 ) + DBG + BRK + +@next-glyph ( addr* -- addr* ) + INC2 LDAk #06 SFT #02 EQU ?next-glyph + JMP2r + +@slen-chars ( str* -- len* ) + LIT2r 0000 + &>loop ( -- ) + INC2r next-glyph LDAk ?&>loop + POP2 STH2r + JMP2r + +@slen-bytes ( str* -- len* ) + STH2k + &>loop + INC2 LDAk ?&>loop + STH2r SUB2 + JMP2r + +@my-string "møøse $1 diff --git a/Task/String-prepend/Crystal/string-prepend.cr b/Task/String-prepend/Crystal/string-prepend.cr new file mode 100644 index 0000000000..8850fac0c9 --- /dev/null +++ b/Task/String-prepend/Crystal/string-prepend.cr @@ -0,0 +1,3 @@ +s = "world" +s = "Hello " + s +puts s diff --git a/Task/String-prepend/OPL/string-prepend.opl b/Task/String-prepend/OPL/string-prepend.opl new file mode 100644 index 0000000000..708fba229f --- /dev/null +++ b/Task/String-prepend/OPL/string-prepend.opl @@ -0,0 +1,7 @@ +PROC main: + LOCAL a$(12) + a$="Code" + a$="Rosetta "+a$ + PRINT a$ + GET +ENDP diff --git a/Task/Strip-a-set-of-characters-from-a-string/Java/strip-a-set-of-characters-from-a-string-4.java b/Task/Strip-a-set-of-characters-from-a-string/Java/strip-a-set-of-characters-from-a-string-4.java new file mode 100644 index 0000000000..e23b978aed --- /dev/null +++ b/Task/Strip-a-set-of-characters-from-a-string/Java/strip-a-set-of-characters-from-a-string-4.java @@ -0,0 +1,13 @@ +import java.util.function.BiFunction; +import java.util.stream.Collectors; + +public final class StripASetOfCharactersFromAString { + + public static void main(String[] args) { + BiFunction stripCharacters = (string, characters) -> string.chars() + .mapToObj(Character::toString).filter( s -> ! characters.contains(s) ).collect(Collectors.joining("")); + + System.out.println(stripCharacters.apply("She was a soul stripper. She took my heart!", "aei")); + } + +} diff --git a/Task/Strip-a-set-of-characters-from-a-string/M2000-Interpreter/strip-a-set-of-characters-from-a-string.m2000 b/Task/Strip-a-set-of-characters-from-a-string/M2000-Interpreter/strip-a-set-of-characters-from-a-string.m2000 new file mode 100644 index 0000000000..af3f36525b --- /dev/null +++ b/Task/Strip-a-set-of-characters-from-a-string/M2000-Interpreter/strip-a-set-of-characters-from-a-string.m2000 @@ -0,0 +1 @@ +print filter$("She was a soul stripper. She took my heart!","aei")="Sh ws soul strppr. Sh took my hrt!" diff --git a/Task/Strip-a-set-of-characters-from-a-string/Objeck/strip-a-set-of-characters-from-a-string.objeck b/Task/Strip-a-set-of-characters-from-a-string/Objeck/strip-a-set-of-characters-from-a-string.objeck new file mode 100644 index 0000000000..ed0e81353a --- /dev/null +++ b/Task/Strip-a-set-of-characters-from-a-string/Objeck/strip-a-set-of-characters-from-a-string.objeck @@ -0,0 +1,17 @@ +class CharsStrip { + function : Main(args : String[]) ~ Nil { + StripChars("She was a soul stripper. She took my heart!","aei")->PrintLine(); + } + + function : StripChars(str : String, strip : String) ~ String { + out := ""; + + each(char in str) { + if(<>strip->Has(char)) { + out += char; + }; + }; + + return out; + } +} diff --git a/Task/Strip-a-set-of-characters-from-a-string/Odin/strip-a-set-of-characters-from-a-string.odin b/Task/Strip-a-set-of-characters-from-a-string/Odin/strip-a-set-of-characters-from-a-string.odin new file mode 100644 index 0000000000..e373a19857 --- /dev/null +++ b/Task/Strip-a-set-of-characters-from-a-string/Odin/strip-a-set-of-characters-from-a-string.odin @@ -0,0 +1,16 @@ +import "core:fmt" +import "core:strings" +import "core:unicode/utf8" + +main :: proc() { + input_string:="She was a soul stripper. She took my heart!" + filter_string:="aei" + + for i in filter_string{ + rune_array:=[]rune{i} + filter:=utf8.runes_to_string(rune_array) + input_string,_=strings.replace(input_string, filter, "", -1) + } + fmt.println(input_string) + +} diff --git a/Task/Strip-a-set-of-characters-from-a-string/R/strip-a-set-of-characters-from-a-string.r b/Task/Strip-a-set-of-characters-from-a-string/R/strip-a-set-of-characters-from-a-string.r new file mode 100644 index 0000000000..aae438aa47 --- /dev/null +++ b/Task/Strip-a-set-of-characters-from-a-string/R/strip-a-set-of-characters-from-a-string.r @@ -0,0 +1,16 @@ +library(stringr) + +stripchars <- function(s, chars){ + #Make sure potentially troublesome regex characters are escaped properly + specialchars <- c("\\","^","[","]","-") + for(char in specialchars){ + if(str_detect(chars, fixed(char))){ + chars <- str_replace_all(chars, fixed(char), str_glue("\\{char}")) + } + } + regexp <- str_glue("[{chars}]") + return(str_replace_all(s, regexp, "")) +} + +stripchars("She was a soul stripper. She took my heart!", "aei") +stripchars("Bet you can't do this one! ^.*?({})[\\-|]+$", "\\^.*?({})[\\-|]+$") diff --git a/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-1.rs b/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-1.rs index dae9f91804..19ab1e93e6 100644 --- a/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-1.rs +++ b/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-1.rs @@ -1,9 +1,9 @@ -fn strip_characters(original : &str, to_strip : &str) -> String { +fn strip_characters(original: &str, to_strip: &str) -> String { let mut result = String::new(); for c in original.chars() { if !to_strip.contains(c) { - result.push(c); - } + result.push(c); + } } result } diff --git a/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-2.rs b/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-2.rs index 1e1f913724..7156545772 100644 --- a/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-2.rs +++ b/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-2.rs @@ -1,3 +1,10 @@ -fn strip_characters(original : &str, to_strip : &str) -> String { - original.chars().filter(|&c| !to_strip.contains(c)).collect() +fn strip_characters(original: &str, to_strip: &str) -> String { + original + .chars() + .filter(|&c| !to_strip.contains(c)) + .collect() +} + +fn strip_characters(original: &str, to_strip: &str) -> String { + original.split(|c| to_strip.contains(c)).collect() } diff --git a/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-3.rs b/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-3.rs index 54e13912c4..5ddcdfb18b 100644 --- a/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-3.rs +++ b/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-3.rs @@ -1,3 +1,6 @@ fn main() { - println!("{}", strip_characters("She was a soul stripper. She took my heart!", "aei")); + println!( + "{}", + strip_characters("She was a soul stripper. She took my heart!", "aei") + ); } diff --git a/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-4.rs b/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-4.rs new file mode 100644 index 0000000000..7c672be0e9 --- /dev/null +++ b/Task/Strip-a-set-of-characters-from-a-string/Rust/strip-a-set-of-characters-from-a-string-4.rs @@ -0,0 +1,13 @@ +fn strip_characters(original: &str, to_strip: &[char]) -> String { + original.split(to_strip).collect() +} + +fn main() { + println!( + "{}", + strip_characters( + "She was a soul stripper. She took my heart!", + &['a', 'e', 'i'] + ) + ); +} diff --git a/Task/Strip-comments-from-a-string/APL/strip-comments-from-a-string.apl b/Task/Strip-comments-from-a-string/APL/strip-comments-from-a-string.apl new file mode 100644 index 0000000000..2e03104cbc --- /dev/null +++ b/Task/Strip-comments-from-a-string/APL/strip-comments-from-a-string.apl @@ -0,0 +1 @@ +strip ← {(~⌽∧\⌽' '=z)/z←(∧\~⍵∊⍺)/⍵} diff --git a/Task/Strip-comments-from-a-string/Emacs-Lisp/strip-comments-from-a-string.l b/Task/Strip-comments-from-a-string/Emacs-Lisp/strip-comments-from-a-string.l new file mode 100644 index 0000000000..8975cbf492 --- /dev/null +++ b/Task/Strip-comments-from-a-string/Emacs-Lisp/strip-comments-from-a-string.l @@ -0,0 +1,5 @@ +(string-trim (string-trim-right " apples, pears # and bananas" "[#;].+")) + +(string-trim (string-trim-right " apples, pears ; and bananas" "[#;].+")) + +(string-trim (string-trim-right " apples, pears and bananas " "[#;].+")) diff --git a/Task/Strip-comments-from-a-string/Refal/strip-comments-from-a-string.refal b/Task/Strip-comments-from-a-string/Refal/strip-comments-from-a-string.refal new file mode 100644 index 0000000000..bf150ccff8 --- /dev/null +++ b/Task/Strip-comments-from-a-string/Refal/strip-comments-from-a-string.refal @@ -0,0 +1,23 @@ +$ENTRY Go { + = > + >; +}; + +StripComments { + e.X = >; +}; + +Trim { + e.X ' ' = ; + e.X = e.X; +}; + +StripAll { + () e.X = e.X; + (s.C e.C) e.X = >; +}; + +Strip { + s.C e.X s.C e.Y = e.X; + s.C e.X = e.X; +}; diff --git a/Task/Strip-comments-from-a-string/SETL/strip-comments-from-a-string.setl b/Task/Strip-comments-from-a-string/SETL/strip-comments-from-a-string.setl new file mode 100644 index 0000000000..f3d4167c40 --- /dev/null +++ b/Task/Strip-comments-from-a-string/SETL/strip-comments-from-a-string.setl @@ -0,0 +1,13 @@ +program strip_comments; + print(strip(";#", "apples, pears # and bananas")); + print(strip(";#", "apples, pears ; and bananas")); + print(strip(";#", "apples, pears")); + + proc strip(comment_chars, s); + if exists c = s(i) | c in comment_chars then + s := s(..i-1); + end if; + rspan(s, "\n\t "); + return s; + end proc; +end program; diff --git a/Task/Strip-control-codes-and-extended-characters-from-a-string/Rust/strip-control-codes-and-extended-characters-from-a-string.rs b/Task/Strip-control-codes-and-extended-characters-from-a-string/Rust/strip-control-codes-and-extended-characters-from-a-string.rs index 92f8c4b9dc..1f72750488 100644 --- a/Task/Strip-control-codes-and-extended-characters-from-a-string/Rust/strip-control-codes-and-extended-characters-from-a-string.rs +++ b/Task/Strip-control-codes-and-extended-characters-from-a-string/Rust/strip-control-codes-and-extended-characters-from-a-string.rs @@ -1,7 +1,7 @@ fn stripped(tostrip: &str) -> String { return tostrip .chars() - .filter(|c| (*c as u32) < 127 && *c as u32 > 31) + .filter(|c| !c.is_ascii_control() && c.is_ascii()) .collect(); } diff --git a/Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail-1.cpp b/Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail-1.cpp new file mode 100644 index 0000000000..58c17deb73 --- /dev/null +++ b/Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail-1.cpp @@ -0,0 +1,47 @@ +#include +#include + +constexpr std::string_view spaces{ " \t\n\v\f" }; + +constexpr std::string_view trim_start(std::string_view str) { + if (auto beg = str.find_first_not_of(spaces); beg != str.npos) { + return str.substr(beg); + } + + return str.substr(str.size()); +} + +constexpr std::string_view trim_end(std::string_view str) { + if (auto end = str.find_last_not_of(spaces); end != str.npos) { + return str.substr(0, end + 1); + } + + return str.substr(0, 0); +} + +constexpr std::string_view trim(std::string_view str) { + auto beg = str.find_first_not_of(spaces); + if (beg == str.npos) { + return str.substr(str.size()); + } + auto end = str.find_last_not_of(spaces); + + return str.substr(beg, end - beg + 1); +} + +int main() { + using std::string_view; + using std::cout; + + string_view test_phrase{ " There are unwanted blanks here! " }; + string_view left_trimmed = trim_start(test_phrase); + string_view right_trimmed = trim_end(test_phrase); + + cout << "The test phrase is :\"" << test_phrase << "\"\n"; + cout << "Trimmed on the left side :\"" << left_trimmed << "\"\n"; + cout << "Trimmed on the right side :\"" << right_trimmed << "\"\n"; + + string_view trimmed = trim(test_phrase); + + cout << "Trimmed on both sides :\"" << trimmed << "\"\n"; +} diff --git a/Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail.cpp b/Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail-2.cpp similarity index 54% rename from Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail.cpp rename to Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail-2.cpp index ce5f4a1eaf..f5b58e9af7 100644 --- a/Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail.cpp +++ b/Task/Strip-whitespace-from-a-string-Top-and-tail/C++/strip-whitespace-from-a-string-top-and-tail-2.cpp @@ -6,10 +6,10 @@ int main( ) { std::string testphrase( " There are unwanted blanks here! " ) ; std::string lefttrimmed = boost::trim_left_copy( testphrase ) ; std::string righttrimmed = boost::trim_right_copy( testphrase ) ; - std::cout << "The test phrase is :" << testphrase << "\n" ; - std::cout << "Trimmed on the left side :" << lefttrimmed << "\n" ; - std::cout << "Trimmed on the right side :" << righttrimmed << "\n" ; + std::cout << "The test phrase is :\"" << testphrase << "\"\n" ; + std::cout << "Trimmed on the left side :\"" << lefttrimmed << "\"\n" ; + std::cout << "Trimmed on the right side :\"" << righttrimmed << "\"\n" ; boost::trim( testphrase ) ; - std::cout << "Trimmed on both sides :" << testphrase << "\n" ; + std::cout << "Trimmed on both sides :\"" << testphrase << "\"\n" ; return 0 ; } diff --git a/Task/Strong-and-weak-primes/EasyLang/strong-and-weak-primes.easy b/Task/Strong-and-weak-primes/EasyLang/strong-and-weak-primes.easy index 09c7d57538..bbffd2c449 100644 --- a/Task/Strong-and-weak-primes/EasyLang/strong-and-weak-primes.easy +++ b/Task/Strong-and-weak-primes/EasyLang/strong-and-weak-primes.easy @@ -1,21 +1,19 @@ fastfunc isprim num . i = 3 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 2 . return 1 . -func nextprim n . +fastfunc nextprim n . repeat n += 2 until isprim n = 1 . return n . -proc strwkprimes ncnt sgn . . +proc strwkprimes ncnt sgn . write "First " & ncnt & ": " pr2 = 2 pr3 = 3 diff --git a/Task/Strong-and-weak-primes/REXX/strong-and-weak-primes.rexx b/Task/Strong-and-weak-primes/REXX/strong-and-weak-primes.rexx index fd8065eba8..3b2116497b 100644 --- a/Task/Strong-and-weak-primes/REXX/strong-and-weak-primes.rexx +++ b/Task/Strong-and-weak-primes/REXX/strong-and-weak-primes.rexx @@ -1,50 +1,55 @@ -/*REXX program lists a sequence (or a count) of ──strong── or ──weak── primes. */ -parse arg N kind _ . 1 . okind; upper kind /*obtain optional arguments from the CL*/ -if N=='' | N=="," then N= 36 /*Not specified? Then assume default.*/ -if kind=='' | kind=="," then kind= 'STRONG' /* " " " " " */ -if _\=='' then call ser 'too many arguments specified.' -if kind\=='WEAK' & kind\=='STRONG' then call ser 'invalid 2nd argument: ' okind -if kind =='WEAK' then weak= 1; else weak= 0 /*WEAK is a binary value for function.*/ -w = linesize() - 1 /*obtain the usable width of the term. */ -tell= (N>0); @.=; N= abs(N) /*N is negative? Then don't display. */ -!.=0; !.1=2; !.2=3; !.3=5; !.4=7; !.5=11; !.6=13; !.7=17; !.8=19; !.9=23; #= 8 -@.=''; @.2=1; @.3=1; @.5=1; @.7=1; @.11=1; @.13=1; @.17=1; @.19=1; start= # + 1 -m= 0; lim= 0 /*# is the number of low primes so far*/ -$=; do i=3 for #-2 while lim<=N /* [↓] find primes, and maybe show 'em*/ - call strongWeak i-1; $= strip($) /*go see if other part of a KIND prime.*/ - end /*i*/ /* [↑] allows faster loop (below). */ - /* [↓] N: default lists up to 35 #'s.*/ - do j=!.#+2 by 2 while limN then do; lim= y; m= m-1; end; else call app; return 1 -app: if tell then if length($ y)>w then do; say $; $= y; end; else $= $ y; return 1 -ser: say; say; say '***error***' arg(1); say; say; exit 13 /*tell error message. */ -commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -strongWeak: parse arg x; Lp= x - 1; Hp= x + 1; y=!.x; s= (!.Lp + !.Hp) / 2 - if weak then if ys then return add() /*is an strong prime.*/ - return 0 /*not " " " */ +call Primes 1e8 +call Task 'Strong',36 +call Task 'Weak',37 +call Task 'Balanced',30 +call Task 'Strong',1e6 +call Task 'Weak',1e6 +call Task 'Balanced',1e6 +call Task 'Strong',1e7 +call Task 'Weak',1e7 +call Task 'Balanced',1e7 +call Task 'Strong',1e8 +call Task 'Weak',1e8 +call Task 'Balanced',1e8 +say Format(Time('e'),,3) 'seconds' +exit + +Task: +procedure expose prim. flag. +parse arg xx,yy +v = (yy<1e3) +if v then + say 'First' yy xx 'primes' +else + say xx 'primes below' yy +n = 0 +do i = 2 to prim.0-1 + if \ v & prim.i > yy then + leave + im = i-1; ip = i+1; a = (prim.im+prim.ip)/2 + s = (prim.i > a); t = (prim.i < a); u = (prim.i = a) + if xx = 'Strong' & s | xx = 'Weak' & t | xx = 'Balanced' & u then do + n = n+1 + if v then do + call Charout ,prim.i' ' + if n = yy then + leave + end + end +end +if v then + say +say n 'found' +say +return + +include Sequences +include Functions +include Abend diff --git a/Task/Subleq/EasyLang/subleq.easy b/Task/Subleq/EasyLang/subleq.easy index d1c65d1470..2d996fb92c 100644 --- a/Task/Subleq/EasyLang/subleq.easy +++ b/Task/Subleq/EasyLang/subleq.easy @@ -2,9 +2,7 @@ global inpos inp$ . func inp . if inpos = 0 inp$ = input - if error = 1 - return 255 - . + if error = 1 : return 255 inpos = 1 . if inpos <= len inp$ @@ -15,7 +13,7 @@ func inp . inpos = 0 return 10 . -proc subleq . mem[] . +proc subleq &mem[] . repeat a = mem[p] b = mem[p + 1] diff --git a/Task/Substitution-cipher/EasyLang/substitution-cipher.easy b/Task/Substitution-cipher/EasyLang/substitution-cipher.easy index b59a2aec52..f8a9055c54 100644 --- a/Task/Substitution-cipher/EasyLang/substitution-cipher.easy +++ b/Task/Substitution-cipher/EasyLang/substitution-cipher.easy @@ -1,13 +1,11 @@ alpha$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" key$ = "VsciBjedgrzyHalvXZKtUPumGfIwJxqOCFRApnDhQWobLkESYMTN" # -proc subst in$ . out$ a$ b$ . +proc subst in$ &out$ &a$ &b$ . out$ = "" for c$ in strchars in$ p = strpos a$ c$ - if p > 0 - c$ = substr b$ p 1 - . + if p > 0 : c$ = substr b$ p 1 out$ &= c$ . . diff --git a/Task/Substitution-cipher/JavaScript/substitution-cipher.js b/Task/Substitution-cipher/JavaScript/substitution-cipher.js new file mode 100644 index 0000000000..a6dd7e8c8a --- /dev/null +++ b/Task/Substitution-cipher/JavaScript/substitution-cipher.js @@ -0,0 +1,30 @@ +const key = "]kYV}(!7P$n5_0i R:?jOWtF/=-pe'AD&@r6%ZXs\"v*N[#wSl9zq2^+g;LoB`aGh{3.HIu4fbK)mU8|dMET><,Qc\\C1yxJ"; + +function encode(s) { + let result = ''; + + for (let i = 0; i < s.length; i++) { + result += key[s.charCodeAt(i) - 32]; + } + + return result; +} + +function decode(s) { + let result = ''; + + for (let i = 0; i < s.length; i++) { + result += String.fromCharCode(key.indexOf(s[i]) + 32); + } + + return result; +} + +function main() { + const s = "The quick brown fox jumps over the lazy dog, who barks VERY loudly!"; + const enc = encode(s); + console.log("Encoded: ", enc); + console.log("Decoded: ", decode(enc)); +} + +main(); diff --git a/Task/Substring/K/substring.k b/Task/Substring/K/substring.k new file mode 100644 index 0000000000..8e5147e2c5 --- /dev/null +++ b/Task/Substring/K/substring.k @@ -0,0 +1,32 @@ +string: "the cow goes over the moon" +substring: "cow" +char:"g" +n:2 +m:4 + +"string: " +"the cow goes over the moon" +" " + +// without first n characters with cut _ +"without first n (2) characters " +{n_x}string + +// without last character ; reverse and remove last then reverse +"without last character" +{|1_|x}"the cow goes over the moon" + +// string from char g until end ; find char with where & and then cut +"string from char g until end" +{((&char=x)[0])_x}string + +// substring of m length from character g ; same as above only flatten with ,// +"substring of m (4) length from character g " +{x[,//(&char=x)[0]+ !m]}string + +// from substring of length m ; find firstindex of substring; check if substring; checks if the characters are in order with < +"from substring of length m" +firstindex:({&x[0]=string}'(((#substring);1)#substring))[0][0] +issubstring:1=*/(!#substring)= (<{&x[0]=string}'(((#substring);1)#substring)) +// if issubstring display; else do nothing +$[issubstring; ({x[firstindex+!m]}string);""] diff --git a/Task/Subtractive-generator/EasyLang/subtractive-generator.easy b/Task/Subtractive-generator/EasyLang/subtractive-generator.easy index 105948c2ab..73fd0a963f 100644 --- a/Task/Subtractive-generator/EasyLang/subtractive-generator.easy +++ b/Task/Subtractive-generator/EasyLang/subtractive-generator.easy @@ -3,7 +3,7 @@ len state[] 55 arrbase state[] 0 global si sj . funcdecl subrand . -proc subrand_seed p1 . . +proc subrand_seed p1 . p2 = 1 state[0] = p1 mod MOD j = 21 @@ -21,9 +21,7 @@ proc subrand_seed p1 . . . . func subrand . - if si = sj - subrand_seed 0 - . + if si = sj : subrand_seed 0 si = (si - 1) mod 55 sj = (sj - 1) mod 55 x = (state[si] - state[sj]) mod MOD diff --git a/Task/Successive-prime-differences/EasyLang/successive-prime-differences.easy b/Task/Successive-prime-differences/EasyLang/successive-prime-differences.easy index 98b850a968..cae380afee 100644 --- a/Task/Successive-prime-differences/EasyLang/successive-prime-differences.easy +++ b/Task/Successive-prime-differences/EasyLang/successive-prime-differences.easy @@ -1,33 +1,25 @@ fastfunc isprim num . i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 . -func nextprime n . +fastfunc nextprime n . n += 1 - while isprim n = 0 - n += 1 - . + while isprim n = 0 : n += 1 return n . func spd n d[] . - if isprim n = 0 - return 0 - . + if isprim n = 0 : return 0 for i = 1 to len d[] - if nextprime n <> n + d[i] - return 0 - . + if nextprime n <> n + d[i] : return 0 n += d[i] . return 1 . -proc print_set n d[] . . +proc print_set n d[] . write "( " & n & " " for i = 1 to len d[] write n + d[i] & " " @@ -35,18 +27,14 @@ proc print_set n d[] . . . print ")" . -proc show max d[] . . +proc show max d[] . write "Differences of " - for d in d[] - write d & " " - . + for d in d[] : write d & " " print "" for n = 2 to max - d[len d[]] if spd n d[] = 1 c += 1 - if c = 1 - print_set n d[] - . + if c = 1 : print_set n d[] last = n . . diff --git a/Task/Successive-prime-differences/REXX/successive-prime-differences.rexx b/Task/Successive-prime-differences/REXX/successive-prime-differences.rexx index 3ea18b4c27..c91c012135 100644 --- a/Task/Successive-prime-differences/REXX/successive-prime-differences.rexx +++ b/Task/Successive-prime-differences/REXX/successive-prime-differences.rexx @@ -1,45 +1,54 @@ -/*REXX program finds and displays primes with successive differences (up to a limit).*/ -parse arg H . 1 . difs /*allow the highest number be specified*/ -if H=='' | H=="," then H= 1000000 /*Not specified? Then use the default.*/ -if difs='' then difs= 2 1 2.2 2.4 4.2 6.4.2 /* " " " " " " */ -call genP H +-- 12 Apr 2025 +include Settings - do j=1 for words(difs) /*traipse through the lists.*/ - dif= translate( word(difs, j),,.); dw= words(dif) /*obtain true differences. */ - do i=1 for dw; dif.i= word(dif, i) /*build an array of diffs. */ - end /*i*/ /* [↑] for optimization. */ - say center('primes with differences of:' dif, 50, '─') /*display title.*/ - p= 1; c= 0; grp= /*init. prime#, count, grp.*/ - do a=1; p= nextP(p+1); if p==0 then leave /*find the next DIF primes*/ - aa= p; !.= /*AA: nextP; the group #'s.*/ - !.1= p /*assign 1st prime in group.*/ - do g=2 for dw /*get the rest of the group.*/ - aa= nextP(aa+1); if aa==0 then leave a /*obtain the next prime. */ - !.g= aa; _= g-1 /*prepare to add difference.*/ - if !._ + dif._\==!.g then iterate a /*determine if fits criteria*/ - end /*g*/ - c= c+1 /*bump count of # of groups.*/ - grp= !.1; do b=2 for dw; grp= grp !.b /*build a list of primes. */ - end /*b*/ - if c==1 then say ' first group: ' grp /*display the first group. */ - end /*a*/ - /* [↓] test if group found.*/ - if grp=='' then say " (none)" /*display the last group. */ - else say ' last group: ' grp /* " " " " */ - say ' count: ' c /* " " group count. */ - say - end /*j*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -nextP: do nxt=arg(1) to H; if @.nxt==. then return nxt; end /*nxt*/; return 0 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: procedure expose @.; parse arg N; != 0; @.=.; @.1= /*initialize the array.*/ - do e=4 by 2 for (N-1)%2; @.e=; end /*treat the even integers > 2 special.*/ - /*all primes are indicated with a "." */ - do j=1 by 2 for (N-1)%2 /*use odd integers up to N inclusive.*/ - if @.j==. then do; if ! then iterate /*Prime? Should skip the top part ? */ - jj= j * j /*compute the square of J. ___ */ - if jj>N then != 1 /*indicate skip top part if j > √ N */ - do m=jj to N by j+j; @.m=; end /*odd multiples.*/ - end /* [↑] strike odd multiples ¬ prime. */ - end /*j*/; return +call Time('r') +say 'SUCCESSIVE PRIME DIFFERENCES' +say version +say +call Primes 1e6 +say 'For the' prim.0 'primes up to 1 million...' +say +call Task 1 +call Task 2 +call Task 2,2 +call Task 2,4 +call Task 4,2 +call Task 2,4,6 +call Task 2,4,6,8 +call Task 2,4,6,8,10 +call Task 2,4,6,8,10,12 +call Task 2,4,6,8,10,12,14 +call Task 32,16,8,4,2 +say Format(Time('e'),,3) 'seconds' +exit + +Task: +procedure expose prim. +diffs = ''; first = ''; last = '' +do i = 1 to Arg() + diffs = diffs||Arg(i)' ' +end +count = 0 +do i = 1 to prim.0-Arg() + a = prim.i; work = a; k = i + do j = 1 to Arg() + k = k+1; b = prim.k + if b-a <> Arg(j) then + iterate i + work = work b; a = b + end + count = count+1 + if first = '' then + first = work + last = work +end +say 'Differences ' diffs +say 'First group ' first +say 'Last group ' last +say 'Groups found' count +say +return + +include Sequences +include Functions +include Abend diff --git a/Task/Sudan-function/Rust/sudan-function.rs b/Task/Sudan-function/Rust/sudan-function.rs new file mode 100644 index 0000000000..b0cd006337 --- /dev/null +++ b/Task/Sudan-function/Rust/sudan-function.rs @@ -0,0 +1,15 @@ +fn sudan1(n: usize, x: usize, y: usize) -> usize { + match (n, y) { + (0, _) => x + y, + (_, 0) => x, + _ => sudan1(n - 1, sudan1(n, x, y - 1), sudan1(n, x, y - 1) + y) + } +} + +fn sudan2(n: usize, x: usize, y: usize) -> usize { + if n == 0 { x + y } + else if y == 0 { x } + else { + sudan2(n - 1, sudan2(n, x, y - 1), sudan2(n, x, y - 1) + y) + } +} diff --git a/Task/Sudoku/EasyLang/sudoku.easy b/Task/Sudoku/EasyLang/sudoku.easy index fe0cbf2195..8bb837333c 100644 --- a/Task/Sudoku/EasyLang/sudoku.easy +++ b/Task/Sudoku/EasyLang/sudoku.easy @@ -3,7 +3,7 @@ len col[] 90 len box[] 90 len grid[] 82 # -proc init . . +proc init . for pos = 1 to 81 if pos mod 9 = 1 s$ = input @@ -31,7 +31,7 @@ proc init . . . init # -proc display . . +proc display . for i = 1 to 81 write grid[i] & " " if i mod 3 = 0 @@ -46,7 +46,7 @@ proc display . . . . # -proc solve pos . . +proc solve pos . while grid[pos] <> 0 pos += 1 . diff --git a/Task/Sum-digits-of-an-integer/Nu/sum-digits-of-an-integer.nu b/Task/Sum-digits-of-an-integer/Nu/sum-digits-of-an-integer-1.nu similarity index 100% rename from Task/Sum-digits-of-an-integer/Nu/sum-digits-of-an-integer.nu rename to Task/Sum-digits-of-an-integer/Nu/sum-digits-of-an-integer-1.nu diff --git a/Task/Sum-digits-of-an-integer/Nu/sum-digits-of-an-integer-2.nu b/Task/Sum-digits-of-an-integer/Nu/sum-digits-of-an-integer-2.nu new file mode 100644 index 0000000000..ce216c50d5 --- /dev/null +++ b/Task/Sum-digits-of-an-integer/Nu/sum-digits-of-an-integer-2.nu @@ -0,0 +1,13 @@ + ( [['0b0' 2] [1 10] [1234 10] ['0xfe' 16] ['0xf0e' 16]] | + each {|n| + let base = $n.1 + let num = match $base { + 16 => {$n.0 | str replace '0x' '' | str downcase}, + 2 => {$n.0 | str replace '0b' '' | str downcase}, + _ => {$n.0 | into string}, + } + # Split the number into characters and sum the digits + $num | split chars | each {|digit| + $digit | into int -r $base + } | math sum + } ) diff --git a/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series-1.alg b/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series-1.alg new file mode 100644 index 0000000000..f57825d08b --- /dev/null +++ b/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series-1.alg @@ -0,0 +1,10 @@ +begin + +comment - calculate sum from k = 1 to 1000 of the sequence 1 / k^2; +real k, sum; +sum := 0; +for k := 1 step 1 until 1000 do + sum := sum + 1 / (k * k); +outreal(1,sum); outstring(1,"\n"); + +end diff --git a/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series-2.alg b/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series-2.alg new file mode 100644 index 0000000000..0bb6f36d89 --- /dev/null +++ b/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series-2.alg @@ -0,0 +1,24 @@ +begin + +comment - return the nth term of the sequence; +real procedure fterm (n); real n; +begin + fterm := 1.0 / (n*n); +end; + +comment - display the nth value of the series, + i.e., the sum of the first n terms of the + sequence defined by f; +procedure showsum (n, f); + value n; integer n; real procedure f; +begin + real x, sum; + sum := 0; + for x := 1 step 1 until n do + sum := sum + f(x); + outreal(1, sum); outstring(1,"\n"); +end; + +showsum(1000, fterm); + +end diff --git a/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series.alg b/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series.alg deleted file mode 100644 index 55260b26a2..0000000000 --- a/Task/Sum-of-a-series/ALGOL-60/sum-of-a-series.alg +++ /dev/null @@ -1,18 +0,0 @@ -begin - -comment - return sum from a to b of the series 1 / k^2; - -real procedure suminvsq(a, b); - value a, b; real a, b; -begin - real k, sum; - sum := 0; - for k := a step 1 until b do - sum := sum + 1 / (k * k); - suminvsq := sum; -end; - -comment - show result for 1..1000 -outreal(1,suminvsq(1,1000)); - -end diff --git a/Task/Sum-of-a-series/EasyLang/sum-of-a-series.easy b/Task/Sum-of-a-series/EasyLang/sum-of-a-series.easy index 539c8d6c05..683f94fae2 100644 --- a/Task/Sum-of-a-series/EasyLang/sum-of-a-series.easy +++ b/Task/Sum-of-a-series/EasyLang/sum-of-a-series.easy @@ -1,4 +1,4 @@ -numfmt 8 0 +numfmt 0 8 for i = 1 to 1000 s += 1 / (i * i) . diff --git a/Task/Sum-of-a-series/S-BASIC/sum-of-a-series.basic b/Task/Sum-of-a-series/S-BASIC/sum-of-a-series.basic new file mode 100644 index 0000000000..54acd278b5 --- /dev/null +++ b/Task/Sum-of-a-series/S-BASIC/sum-of-a-series.basic @@ -0,0 +1,11 @@ +var k, sum = real.double +sum = 0 +k = 1 +while k <= 1000 do + begin + sum = sum + (1 / (k * k)) + k = k + 1 + end +print using "#.######"; sum + +end diff --git a/Task/Sum-of-a-series/TypeScript/sum-of-a-series.ts b/Task/Sum-of-a-series/TypeScript/sum-of-a-series.ts new file mode 100644 index 0000000000..ddbfc76c4f --- /dev/null +++ b/Task/Sum-of-a-series/TypeScript/sum-of-a-series.ts @@ -0,0 +1,5 @@ +function s(n:number): number { + return [...Array(n).keys()].map(k => 1 / (1+k)**2).reduce((a, b) => a + b); +} + +console.log( s(1000) ) diff --git a/Task/Sum-of-elements-below-main-diagonal-of-matrix/EasyLang/sum-of-elements-below-main-diagonal-of-matrix.easy b/Task/Sum-of-elements-below-main-diagonal-of-matrix/EasyLang/sum-of-elements-below-main-diagonal-of-matrix.easy index 9832dc0943..de573fb844 100644 --- a/Task/Sum-of-elements-below-main-diagonal-of-matrix/EasyLang/sum-of-elements-below-main-diagonal-of-matrix.easy +++ b/Task/Sum-of-elements-below-main-diagonal-of-matrix/EasyLang/sum-of-elements-below-main-diagonal-of-matrix.easy @@ -1,11 +1,10 @@ -proc sumbd . m[][] r . - r = 0 +func sumbd &m[][] . for i = 2 to len m[][] for j = 1 to i - 1 r += m[i][j] . . + return r . m[][] = [ [ 1 3 7 8 10 ] [ 2 4 16 14 4 ] [ 3 1 9 18 11 ] [ 12 14 17 18 20 ] [ 7 1 3 9 5 ] ] -sumbd m[][] r -print r +print sumbd m[][] diff --git a/Task/Sum-of-elements-below-main-diagonal-of-matrix/Quackery/sum-of-elements-below-main-diagonal-of-matrix.quackery b/Task/Sum-of-elements-below-main-diagonal-of-matrix/Quackery/sum-of-elements-below-main-diagonal-of-matrix.quackery new file mode 100644 index 0000000000..cc32c57366 --- /dev/null +++ b/Task/Sum-of-elements-below-main-diagonal-of-matrix/Quackery/sum-of-elements-below-main-diagonal-of-matrix.quackery @@ -0,0 +1,10 @@ +[ 0 swap witheach + [ i^ split drop + 0 swap witheach + + ] ] is sumbelow ( [ --> n ) + +' [ [ 1 3 7 8 10 ] + [ 2 4 16 14 4 ] + [ 3 1 9 18 11 ] + [ 12 14 17 18 20 ] + [ 7 1 3 9 5 ] ] +sumbelow echo diff --git a/Task/Sum-to-100/EasyLang/sum-to-100.easy b/Task/Sum-to-100/EasyLang/sum-to-100.easy index ad5820f9e0..4306c8b04c 100644 --- a/Task/Sum-to-100/EasyLang/sum-to-100.easy +++ b/Task/Sum-to-100/EasyLang/sum-to-100.easy @@ -24,13 +24,13 @@ func evaluate code . . return value . -proc init . . +proc init . for i = 0 to nexpr f[i] = evaluate i . . call init -proc out code . . +proc out code . a = 19683 b = 6561 for k = 1 to 9 diff --git a/Task/Superellipse/EasyLang/superellipse.easy b/Task/Superellipse/EasyLang/superellipse.easy index d6f40685ab..0eebece6bb 100644 --- a/Task/Superellipse/EasyLang/superellipse.easy +++ b/Task/Superellipse/EasyLang/superellipse.easy @@ -1,10 +1,12 @@ n = 2.5 a = 200 b = 200 -linewidth 0.2 +glinewidth 0.2 while t <= 360 - x = pow abs cos t (2 / n) * a * sign cos t - y = pow abs sin t (2 / n) * b * sign sin t - line x / 5 + 50 y / 5 + 50 + xp = x + yp = y + x = (pow abs cos t (2 / n) * a * sign cos t) / 5 + 50 + y = (pow abs sin t (2 / n) * b * sign sin t) / 5 + 50 + if t > 0 : gline xp yp x y t += 0.5 . diff --git a/Task/Sutherland-Hodgman-polygon-clipping/Zig/sutherland-hodgman-polygon-clipping.zig b/Task/Sutherland-Hodgman-polygon-clipping/Zig/sutherland-hodgman-polygon-clipping.zig new file mode 100644 index 0000000000..65f5f374ef --- /dev/null +++ b/Task/Sutherland-Hodgman-polygon-clipping/Zig/sutherland-hodgman-polygon-clipping.zig @@ -0,0 +1,151 @@ +const std = @import("std"); +const print = std.debug.print; +const ArrayList = std.ArrayList; + +const Point = struct { + x: f64, + y: f64, + + pub fn format( + self: Point, + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = fmt; + _ = options; + try writer.print("Point{{ x: {d}, y: {d} }}", .{ self.x, self.y }); + } +}; + +const Polygon = struct { + points: ArrayList(Point), + + pub fn init(allocator: std.mem.Allocator) Polygon { + return Polygon{ + .points = ArrayList(Point).init(allocator), + }; + } + + pub fn deinit(self: *Polygon) void { + self.points.deinit(); + } + + pub fn clone(self: Polygon, allocator: std.mem.Allocator) !Polygon { + var new_polygon = Polygon.init(allocator); + try new_polygon.points.appendSlice(self.points.items); + return new_polygon; + } + + pub fn format( + self: Polygon, + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = fmt; + _ = options; + try writer.print("Polygon{{", .{}); + for (self.points.items, 0..) |point, i| { + try writer.print(" {}", .{point}); + if (i < self.points.items.len - 1) { + try writer.print(",", .{}); + } + } + try writer.print(" }}", .{}); + } +}; + +fn isInside(p: Point, cp1: Point, cp2: Point) bool { + return (cp2.x - cp1.x) * (p.y - cp1.y) > (cp2.y - cp1.y) * (p.x - cp1.x); +} + +fn computeIntersection(cp1: Point, cp2: Point, s: Point, e: Point) Point { + const dc = Point{ + .x = cp1.x - cp2.x, + .y = cp1.y - cp2.y, + }; + const dp = Point{ + .x = s.x - e.x, + .y = s.y - e.y, + }; + const n1 = cp1.x * cp2.y - cp1.y * cp2.x; + const n2 = s.x * e.y - s.y * e.x; + const n3 = 1.0 / (dc.x * dp.y - dc.y * dp.x); + + return Point{ + .x = (n1 * dp.x - n2 * dc.x) * n3, + .y = (n1 * dp.y - n2 * dc.y) * n3, + }; +} + +fn sutherlandHodgmanClip(allocator: std.mem.Allocator, subject_polygon: Polygon, clip_polygon: Polygon) !Polygon { + var result_ring = try subject_polygon.clone(allocator); + + if (clip_polygon.points.items.len == 0) { + return result_ring; + } + + var cp1 = clip_polygon.points.items[clip_polygon.points.items.len - 1]; + + for (clip_polygon.points.items) |cp2| { + var input = try result_ring.clone(allocator); + defer input.deinit(); + + result_ring.points.clearRetainingCapacity(); + + if (input.points.items.len == 0) { + continue; + } + + var s = input.points.items[input.points.items.len - 1]; + + for (input.points.items) |e| { + if (isInside(e, cp1, cp2)) { + if (!isInside(s, cp1, cp2)) { + try result_ring.points.append(computeIntersection(cp1, cp2, s, e)); + } + try result_ring.points.append(e); + } else if (isInside(s, cp1, cp2)) { + try result_ring.points.append(computeIntersection(cp1, cp2, s, e)); + } + s = e; + } + + cp1 = cp2; + } + + return result_ring; +} + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer _ = gpa.deinit(); + + var subject_polygon = Polygon.init(allocator); + defer subject_polygon.deinit(); + + try subject_polygon.points.append(.{ .x = 50.0, .y = 150.0 }); + try subject_polygon.points.append(.{ .x = 200.0, .y = 50.0 }); + try subject_polygon.points.append(.{ .x = 350.0, .y = 150.0 }); + try subject_polygon.points.append(.{ .x = 350.0, .y = 300.0 }); + try subject_polygon.points.append(.{ .x = 250.0, .y = 300.0 }); + try subject_polygon.points.append(.{ .x = 200.0, .y = 250.0 }); + try subject_polygon.points.append(.{ .x = 150.0, .y = 350.0 }); + try subject_polygon.points.append(.{ .x = 100.0, .y = 250.0 }); + try subject_polygon.points.append(.{ .x = 100.0, .y = 200.0 }); + + var clip_polygon = Polygon.init(allocator); + defer clip_polygon.deinit(); + + try clip_polygon.points.append(.{ .x = 100.0, .y = 100.0 }); + try clip_polygon.points.append(.{ .x = 300.0, .y = 100.0 }); + try clip_polygon.points.append(.{ .x = 300.0, .y = 300.0 }); + try clip_polygon.points.append(.{ .x = 100.0, .y = 300.0 }); + + var result = try sutherlandHodgmanClip(allocator, subject_polygon, clip_polygon); + defer result.deinit(); + + print("{}\n", .{result}); +} diff --git a/Task/Sylvesters-sequence/EasyLang/sylvesters-sequence.easy b/Task/Sylvesters-sequence/EasyLang/sylvesters-sequence.easy index deda357e5b..e81753067c 100644 --- a/Task/Sylvesters-sequence/EasyLang/sylvesters-sequence.easy +++ b/Task/Sylvesters-sequence/EasyLang/sylvesters-sequence.easy @@ -1,4 +1,4 @@ -numfmt 8 0 +numfmt 0 8 for i = 1 to 10 if i = 1 sylv = 2 diff --git a/Task/Take-notes-on-the-command-line/Crystal/take-notes-on-the-command-line.cr b/Task/Take-notes-on-the-command-line/Crystal/take-notes-on-the-command-line.cr new file mode 100644 index 0000000000..e5f984ec6a --- /dev/null +++ b/Task/Take-notes-on-the-command-line/Crystal/take-notes-on-the-command-line.cr @@ -0,0 +1,9 @@ +NOTES = "NOTES.TXT" + +if ARGV.empty? + print File.read(NOTES) rescue nil +else + File.open NOTES, "a" do |f| + f.puts "#{Time.local}\n\t#{ARGV.join(" ")}" + end +end diff --git a/Task/Tau-number/REXX/tau-number.rexx b/Task/Tau-number/REXX/tau-number-1.rexx similarity index 100% rename from Task/Tau-number/REXX/tau-number.rexx rename to Task/Tau-number/REXX/tau-number-1.rexx diff --git a/Task/Tau-number/REXX/tau-number-2.rexx b/Task/Tau-number/REXX/tau-number-2.rexx new file mode 100644 index 0000000000..9956fc6292 --- /dev/null +++ b/Task/Tau-number/REXX/tau-number-2.rexx @@ -0,0 +1,34 @@ +-- 8 May 2025 +include Settings + +call Time('r') +say 'TAU NUMBER' +say version +say +call Task 100 +call Timer +exit + +Task: +procedure +arg xx +say 'First' xx ' tau numbers...' +n = 0 +do i = 1 until n = xx + a = Divisor(i) + if i//a = 0 then do + n = n+1 + call Charout ,Right(i,5) + if n//10 = 0 then + say + end +end +say +return + +include Sequences +include Functions +include Special +include Constants +include Helper +include Abend diff --git a/Task/Terminal-control-Clear-the-screen/X86-64-Assembly/terminal-control-clear-the-screen.x86-64 b/Task/Terminal-control-Clear-the-screen/X86-64-Assembly/terminal-control-clear-the-screen.x86-64 new file mode 100644 index 0000000000..07b1bb4835 --- /dev/null +++ b/Task/Terminal-control-Clear-the-screen/X86-64-Assembly/terminal-control-clear-the-screen.x86-64 @@ -0,0 +1,17 @@ +.intel_syntax noprefix +.global _start +.text +_start: + call cls + mov rax, 60 + xor rdi, rdi + syscall +cls: /* void cls(); */ + push 0x631b /* push "\033c" on to the stack */ + mov rdx, 2 /* number of charcters to write */ + mov rsi, rsp /* the string to write is at "top" of stack */ + mov rdi, 1 /* stdout is the stream to write to */ + mov rax, 1 /* 1 is the system call "write" */ + syscall /* execute the system call */ + add rsp, 8 /* restore the stack */ + ret /* return from subroutine. */ diff --git a/Task/Test-integerness/EasyLang/test-integerness.easy b/Task/Test-integerness/EasyLang/test-integerness.easy index 9b53110ed6..f1800d664c 100644 --- a/Task/Test-integerness/EasyLang/test-integerness.easy +++ b/Task/Test-integerness/EasyLang/test-integerness.easy @@ -1,11 +1,9 @@ func isint x . - if x mod 1 = 0 - return 1 - . + return if x mod 1 = 0 . num[] = [ 25.000000 24.999999 25.0001 -2.1e120 -5e-2 0 / 0 1 / 0 ] # -numfmt 10 0 +numfmt 0 10 for n in num[] write n & " -> " if isint n = 1 diff --git a/Task/Text-processing-1/Lua/text-processing-1.lua b/Task/Text-processing-1/Lua/text-processing-1.lua index 9fb810c572..a9a02e9022 100644 --- a/Task/Text-processing-1/Lua/text-processing-1.lua +++ b/Task/Text-processing-1/Lua/text-processing-1.lua @@ -5,10 +5,7 @@ file_sum, file_cnt_data, file_lines = 0, 0, 0 max_rejected, n_rejected = 0, 0 max_rejected_date, rejected_date = "", "" -while true do - data = io.read("*line") - if data == nil then break end - +for data in io.lines() do date = string.match( data, "%d+%-%d+%-%d+" ) if date == nil then break end @@ -24,9 +21,9 @@ while true do cnt = cnt + 1 n_rejected = 0 else - if n_rejected == 0 then - rejected_date = date - end + if n_rejected == 0 then + rejected_date = date + end n_rejected = n_rejected + 1 if n_rejected > max_rejected then max_rejected = n_rejected diff --git a/Task/Text-processing-1/XPL0/text-processing-1.xpl0 b/Task/Text-processing-1/XPL0/text-processing-1.xpl0 new file mode 100644 index 0000000000..3822ed843b --- /dev/null +++ b/Task/Text-processing-1/XPL0/text-processing-1.xpl0 @@ -0,0 +1,49 @@ +include xpllib; \for Print + +char File_name, C, Date(10+1), FalseDate(10+1); +int N, I, Flag, Count, FalseCount, FalseRun, Readings; +real Data, Line_tot, Line_avg, Total; + +[File_name:= "readings.txt"; +FSet(FOpen(File_name, 0), ^i); OpenI(3); +Total:= 0.; Readings:= 0; FalseCount:= 0; FalseRun:= 0; +loop + [for N:= 0 to 10-1 do + [C:= ChIn(3); + if C = LF then C:= ChIn(3); + if C = EOF then quit; + Date(N):= C; + ]; + Date(N):= 0; + + Line_tot:= 0.; Count:= 0; + for N:= 0 to 24-1 do + [Data:= RlIn(3); + Flag:= IntIn(3); + if Flag > 0 then + [Line_tot:= Line_tot + Data; + Count:= Count + 1; + FalseCount:= 0; + ] + else + [FalseCount:= FalseCount+1; + if FalseCount > FalseRun then + [FalseRun:= FalseCount; + for I:= 0 to 10 do FalseDate(I):= Date(I); + ]; + ]; + ]; + Total:= Total + Line_tot; + Readings:= Readings + Count; + Line_avg:= Line_tot / float(Count); + Print("Line: %s Reject: %2d Accept: %2d Line_tot: %4.3f Line_avg: %3.3f\n", + Date, 24-Count, Count, Line_tot, Line_avg); + ]; +Print("\nFile = %s\n", File_name); +Print("Total = %1.3f\n", Total); +Print("Readings = %d\n", Readings); +Print("Average = %1.3f\n", Total/float(Readings)); + +Print("\nMaximum run of %d consecutive false readings", FalseRun); +Print("\nends at line starting with date: %s\n", FalseDate); +] diff --git a/Task/Text-processing-2/ALGOL-68/text-processing-2.alg b/Task/Text-processing-2/ALGOL-68/text-processing-2.alg new file mode 100644 index 0000000000..2ff93bbb0d --- /dev/null +++ b/Task/Text-processing-2/ALGOL-68/text-processing-2.alg @@ -0,0 +1,164 @@ +BEGIN # Test processing/2 - using thee file from Text processing/1, # + # verify the format, detect duplicate dates and # + # count the number of records with all instruments # + # functioning # + + PR read "files.incl.a68" PR # include file utilities: EACHLINE, etc. # + + CHAR tab = REPR 9; + + INT instruments = 24; # expected number of instrument readings # + MODE READING = STRUCT( STRING date + , [ 1 : instruments ]REAL data + , [ 1 : instruments ]INT status + , BOOL format ok + , STRING message + ); + OP INIT = ( REF READING r )VOID: + BEGIN + FOR n TO instruments DO ( data OF r )[ n ] := ( status OF r )[ n ] := 0 OD; + format ok OF r := TRUE; + date OF r := ""; + message OF r := "" + END # INIT # ; + + INT all good count := 0; # number of lines which have all instruments ok # + STRING last date := ""; # date of the previous line # + + # return the date and instrument readings and status values on the line # + PROC parse readings = ( STRING line )READING: + BEGIN + BOOL data error := FALSE; + # returns v converted to a REAL, returns 0 and sets data error # + # to TRUE if v is invalid # + OP TOREAL = ( STRING v )REAL: + BEGIN + REAL value := 0; + FILE real value; + associate( real value, LOC STRING := v ); + on value error + ( real value + , ( REF FILE ef )BOOL: # "handles" invalid data and # + BEGIN # returns TRUE so processing # + value := 0; # can continue # + data error := TRUE + END + ); + get( real value, value ); + close( real value ); + value + END # TOREAL # ; + # returns v converted to an INT, returns 0 and sets data error # + # to TRUE if v is invalid # + OP TOINT = ( STRING text )INT: + BEGIN + INT value := 0; + BOOL is numeric := TRUE; + FOR ch pos FROM UPB text BY -1 TO LWB text WHILE is numeric DO + CHAR c = text[ ch pos ]; + IF c = "-" + THEN value := - value; + is numeric := ch pos = LWB text AND ch pos /= UPB text + ELSE is numeric := is numeric AND c >= "0" AND c <= "9"; + IF is numeric THEN ( value *:= 10 ) +:= ABS c - ABS "0" FI + FI + OD; + IF NOT is numeric THEN data error := TRUE FI; + value + END # TOINT # ; + # superficially checks v is in the format yyyy-mm-dd # + PROC check date format = ( STRING v )BOOL: + BEGIN + STRING ymd := v[ AT 1 ]; + IF NOT ( data error := UPB ymd /= 10 ) THEN + # length is correct for yyyy-mm-dd # + IF NOT ( data error := ymd[ 5 ] /= "-" OR ymd[ 8 ] /= "-" ) THEN + INT d; + d := ( TOINT ymd[ 1 : 4 ] * 10000 ) + + ( TOINT ymd[ 6 : 7 ] * 100 ) + + TOINT ymd[ 9 : 10 ] + FI + FI; + NOT data error + END # check date format # ; + + READING result; INIT result; + INT c pos := LWB line; + INT max pos = UPB line; + INT field number := 0; + WHILE c pos <= max pos DO + # skip leading spaces and tabs # + WHILE IF c pos > max pos + THEN FALSE + ELSE CHAR ch = line[ c pos ]; ch = " " OR ch = tab + FI + DO c pos +:= 1 OD; + IF c pos <= max pos THEN # have a field # + INT start pos = c pos; + WHILE IF c pos > max pos + THEN FALSE + ELSE CHAR ch := line[ c pos ]; ch /= " " AND ch /= tab + FI + DO c pos +:= 1 OD; + STRING f := line[ start pos : c pos - 1 ]; + IF ( field number +:= 1 ) = 1 THEN # the date # + IF NOT check date format( f ) THEN + format ok OF result := FALSE; + message OF result := "Invalid date: " + f + FI; + date OF result := f + ELIF INT instrument = field number OVER 2; + instrument > instruments THEN + format ok OF result := FALSE; # too many readings # + message OF result := "Too many instruments" + ELIF ODD field number THEN + # field 3, 5, 7... the instrument state of reading # + ( status OF result )[ field number OVER 2 ] := TOINT f; + IF data error THEN + format ok OF result := FALSE; + message OF result := "Invalid status for instrument " + whole( instrument, 0 ) + FI + ELSE # must be the instrument reading # + ( data OF result )[ field number OVER 2 ] := TOREAL f; + IF data error THEN + format ok OF result := FALSE; + message OF result := "Invalid reading for instrument " + whole( instrument, 0 ) + FI + FI + FI + OD; + IF format ok OF result AND field number /= 2 * instruments + 1 THEN + format ok OF result := FALSE; + message OF result := "Incorrect number of readings/status values" + FI; + result + END # parse readings # ; + + # checks the readings and date on line # + PROC check readings = ( STRING line, INT line count )BOOL: + BEGIN + READING data := parse readings( line ); + IF format ok OF data AND line count > 1 AND date OF data = last date THEN + format ok OF data := FALSE; + message OF data := "Duplicate date: " + date OF data + FI; + IF NOT format ok OF data THEN # line has invalid data # + print( ( "Line: ", whole( line count, 0 ), ": ", message OF data, newline ) ) + ELSE # the line appears ok # + BOOL all good := TRUE; + FOR i TO instruments WHILE all good := ( status OF data )[ i ] > 0 DO SKIP OD; + IF all good THEN all good count +:= 1 FI; + last date := date OF data + FI; + TRUE + END # check readings # ; + + IF STRING file name = "readings.txt"; + INT total lines = file name EACHLINE check readings; + total lines < 0 + THEN print( ( "Unable to open ", file name, newline ) ) + ELSE print( ( whole( total lines, 0 ), " lines in ", file name, ", " ) ); + print( ( whole( all good count, 0 ), " have all instruments in a good state.", newline ) ) + FI + +END diff --git a/Task/Text-processing-2/FreeBASIC/text-processing-2.basic b/Task/Text-processing-2/FreeBASIC/text-processing-2.basic new file mode 100644 index 0000000000..c499b5e543 --- /dev/null +++ b/Task/Text-processing-2/FreeBASIC/text-processing-2.basic @@ -0,0 +1,128 @@ +#include "datetime.bi" + +Const filename = "readings.txt" +Const readings = 24 ' per line +Const fields = readings*2 + 1 ' per line +Const dateFormat = "%Y-%m-%d" + +Type DateRecord + fecha As String + hasGoodRecord As Boolean +End Type + +' Array to store unique dates +Dim Shared As DateRecord dateRecords(Any) + +' Function to check if a fecha exists in our array +Function findDate(dateArray() As DateRecord, dateStr As String, count As Integer) As Integer + For i As Integer = 0 To count - 1 + If dateArray(i).fecha = dateStr Then Return i + Next + Return -1 +End Function + +Sub main() + Dim As Integer ff, flag, dateIndex, i, partCount + Dim As Integer allGood = 0, uniqueGood = 0, dateCount = 0 + Dim As String linea, dateStr, currentPart, c + Dim As Double value + Dim As Boolean good + + + ff = Freefile + If Open(filename For Input As #ff) <> 0 Then + Print "Error: Could not open file '" & filename & "'" + Exit Sub + End If + + ' Process each line + While Not Eof(ff) + Line Input #ff, linea + + ' Split the line into fields + Dim As String parts(0 To fields-1) + partCount = 0 + currentPart = "" + + ' Optimized string parsing + For i = 1 To Len(linea) + c = Mid(linea, i, 1) + If c = " " Or c = Chr(9) Then ' Space or Tab + If Len(currentPart) > 0 Then + parts(partCount) = currentPart + partCount += 1 + currentPart = "" + End If + Else + currentPart &= c + End If + Next + + ' Add the last part if it exists + If Len(currentPart) > 0 Then + parts(partCount) = currentPart + partCount += 1 + End If + + ' Check if we have the expected number of fields + If partCount <> fields Then + Print "Error: Unexpected format, " & partCount & " fields." + Close #ff + Exit Sub + End If + + ' Get the date + dateStr = parts(0) + + ' Check if all readings are good + good = True + For i = 1 To fields-1 Step 2 + flag = Val(parts(i+1)) + If flag > 0 Then + value = Val(parts(i)) + If value = 0 And parts(i) <> "0" And parts(i) <> "0.000" Then + Print "Error: Could not convert '" & parts(i) & "' to integer." + Close #ff + Exit Sub + End If + Else + good = False + Exit For + End If + Next + + If good Then allGood += 1 + + dateIndex = findDate(dateRecords(), dateStr, dateCount) + + If dateIndex >= 0 Then + Print "Duplicate datestamp: " & dateStr + If good And Not dateRecords(dateIndex).hasGoodRecord Then + dateRecords(dateIndex).hasGoodRecord = True + uniqueGood += 1 + End If + Else + ' New date + If dateCount > Ubound(dateRecords) Then + Redim Preserve dateRecords(Ubound(dateRecords) + 100) + End If + + dateRecords(dateCount).fecha = dateStr + dateRecords(dateCount).hasGoodRecord = good + + If good Then uniqueGood += 1 + + dateCount += 1 + End If + Wend + + Close #ff + + Print !"\nData format valid." + Print allGood & " records with good readings for all instruments." + Print uniqueGood & " unique dates with good readings for all instruments." +End Sub + +main() + +Sleep diff --git a/Task/Text-processing-2/Lua/text-processing-2.lua b/Task/Text-processing-2/Lua/text-processing-2.lua index e7680645e4..bd9f36afdd 100644 --- a/Task/Text-processing-2/Lua/text-processing-2.lua +++ b/Task/Text-processing-2/Lua/text-processing-2.lua @@ -5,10 +5,7 @@ dates = {} duplicated, bad_format = {}, {} num_good_records, lines_total = 0, 0 -while true do - line = io.read( "*line" ) - if line == nil then break end - +for line in io.lines() do lines_total = lines_total + 1 date = string.match( line, "%d+%-%d+%-%d+" ) diff --git a/Task/Text-processing-2/XPL0/text-processing-2.xpl0 b/Task/Text-processing-2/XPL0/text-processing-2.xpl0 new file mode 100644 index 0000000000..43c7974864 --- /dev/null +++ b/Task/Text-processing-2/XPL0/text-processing-2.xpl0 @@ -0,0 +1,42 @@ +include xpllib; \for Print, StrCmp and StrCopy + +int Records, Invalid, AllGood; +char File_name, C, Date(10+1), LastDate(10+1); +int N, Flag, Count; +real Data; + +[File_name:= "readings.txt"; +Print("File = %s\n", File_name); +Print("\nDuplicated dates:\n"); +FSet(FOpen(File_name, 0), ^i); OpenI(3); + +Records:= 0; Invalid:= 0; AllGood:= 0; +LastDate(0):= 0; +loop + [for N:= 0 to 10-1 do + [C:= ChIn(3); + if C = LF then C:= ChIn(3); + if C = EOF then quit; + Date(N):= C; + ]; + Date(N):= 0; + if Date(0)#^1 and Date(0)#^2 then Invalid:= Invalid+1; + if StrCmp(Date, LastDate) = 0 then + Print("%s\n", Date); + StrCopy(LastDate, Date); + Records:= Records+1; + + Count:= 0; + for N:= 0 to 24-1 do + [Data:= RlIn(3); + Flag:= IntIn(3); + if Flag > 0 then + Count:= Count+1; + ]; + if Count = 24 then AllGood:= AllGood+1; + ]; +Print("\nTotal number of records : %d\n", Records); +Print("Number of invalid records : %d\n", Invalid); +Print("Number which are all good : %d (%1.2f^%)\n", + AllGood, float(AllGood)/float(Records)*100.0); +] diff --git a/Task/Text-processing-Max-licenses-in-use/Lua/text-processing-max-licenses-in-use.lua b/Task/Text-processing-Max-licenses-in-use/Lua/text-processing-max-licenses-in-use.lua index 0c56849d95..65a4b7eb43 100644 --- a/Task/Text-processing-Max-licenses-in-use/Lua/text-processing-max-licenses-in-use.lua +++ b/Task/Text-processing-Max-licenses-in-use/Lua/text-processing-max-licenses-in-use.lua @@ -1,24 +1,17 @@ filename = "mlijobs.txt" -io.input( filename ) max_out, n_out = 0, 0 occurr_dates = {} -while true do - line = io.read( "*line" ) - if line == nil then break end - - if string.find( line, "OUT" ) ~= nil then - n_out = n_out + 1 - if n_out > max_out then +for line in io.lines(filename) + local dispensed = string.find( line, "OUT" ) + n_out = n_out + (dispensed==true and 1 or -1) + if dispensed and n_out >= max_out then + if n_out > max_out then max_out = n_out occurr_dates = {} - occurr_dates[#occurr_dates+1] = string.match( line, "@ ([%d+%p]+)" ) - elseif n_out == max_out then - occurr_dates[#occurr_dates+1] = string.match( line, "@ ([%d+%p]+)" ) - end - else - n_out = n_out - 1 + end + occurr_dates[#occurr_dates+1] = string.match( line, "@ ([%d+%p]+)" ) end end diff --git a/Task/The-Name-Game/EasyLang/the-name-game.easy b/Task/The-Name-Game/EasyLang/the-name-game.easy index bf40f74c86..b26adb387b 100644 --- a/Task/The-Name-Game/EasyLang/the-name-game.easy +++ b/Task/The-Name-Game/EasyLang/the-name-game.easy @@ -1,4 +1,4 @@ -proc verse x$ . . +proc verse x$ . x1$ = substr x$ 1 1 y$ = substr x$ 2 99 if strpos "AEIOU" x1$ <> 0 diff --git a/Task/The-sieve-of-Sundaram/EasyLang/the-sieve-of-sundaram.easy b/Task/The-sieve-of-Sundaram/EasyLang/the-sieve-of-sundaram.easy index 5dd88b4cb7..f851e74ca4 100644 --- a/Task/The-sieve-of-Sundaram/EasyLang/the-sieve-of-sundaram.easy +++ b/Task/The-sieve-of-Sundaram/EasyLang/the-sieve-of-sundaram.easy @@ -1,7 +1,7 @@ func log n . return log10 n / log10 2.71828182845904523 . -proc sundaram np . primes[] . +proc sundaram np &primes[] . nmax = floor (np * (log np + log log np) - 0.9385) + 1 k = (nmax - 2) / 2 len marked[] k diff --git a/Task/The-sieve-of-Sundaram/REXX/the-sieve-of-sundaram.rexx b/Task/The-sieve-of-Sundaram/REXX/the-sieve-of-sundaram.rexx index c66127eda0..8825dc83a0 100644 --- a/Task/The-sieve-of-Sundaram/REXX/the-sieve-of-sundaram.rexx +++ b/Task/The-sieve-of-Sundaram/REXX/the-sieve-of-sundaram.rexx @@ -1,33 +1,62 @@ -/*REXX program finds & displays N Sundaram primes, or displays the Nth Sundaram prime.*/ -parse arg n cols . /*get optional number of primes to find*/ -if n=='' | n=="," then n= 100 /*Not specified? Then assume default.*/ -if cols=='' | cols=="," then cols= 10 /* " " " " " */ -@.= .; lim= 16 * n /*default value for array; filter limit*/ - do j=1 for n; do k=1 for n until _>lim; _= j + k + 2*j*k; @._= - end /*k*/ - end /*j*/ -w= 10 /*width of a number in any column. */ - title= 'a list of ' commas(N) " Sundaram primes" -if cols>0 then say ' index │'center(title, 1 + cols*(w+1) ) -if cols>0 then say '───────┼'center("" , 1 + cols*(w+1), '─') -#= 0; idx= 1 /*initialize # of Sundaram primes & IDX*/ -$= /*a list of Sundaram primes (so far). */ - do j=1 until #==n /*display the output (if cols > 0). */ - if @.j\==. then iterate /*Is the number not prime? Then skip. */ - #= # + 1 /*bump number of Sundaram primes found.*/ - a= j /*save J for calculating the Nth prime.*/ - if cols<=0 then iterate /*Build the list (to be shown later)? */ - c= commas(j + j + 1) /*maybe add commas to Sundaram prime.*/ - $= $ right(c, max(w, length(c) ) ) /*add Sundaram prime──►list, allow big#*/ - if #//cols\==0 then iterate /*have we populated a line of output? */ - say center(idx, 7)'│' substr($, 2); $= /*display what we have so far (cols). */ - idx= idx + cols /*bump the index count for the output*/ - end /*j*/ - -if $\=='' then say center(idx, 7)"│" substr($, 2) /*possible display residual output.*/ -if cols>0 then say '───────┴'center("" , 1 + cols*(w+1), '─') +-- 25 Apr 2025 +include Settings +arg xx +say 'THE SIEVE OF SUNDARAM' +say version say -say 'found ' commas(#) " Sundaram primes, and the last Sundaram prime is " commas(a+a+1) -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? +call Collect 16e6 +call Task100 +call Task1e6 +call Timer +exit + +Collect: +procedure expose prim. work. +arg xx +say 'Collecting primes up to' xx'...' +work. = 1 +k = (xx-3)%2+1; m = (Isqrt(xx-3))%2+1 +do i = 0 to m + p = 2*i+3; s = (p*p-3)%2 + do j = s by p to k + work.j = 0 + end +end +prim. = 0; n = 0 +do i = 0 to k + if work.i then do + p = i+i+3 + if p > xx then + leave i + n = n+1; prim.n = p + end +end +prim.0 = n +say n 'found' +say +return n + +Task100: +procedure expose prim. +say 'First 100 Sundaram primes (excluding 2)...' +do i = 1 to 100 + call Charout ,Right(prim.i,4) + if i//10 = 0 then + say +end +say +return + +Task1e6: +procedure expose prim. +say '1 millionth Sundaram prime (excluding 2)...' +say prim.1000000 +say +return + +include Sequences +include Helper +include Numbers +include Functions +include Constants +include Abend diff --git a/Task/Thieles-interpolation-formula/Fortran/thieles-interpolation-formula.f b/Task/Thieles-interpolation-formula/Fortran/thieles-interpolation-formula.f new file mode 100644 index 0000000000..334028f3c8 --- /dev/null +++ b/Task/Thieles-interpolation-formula/Fortran/thieles-interpolation-formula.f @@ -0,0 +1,87 @@ +program thiele_trig_demo + use, intrinsic :: ieee_arithmetic + implicit none + integer, parameter :: n1 = 48 + integer, parameter :: n2 = n1 * (n1 - 1) / 2 + real(16), parameter :: pi = 4q0 * atan(1q0) + real(16), parameter :: paso = pi / (n1-1) + real(16) :: xVal(n1), tSin(n1), tCos(n1), tTan(n1) + real(16) :: res_sin, res_cos, res_tan, res_acos_neg1 + real(16) :: nan + integer :: i, n_half + real(16), allocatable :: rhot(:,:) + integer, parameter :: rSin=0, rCos=1, rTan=2, rTrig=2 + + nan = ieee_value(0.0q0, ieee_quiet_nan) + allocate(rhot(0:rTrig, 0:n2)) + rhot = nan + + ! Build the trig table + do i = 1, n1 + xVal(i) = (i-1) * paso + tSin(i) = sin(xVal(i)) + tCos(i) = cos(xVal(i)) + tTan(i) = tan(xVal(i)) + end do + + n_half = n1 / 2 + 1 ! covers [0, p/2] for arcsin and arctan + + print '(A,F16.12)', " PI : ", pi + print '(A,F16.12)', " 6*arcsin(0.5) : ", 6q0 * asin(0.5q0) + print '(A,F16.12)', " 3*arccos(0.5) : ", 3q0 * acos(0.5q0) + print '(A,F16.12)', " 4*arctan(1.0) : ", 4q0 * atan(1.0q0) + print '(A,F16.12)', " 1*arccos(-1.0): ", acos(-1.0q0) + + rhot = nan + res_sin = 6q0 * thieleInterpolator(tSin(1:n_half), xVal(1:n_half), rSin, 0.5q0, 0, n_half-1, rhot) + rhot = nan + res_cos = 3q0 * thieleInterpolator(tCos, xVal, rCos, 0.5q0, 0, n1-1, rhot) + rhot = nan + res_tan = 4q0 * thieleInterpolator(tTan(1:n_half), xVal(1:n_half), rTan, 1.0q0, 0, n_half-1, rhot) + rhot = nan + res_acos_neg1 = thieleInterpolator(tCos, xVal, rCos, -1.0q0, 0, n1-1, rhot) + print '(A,F16.12)', "6*thiele(tSin,xVal,rSin,0.5,0) : ", res_sin + print '(A,F16.12)', "3*thiele(tCos,xVal,rCos,0.5,0) : ", res_cos + print '(A,F16.12)', "4*thiele(tTan,xVal,rTan,1.0,0) : ", res_tan + print '(A,F16.12)', "1*thiele(tCos,xVal,rCos,-1.0,0): ", res_acos_neg1 + +contains + + recursive function rho(x, y, rdx, i, n, rhot) result(val) + real(16), intent(in) :: x(:), y(:) + integer, intent(in) :: rdx, i, n + real(16), intent(inout) :: rhot(0:,0:) + real(16) :: val + integer :: idx + + if (n < 0) then + val = 0q0 + return + end if + if (n == 0) then + val = y(i+1) + return + end if + + idx = (size(x)-1 - n) * (size(x) - n) / 2 + i + if (ieee_is_nan(rhot(rdx, idx))) then + rhot(rdx, idx) = (x(i+1) - x(i+1 + n)) / (rho(x, y, rdx, i, n-1, rhot) - rho(x, y, rdx, i+1, n-1, rhot)) & + + rho(x, y, rdx, i+1, n-2, rhot) + end if + val = rhot(rdx, idx) + end function rho + + recursive function thieleInterpolator(x, y, rdx, xin, n, nmax, rhot) result(val) + real(16), intent(in) :: x(:), y(:), xin + integer, intent(in) :: rdx, n, nmax + real(16), intent(inout) :: rhot(0:,0:) + real(16) :: val + + if (n > nmax) then + val = 1.0q0 + return + end if + val = rho(x, y, rdx, 0, n, rhot) - rho(x, y, rdx, 0, n-2, rhot) + (xin - x(n+1)) / thieleInterpolator(x, y, rdx, xin, n+1, nmax, rhot) + end function thieleInterpolator + +end program thiele_trig_demo diff --git a/Task/Thue-Morse/Zig/thue-morse.zig b/Task/Thue-Morse/Zig/thue-morse.zig new file mode 100644 index 0000000000..45a506d67f --- /dev/null +++ b/Task/Thue-Morse/Zig/thue-morse.zig @@ -0,0 +1,16 @@ +const std = @import("std"); + +fn thueMorse(comptime T: type, n: T) bool { + var r = n; + var s: u8 = @sizeOf(T); + + while (s > 0) : (s >>= 1) r ^= std.math.shr(T, r, s); + return r & 1 == 1; +} + +pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + for (0..63) |n| + try stdout.writeByte(if (thueMorse(@TypeOf(n), n)) '1' else '0'); + try stdout.writeByte('\n'); +} diff --git a/Task/Tic-tac-toe/APL/tic-tac-toe-1.apl b/Task/Tic-tac-toe/APL/tic-tac-toe-1.apl new file mode 100644 index 0000000000..4a50ac1e46 --- /dev/null +++ b/Task/Tic-tac-toe/APL/tic-tac-toe-1.apl @@ -0,0 +1,7 @@ +⎕IO←0 ⋄ t←1∘↑ ⋄ b←1∘↓ ⋄ c←{Z[?≢Z←⍸0=⍵]} ⍝ extract turn/board; cpu's move +y←{3::∇⍵⊣⎕←'no' ⋄ ⍞←'move (1-9): ' ⋄ 0=⍵[p←⍎12↓⍞]: p ⋄ 2⌷0 0} ⍝ your move +m←{((-,⊢)t⍵)@(0,{1=t⍵: y⍵ ⋄ c⍵}⍵)⊢⍵} ⍝ apply current player's move to board +w←{∨/3=|+/(0 0⍉B)⍪(0 0⍉⌽B)⍪B⍪⍉B←3 3⍴b⍵} ⍝ has game been won? +d←{⍵⊣⎕←' '⍪' '⍪⍨↑(⊣,' ',⊢)/3 3⍴'.XO'[0 1 ¯1⍳b⍵]} ⍝ display board +o←{0∊b⍵: 'XO'[1=t⍵],' wins' ⋄ 'tie'} ⍝ determine and print game outcome +g←{o d∘m⍣((w∨0~⍤∊b)⊣)10↑¯1} ⍝ game; move & display until won or full diff --git a/Task/Tic-tac-toe/APL/tic-tac-toe-2.apl b/Task/Tic-tac-toe/APL/tic-tac-toe-2.apl new file mode 100644 index 0000000000..d1f2edb155 --- /dev/null +++ b/Task/Tic-tac-toe/APL/tic-tac-toe-2.apl @@ -0,0 +1 @@ +g←{S←d m⍵ ⋄ w S: 'XO'[1=t S],' wins' ⋄ ~0∊b S: 'tie' ⋄ ∇S}10↑¯1⍨ diff --git a/Task/Tic-tac-toe/EasyLang/tic-tac-toe.easy b/Task/Tic-tac-toe/EasyLang/tic-tac-toe.easy index fffa6c4109..c7f605dbe6 100644 --- a/Task/Tic-tac-toe/EasyLang/tic-tac-toe.easy +++ b/Task/Tic-tac-toe/EasyLang/tic-tac-toe.easy @@ -1,47 +1,36 @@ len f[] 9 state = 0 -textsize 14 +gtextsize 14 # -proc init . . - linewidth 2 - clear - color 666 - move 34 96 - line 34 20 - move 62 96 - line 62 20 - move 10 72 - line 86 72 - move 10 44 - line 86 44 - linewidth 2.5 - for i = 1 to 9 - f[i] = 0 - . - if state = 1 - timer 0.2 - . +proc init . + glinewidth 2 + gclear + gcolor 666 + gline 34 96 34 20 + gline 62 96 62 20 + gline 10 72 86 72 + gline 10 44 86 44 + glinewidth 2.5 + for i = 1 to 9 : f[i] = 0 + if state = 1 : timer 0.2 . -proc draw ind . . +proc draw ind . c = (ind - 1) mod 3 r = (ind - 1) div 3 x = c * 28 + 20 y = r * 28 + 30 if f[ind] = 4 - color 900 - move x - 7 y - 7 - line x + 7 y + 7 - move x + 7 y - 7 - line x - 7 y + 7 + gcolor 900 + gline x - 7 y - 7 x + 7 y + 7 + gline x + 7 y - 7 x - 7 y + 7 elif f[ind] = 1 - color 009 - move x y - circle 10 - color -2 - circle 7.5 + gcolor 009 + gcircle x y 10 + gcolor -2 + gcircle x y 7.5 . . -proc sum3 a d . st . +proc sum3 a d &st . for i = 1 to 3 s += f[a] a += d @@ -52,34 +41,24 @@ proc sum3 a d . st . st = 1 . . -proc rate . res done . +proc rate &res &done . res = 0 - for i = 1 step 3 to 7 - sum3 i 1 res - . - for i = 1 to 3 - sum3 i 3 res - . + for i = 1 step 3 to 7 : sum3 i 1 res + for i = 1 to 3 : sum3 i 3 res sum3 1 4 res sum3 3 2 res cnt = 1 for i = 1 to 9 - if f[i] = 0 - cnt += 1 - . + if f[i] = 0 : cnt += 1 . res *= cnt done = 1 - if res = 0 and cnt > 1 - done = 0 - . + if res = 0 and cnt > 1 : done = 0 . -proc minmax player alpha beta . rval rmov . +proc minmax player alpha beta &rval &rmov . rate rval done if done = 1 - if player = 1 - rval = -rval - . + if player = 1 : rval = -rval else rval = alpha start = random 9 @@ -100,30 +79,27 @@ proc minmax player alpha beta . rval rmov . . . . -proc show_result val . . - color 555 - move 16 4 +proc show_result val . + gcolor 555 if val < 0 # this never happens - text "You won" + gtext 16 4 "You won" elif val > 0 - text "You lost" + gtext 16 4 "You lost" else - text "Tie" + gtext 16 4 "Tie" . state += 2 . -proc computer . . +proc computer . minmax 4 -11 11 val mov f[mov] = 4 draw mov rate val done state = 0 - if done = 1 - show_result val - . + if done = 1 : show_result val . -proc human . . +proc human . mov = floor ((mouse_x - 6) / 28) + 3 * floor ((mouse_y - 16) / 28) + 1 if f[mov] = 0 f[mov] = 1 diff --git a/Task/Tic-tac-toe/Factor/tic-tac-toe-1.factor b/Task/Tic-tac-toe/Factor/tic-tac-toe-1.factor new file mode 100644 index 0000000000..9bbbd5ad71 --- /dev/null +++ b/Task/Tic-tac-toe/Factor/tic-tac-toe-1.factor @@ -0,0 +1,22 @@ +USING: multiline math.vectors arrays sequences io.streams.c kernel assocs math io grouping math.matrices math.parser random strings ; IN: tictactoe + +CONSTANT: winmasks { 7 56 448 73 146 292 273 84 } +t 0 0 ! turn board1 board2 +[ + pick ! turn b1 b2 turn + [ 2dup bitor 9 f swap indices random set-bit ] ! cpu's move + [ [ 2dup bitor nl "enter a move (1-9):" print readln string>number 1 - tuck ! your move + [ nip [ 9 < ] [ 0 >= ] bi and ] [ bit? not ] 2bi and [ set-bit f ] [ drop "no" print t ] if + ] loop + ] if ! switch on turn + { { [ dup winmasks swap [ bitand bit-count 3 = ] curry any? ! check for win + ] [ pick "O" "X" ? " wins" append print f ] + } + { [ 2dup bitor 511 = ] [ "tie" print f ] ! check for tie + } [ t ] ! if neither, then loop + } cond + [ 3dup rot not [ swap ] when [ 9 >array ] bi@ 2 v*n v+ 3 ! display the board + [ nl [ ".XO" nth 1string " " append write ] each ] each nl + ] dip ! keep loop flag + [ not ] 3dip swapd ! negate turn; swap boards +] loop 3drop ! empty the stack when done diff --git a/Task/Tic-tac-toe/Factor/tic-tac-toe-2.factor b/Task/Tic-tac-toe/Factor/tic-tac-toe-2.factor new file mode 100644 index 0000000000..21e54238b0 --- /dev/null +++ b/Task/Tic-tac-toe/Factor/tic-tac-toe-2.factor @@ -0,0 +1,27 @@ +USING: multiline math.vectors arrays sequences io.streams.c kernel assocs math io grouping math.matrices math.parser random strings ; IN: tictactoe + +: open? ( pos board -- ? ) nth 0 = ; + +: full? ( board -- ? ) 0 swap member? not ; + +: won? ( board -- ? ) + 3 dup [ flip ] [ main-diagonal ] [ anti-diagonal ] tri 2array 3append [ sum abs 3 = ] any? ; + +: you ( -- position ) + "enter a move (1-9):" print readln string>number 1 - dup + [ 9 < ] [ 0 >= ] bi and [ drop "no" print you ] unless ; + +: cpu ( board -- ? ) [ [ 0 = ] dip and ] map-index sift random ; + +: pos ( cturn? board -- position ) swap 0 < [ cpu ] [ drop you ] if ; + +: move ( turn board -- nturn nboard ) + 2dup pos swap 2dup open? [ [ set-nth ] [ nip ] 3bi [ neg ] dip ] [ nip "no" print move ] if ; + +: show ( board -- ) + nl 3 [ [ 1 + "O.X" nth 1string " " append write ] each nl ] each ; + +: outcome ( turn board -- ) + [ neg ] dip won? [ 1 + "O.X" nth 1string " wins" append ] [ drop "tie" ] if nl print ; + +: ttt ( -- ) -1 9 0 [ move [ show ] keep dup [ won? ] [ full? ] bi or not ] loop outcome ; diff --git a/Task/Tic-tac-toe/J/tic-tac-toe-1.j b/Task/Tic-tac-toe/J/tic-tac-toe-1.j index ef06e6f43c..8d1d5e9411 100644 --- a/Task/Tic-tac-toe/J/tic-tac-toe-1.j +++ b/Task/Tic-tac-toe/J/tic-tac-toe-1.j @@ -1,8 +1,8 @@ -'`turn board open full'=. {.`}.`(0=[{board@])`(0-.@e.board) -'`cpu pos'=. (?@#{])@([:I.0=board)`(cpu`you@.(_1 1 i.turn)) -you=. $:@echo@'no'^:(-.@e.i.@9)@:<:@".@(1!:1)@1@echo@'enter a move (1–9):' -move=. pos ($:@][echo@'no')`(-@turn@], turn@]`[`(board@])})@.open ] -outcome=. 'tie'"_`(' wins',~ {&'.XO'@-@turn)@.won -show=. [ ''echo@, '',~ (,' '&,)/"1@({&'.XO')@(3 3$board) -won=. [: +./ 3 = [: | +/"1@(],|:,(<@0 1|:]),:<@0 1|:|.)@(3 3$board) -ttt=: [: outcome [: show@move^:(won-.@+.full)^:_. (10&{.@_1) +'`c t b'=. (?@#{])@([:I.0=b)`{.`}. NB. cpu's move; extract turn/board +v=. (0=]{b@[) :: 0 *. ]e.i.@9 NB. posn (y) valid and open on board (x)? +y=. ($:@[ echo@'no')^:(-.@v) _1+0".1!:1@1@echo@'move (1-9):' NB. your move +m=. (-,])@t [`(0,1+c`y@.(1=t)@])} ] NB. apply current player's move to board +o=. 'tie'"_`(' wins',~ {&'.XO'@-@t)@.w NB. print game outcome +d=. [ ''echo@, '',~ (,' '&,)/"1@({&'.XO')@(3 3$b) NB. display the board +w=. [:+./ 3 = |@(+/"1)@(],|:,(<@0 1|:|.),:<@0 1|:])@(3 3$b) NB. test whether game has been won +g=: [: o [: d@m^:(-.@w*.0 e.b)^:_. _1:,9#0: NB. game; move & display until won or full diff --git a/Task/Tic-tac-toe/J/tic-tac-toe-2.j b/Task/Tic-tac-toe/J/tic-tac-toe-2.j index 10d907e113..c4ab8cecc2 100644 --- a/Task/Tic-tac-toe/J/tic-tac-toe-2.j +++ b/Task/Tic-tac-toe/J/tic-tac-toe-2.j @@ -1 +1,8 @@ -Until=. {{u^:(-.@v)^:_.}} NB. apply u until condition v is true +'`c t b e x'=.(?@#{])@([:I.0=b)`{.`}.`echo`(1:Z:1:) NB. cpu's move; turn; board; print; exit +'`wm tm'=. (''e@, {&'.XO'@-@t ,' wins'"_)`([:e LF&,@'tie') NB. print win/tie message +i=. (0=]{b@[) ::0 -.@*. ]e.i.@9 NB. invalid posn? (x: state; y: posn) +y=. ($:@[ e@'no')^:i _1+0".@(1!:1@1)@e@'move (1-9):' NB. your move +m=. -@t , c`y@.(1=t) t@]`[`(b@])} ] NB. apply current player's move to board +d=. ''e@, '',~ (,' '&,)/"1@({&'.XO')@(3 3$b) NB. display the board +w=. 3 +./@:= |@(+/"1)@(],|:,(<@0 1|:|.),:<@0 1|:])@(3 3$b) NB. test whether game has been won +g=: [: d F.(([ [x@tm^:(0-.@e.b) [x@wm^:w)@m) 10{._1: NB. the game diff --git a/Task/Tic-tac-toe/J/tic-tac-toe-3.j b/Task/Tic-tac-toe/J/tic-tac-toe-3.j index 5d221db368..9a4e28668b 100644 --- a/Task/Tic-tac-toe/J/tic-tac-toe-3.j +++ b/Task/Tic-tac-toe/J/tic-tac-toe-3.j @@ -1 +1 @@ -ttt=: [: outcome [: show@move Until (won+.full) 10&{.@_1 +wm`tm`$:@.(1:i.~w,0-.@e.b)@([d)@m 10{._1 diff --git a/Task/Tic-tac-toe/J/tic-tac-toe-4.j b/Task/Tic-tac-toe/J/tic-tac-toe-4.j new file mode 100644 index 0000000000..99d78bd028 --- /dev/null +++ b/Task/Tic-tac-toe/J/tic-tac-toe-4.j @@ -0,0 +1,14 @@ +'`turn board'=. {.`}. +Until=. {{u^:(-.@:v)^:_.}} NB. apply u until v is true +full=. {{-. 0 e. board y}} NB. board is full (tie game) +open=. {{0 = x { board y}} NB. given pos is free on board +invalid=. {{-. (y open ::0 x) *. y e.i.9}} NB. test for invalid position +cpu=. {{(?#o) { o=.I.0=board y}} NB. cpu's move +pos=. {{cpu`you@.(1 = turn y)y}} NB. get cpu's or user's move +you=. {{y {{you x[echo'no'}}^:(y invalid p) p=.<:0".(1!:1)1[echo'move (1-9):'}} NB. your move +move=. {{(- turn y) , (turn y) (pos y)} board y}} NB. apply move to the board +outcome=. {{ 'tie'"_ ` {{('.XO'{~-turn y),' wins'}}@.won y}} NB. print game outcome +show=. {{y [ echo'','',~([,' ',])/"1 '.XO'{~3 3$board y}} NB. display the board +'`diag antid'=. {{(<0 1)|:y}} ` {{(<0 1)|:|.y}} NB. get (anti-)diagonal +won=. {{+./3=|+/"1 B,(|:B),(antid B),:diag B=.3 3$board y}} NB. has game been won? +game=: {{outcome (show@move Until (won+.full)) _1,9#0[y}} diff --git a/Task/Tic-tac-toe/JavaScript/tic-tac-toe-3.js b/Task/Tic-tac-toe/JavaScript/tic-tac-toe-3.js new file mode 100644 index 0000000000..5da4f41904 --- /dev/null +++ b/Task/Tic-tac-toe/JavaScript/tic-tac-toe-3.js @@ -0,0 +1,96 @@ +/* + + Board Positions: Win Lines by Id: + 0|1|2 0 --- | | | \/ + 3|4|5 1 --- | | | /\ + 6|7|8 2 --- | | | 6 7 + 3 4 5 + + About: This is a "too clever by half" way of checking for wins. + To explain, let's first consider some other ways to check for wins: + + - Naive: if( (board[0] == pin && board[1] == pin && board[2] == pin)) return true; ... and repeat for all other win lines + + - Bitboard optimized: if ( (board & WIN_LINE1) == WIN_LINE1 || (board & WIN_LINE2) ... and repeat for all other win lines + + - Hash: Maybe we could just hash the winning values? Nope: in general, the "noise" from other pins requires too many states to be practical + + - Regex: See the PHP example of this: https://rosettacode.org/wiki/Tic-tac-toe#PHP + + - Base 4 method: But, can we do better?!?!? What is the limit of the maximum we can parallelize our win checking? + Dare we quixotically hope for a Game-Terminal check of O(1)? YES!! Yes, indeed! + And, that is what the follow is: An optimized way of win checking using some clever abuses of numbering systems, + (and uhm, by doing a little bit more work in the makeMove function). But, trade-offs, doncha know... + + Overview: The insight into the way this works, is that instead of looking at the board state, we are instead going to focus on counting the pins in a win line. + For example, what if we had counters like this: + + X|.|. --> Win Line 0 Count = 1 + X|X|. --> Win Line 1 Count = 2 + X|.|. --> Win Line 2 Count = 1 + \-----> Win Lines 3,4,5,6,7 = 3,1,0,2,2 respectively + + This is sufficient to let us know when there is a win. But, of course, just like the other methods, it requires multiple checks to determine if there is a winning line. + + But, we note that the count won't exceed three or four, so let's serialize the counters into a base4 string, (where each digit is the count for a win line). + + Giving us [2 2 0 1 3 1 2 1].b4 [41433].b10 for the example above. (With Win Line 0 starting in the Least-Significant-Bit on the right) + + Now, this seems a bit promising, as the winning count of three is right there in the middle of the string of digits. Now, if we could just + find some way to filter it out. But, what way might that be? + + The hack: Perhaps there's a more elegant solution? (Let me know if you find one...) + Regardless, a functional, if ugly method we can use is to take advantage of the overlap between base 4, and binary. This allows us to keep our count "logic" in base 4, + but still use bitwise operations to check in parallel. + + Expanding on this, we start counting at ONE, rather than ZERO - relying on the fact that it will then overflow to the next digit when it reaches a count of 4, + since we are working in base 4. + (Note: This does require us to double the digits used for counting in our base 4 serialized string, in order to keep the win lines from intersecting each other.) + + Here is the initial base 4 win line count, with all the lines starting off empty: + [01 01 01 01 01 01 01 01].b4 [286331153].b10 + + And for the example above we have the following: + + [03 03 01 02 10 02 03 02].b4 [856834610].b10 + + Finally, in the binary version of the win line string, (with four binary digits corresponding to the two base 4 digits), it can be seen that the count "overflow", + (and thus a win), is going to be "visible" as a bit set in the third of the 4 binary digits group corresponding to the base 4 count. + [0011 0011 0001 0010 0100 0010 0011 0010].b2 + ^--- Here + + The advantage of this, is that now we can create a bitwise mask to target only those third bits like this: + [0100 0100 0100 0100 0100 0100 0100 0100].b2 + ^ ^ ^ ^ ^ ^ ^ ^ + + Then, just do a bitwise AND against that overflow mask, and Bob's your uncle! + + Admittedly, this is indeed overkill for TicTacToe, but it could theoretically have potential uses with larger N-in-a-row games. + +*/ +const LINE_COUNTS = [0x11111111, 0x11111111]; // [01 01 01 01 01 01 01 01].b4 +const WIN_MASK = 0x44444444; // [10 10 10 10 10 10 10 10].b4 +const LINES_BY_POS = [ + 0x1001001, //Pos 0 - [00 01 00 00 01 00 00 01].b4 + 0x10001, //Pos 1 - [00 00 00 01 00 00 00 01].b4 + 0x10100001, //Pos 2 - [01 00 01 00 00 00 00 01].b4 + 0x1010, //Pos 3 - [00 00 00 00 01 00 01 00].b4 + 0x11010010, //Pos 4 - [01 01 00 01 00 00 01 00].b4 + 0x100010, //Pos 5 - [00 00 01 00 00 00 01 00].b4 + 0x10001100, //Pos 6 - [01 00 00 00 01 01 00 00].b4 + 0x10100, //Pos 7 - [00 00 00 01 00 01 00 00].b4 + 0x1100100, //Pos 8 - [00 01 01 00 00 01 00 00].b4 +]; + + +function isGameOver(turn) { + if ( (LINE_COUNTS[turn] & WIN_LINE)) return true; //This is the entire glorious raison d'etre for all the above rigamarole + else if (moveCount >= TOTAL_MOVES) return true;//Cat's game + else return false; +} + +function makeMove(pos) { + //Update state + LINE_COUNTS[turn] += LINES_BY_POS[pos]; //Win line accounting + moveCount++; +} diff --git a/Task/Time-a-function/Lua/time-a-function.lua b/Task/Time-a-function/Lua/time-a-function.lua index 2344a8fcdf..e7a108419b 100644 --- a/Task/Time-a-function/Lua/time-a-function.lua +++ b/Task/Time-a-function/Lua/time-a-function.lua @@ -1,12 +1,14 @@ -function Test_Function() - for i = 1, 10000000 do - local s = math.log( i ) - s = math.sqrt( s ) - end +function bench(Function, ...) + local t = os.time() + local clock1 = os.clock() + Function(...) + local c = os.clock()-clock + return os.time()-t, c end -t1 = os.clock() - Test_Function() -t2 = os.clock() +function sleep(n) + local start = os.time() + repeat until os.time()-start==n +end -print( os.difftime( t2, t1 ) ) +print( bench(sleep, 2) ) diff --git a/Task/Time-a-function/REXX/time-a-function-2.rexx b/Task/Time-a-function/REXX/time-a-function-2.rexx index 0e752fd011..b8a590ac0f 100644 --- a/Task/Time-a-function/REXX/time-a-function-2.rexx +++ b/Task/Time-a-function/REXX/time-a-function-2.rexx @@ -1,27 +1,483 @@ -/*REXX program displays the elapsed time for a REXX function (or subroutine). */ -arg reps . /*obtain an optional argument from C.L.*/ -if reps=='' then reps=100000 /*Not specified? No, then use default.*/ -call time 'Reset' /*only the 1st character is examined. */ -junk = silly(reps) /*invoke the SILLY function (below). */ - /*───► CALL SILLY REPS also works.*/ +-- 22 Mar 2025 +arg count','prec +include Settings - /* The E is for elapsed time.*/ - /* │ ─ */ - /* ┌────◄───┘ */ - /* │ */ - /* ↓ */ -say 'function SILLY took' format(time("E"),,2) 'seconds for' reps "iterations." - /* ↑ */ - /* │ */ - /* ┌────────►───────┘ */ - /* │ */ - /* The above 2 for the FORMAT function displays the time with*/ - /* two decimal digits (rounded) past the decimal point). Using */ - /* a 0 (zero) would round the time to whole seconds. */ -exit /*stick a fork in it, we're all done. */ -/*────────────────────────────────────────────────────────────────────────────*/ -silly: procedure /*chew up some CPU time doing some silly stuff.*/ - do j=1 for arg(1) /*wash, apply, lather, rinse, repeat. ··· */ - @.j=random() date() time() digits() fuzz() form() xrange() queued() - end /*j*/ - return j-1 +say 'TIME A FUNCTION' +say version +say +call Parameters +call DoLoop +call DoForLoop +call DoToLoop +call DoForByLoop +call DoToByLoop +say +call Tarra +call IntegerAssign +call IntegerAdd +call IntegerMultiply +call IntegerDivide1 +call IntegerDivide2 +call IntegerRemainder +call IntegerPower +say +call FloatAssign +call FloatAdd +call FloatMultiply +call FloatDivide1 +call FloatDivide2 +call FloatRemainder +call FloatPower +call FloatFormula +say +call StringFunctions +call NumericFunctions +call DateFunctions +call TimeFunctions +say +call FixedParseVar +call DynamicParseVar +call ParseValue +say +call NoOperation +say +call IfThen +call SelectWhen +say +call CallProc +call CallProcParms +call CallRout +call CallRoutParms +say +call Interpreting +say +call Output +call Input +say +call Stems +say +call Average +return + +Parameters: +start = date() time() +if count = '' then + count = 1e6 +if prec = '' then + prec = 9 +parse version version +say 'Version' version +say 'Using loop counter' count/1e6 'million and' Digits() 'digits' +say +numeric digits prec +int1 = right(sqrt3(),prec%2); int2 = right(sqrt2(),prec%2) +if int2 > int1 then + parse value int2 int1 with int1 int2 +float1 = sqrt3()/1; float2 = sqrt2()/1 +tarra = 0; totelaps = 0; totcount = 0 +return + +DoLoop: +call Time('r') +do count +end +call Measure 'Do',1 +return + +DoForLoop: +call Time('r') +do n = 1 for count +end +call Measure 'Do for',1 +return + +DoToLoop: +call Time('r') +do n = 1 to count +end +call Measure 'Do to',1 +return + +DoForByLoop: +call Time('r') +do n = 1 for count by 1 +end +call Measure 'Do for by',1 +return + +DoToByLoop: +call Time('r') +do n = 1 to count by 1 +end +call Measure 'Do to by',1 +return + +Tarra: +call Time('r') +do n = 1 to 1e8 +end +tarra = Time('e')*count/1e8 +return + +IntegerAssign: +call Time('r') +do n = 1 to count + a = int1 +end +call Measure 'Integer assign',1 +return + +IntegerAdd: +call Time('r') +do n = 1 to count + a = int1+int2 +end +call Measure 'Integer +',1 +return + +IntegerMultiply: +call Time('r') +do n = 1 to count + a = int1*int2 +end +call Measure 'Integer *',1 +return + +IntegerDivide1: +call Time('r') +do n = 1 to count + a = int1/int2 +end +call Measure 'Integer /',1 +return + +IntegerDivide2: +call Time('r') +do n = 1 to count + a = int1//int2 +end +call Measure 'Integer //',1 +return + +IntegerRemainder: +call Time('r') +do n = 1 to count + a = int1%int2 +end +call Measure 'Integer %',1 +return + +IntegerPower: +call Time('r') +do n = 1 to count + a = int1**2 +end +call Measure 'Integer **',1 +return + +FloatAssign: +call Time('r') +do n = 1 to count + a = float1 +end +call Measure 'Float assign',1 +return + +FloatAdd: +call Time('r') +do n = 1 to count + a = float1+float2 +end +call Measure 'Float +',1 +return + +FloatMultiply: +call Time('r') +do n = 1 to count + a = float1*float2 +end +call Measure 'Float *',1 +return + +FloatDivide1: +call Time('r') +do n = 1 to count + a = float1/float2 +end +call Measure 'Float /',1 +return + +FloatDivide2: +call Time('r') +do n = 1 to count + a = float1//float2 +end +call Measure 'Float //',1 +return + +FloatRemainder: +call Time('r') +do n = 1 to count + a = float1%float2 +end +call Measure 'Float %',1 +return + +FloatPower: +call Time('r') +do n = 1 to count + a = float1**2 +end +call Measure 'Float **',1 +return + +FloatFormula: +call Time('r') +do n = 1 to count + a = (float1+float2) + (float1*float2) + (float1/float2) +end +call Measure 'Float formula',1 +return + +StringFunctions: +a = 'This is the first text'; b = 'This is the second text'; c = float1 +call Time('r') +do n = 1 to count + t = a||b + t = Abbrev('text',a) + t = Center(a,100) + t = Compare(a,b) + t = Copies(a,3) + t = Delstr(a,5,10) + t = Delword(a,2,3) + t = Format(c,1,5) + t = Insert(a,b,10) + t = Lastpos('text',a) + t = Left(a,10) + t = Length(a) + t = Overlay('xxx',a,3) + t = Pos('text',a) + t = Reverse(a) + t = Right(a,10) + t = Space(a) + t = Strip(a) + t = Substr(a,5,10) + t = Subword(a,2,2) + t = Translate(a,'xxx','the') + t = Verify(a,'the') + t = Word(a,3) + t = Wordindex(a,3) + t = Wordlength(a,3) + t = Wordpos('the',a) + t = Words(a) + t = Xrange('a','z') +end +call Measure 'String functions',28 +return + +NumericFunctions: +call Time('r') +do n = 1 to count + t = Abs(float1) + t = Max(float1,float2) + t = Min(float1,float2) + t = Random() + t = Sign(float1) + t = Trunc(float1) + t = Digits() +end +call Measure 'Numeric functions',7 +return + +DateFunctions: +call Time('r') +do n = 1 to count + t = Date('b') + t = Date('d') + t = Date('e') + t = Date('m') + t = Date('n') + t = Date('o') + t = Date('s') + t = Date('u') + t = Date('w') +end +call Measure 'Date functions',9 +return + +TimeFunctions: +call Time('r') +do n = 1 to count + t = Time('c') + t = Time('e') + t = Time('h') + t = Time('l') + t = Time('m') + t = Time('n') + t = Time('s') +end +call Measure 'Time functions',7 +return + +FixedParseVar: +t = '1,2,3,4,5,6,7,8,9,10' +call Time('r') +do n = 1 to count + parse var t rec1 ',' rec2 ',' rec3 ',' rec4 ',' rec5 ',' rec6 ',' rec7 ',' rec8 ',' rec9 ',' rec10 +end +call Measure 'Fixed parse var',1 +return + +DynamicParseVar: +t = '1,2,3,4,5,6,7,8,9,10' +call Time('r') +do n = 1 to count + do y = 1 to 10 + parse var t rec.y ',' t + end +end +call Measure 'Dynamic parse var',1 +return + +Parsevalue: +call Time('r') +do n = 1 to count + parse value float1 float2 with a,b +end +call Measure 'Parse value',1 +return + +NoOperation: +call Time('r') +do n = 1 to count + nop +end +call Measure 'No operation',1 +return + +IfThen: +call Time('r') +do n = 1 to count + if float1 = float1 then nop +end +call Measure 'If then',1 +return + +SelectWhen: +call Time('r') +do n = 1 to count + select + when float1 = float1 then nop + end +end +call Measure 'Select when',1 +return + +CallProc: +call Time('r') +do n = 1 to count + call Proc1 +end +call Measure 'Call procedure',1 +return + +CallProcParms: +call Time('r') +do n = 1 to count + call Proc2 1,2,3 +end +call Measure 'Call procedure arg',1 +return + +CallRout: +call Time('r') +do n = 1 to count + call Rout1 +end +call Measure 'Call routine',1 +return + +CallRoutParms: +call Time('r') +do n = 1 to count + call Rout2 1,2,3 +end +call Measure 'Call routine arg',1 +return + +Proc1: +procedure +return + +Proc2: +procedure +arg a,b,c +return + +Rout1: +return + +Rout2: +arg a,b,c +return + +Interpreting: +a = 'nop' +call Time('r') +do n = 1 to count + interpret a +end +call Measure 'Interpret',1 +return + +Output: +file = 'dummy.txt' +call Lineout file,,1 +call Time('r') +do n = 1 to count + call Lineout file,'Just a small line' +end +call Measure 'Output',1 +return + +Input: +file = 'dummy.txt' +call Time('r') +do n = 1 to count + t = Linein(file) +end +call Measure 'Input',1 +return + +Stems: +call Time('r') +do n = 1 to count + stem.n = n +end +call Measure 'Stem processing',1 +return + +Average: +totelaps = 1e6*totelaps/totcount +say Left('Average',20) round(totelaps,3) 'microsec =' round(1/totelaps,1) 'million clauses/sec' +say +say Left('Start run',20) start +say Left('Clauses processed',20) round(totcount/1e6,1) 'million' +say Left('Stop run',20) date() time() +return + +Measure: +parse arg measure,clauses +elaps = Time('e')-tarra +if elaps > 0 then do + totelaps = totelaps+elaps; totcount = totcount+count*clauses + elaps = 1e6*elaps/(count*clauses) + say Left(measure,20) round(elaps,3) 'microsec =' round(1/elaps,1) 'million clauses/sec' +end +else + say Left(measure,20) 'cannot perform measure, please try a higher count' +return + +include Functions +include Constants +include Abend diff --git a/Task/Time-a-function/REXX/time-a-function-3.rexx b/Task/Time-a-function/REXX/time-a-function-3.rexx deleted file mode 100644 index 4d8817660a..0000000000 --- a/Task/Time-a-function/REXX/time-a-function-3.rexx +++ /dev/null @@ -1,27 +0,0 @@ -/*REXX program displays the elapsed time for a REXX function (or subroutine). */ -arg reps . /*obtain an optional argument from C.L.*/ -if reps=='' then reps=100000 /*Not specified? No, then use default.*/ -call time 'Reset' /*only the 1st character is examined. */ -junk = silly(reps) /*invoke the SILLY function (below). */ - /*───► CALL SILLY REPS also works.*/ - - /* The J is for the CPU time used */ - /* │ by the REXX program since */ - /* ┌───────┘ since the time was RESET. */ - /* │ This is a Regina extension.*/ - /* ↓ */ -say 'function SILLY took' format(time("J"),,2) 'seconds for' reps "iterations." - /* ↑ */ - /* │ */ - /* ┌────────►───────┘ */ - /* │ */ - /* The above 2 for the FORMAT function displays the time with*/ - /* two decimal digits (rounded) past the decimal point). Using */ - /* a 0 (zero) would round the time to whole seconds. */ -exit /*stick a fork in it, we're all done. */ -/*────────────────────────────────────────────────────────────────────────────*/ -silly: procedure /*chew up some CPU time doing some silly stuff.*/ - do j=1 for arg(1) /*wash, apply, lather, rinse, repeat. ··· */ - @.j=random() date() time() digits() fuzz() form() xrange() queued() - end /*j*/ - return j-1 diff --git a/Task/Time-a-function/REXX/time-a-function-4.rexx b/Task/Time-a-function/REXX/time-a-function-4.rexx deleted file mode 100644 index d4b24082bd..0000000000 --- a/Task/Time-a-function/REXX/time-a-function-4.rexx +++ /dev/null @@ -1,485 +0,0 @@ -Main: -call Parameters -call DoToLoops -call DoForLoops -call Tarra -call IntegerAssign -call IntegerAdd -call IntegerSubtract -call IntegerMultiply -call IntegerDivide1 -call IntegerDivide2 -call IntegerRemainder -call IntegerPower -call FloatingAssign -call FloatingAdd -call FloatingSubtract -call FloatingMultiply -call FloatingDivide1 -call FloatingDivide2 -call FloatingRemainder -call FloatingPower -call Formula -call StringFunctions -call NumericFunctions -call FixedParseVar -call DynamicParseVar -call NoOperation -call IfThen -call SelectWhen -call IfElseIf -call CallProc -call CallProcParms -call CallRout -call CallRoutParms -call DateTime -call PushPullQueued -call Interpreting -call Output -call Input -call StemProcessing -return - -Parameters: -arg count digit -if count = '' then - count = 1e6 -if digit = '' then - digit = 9 -numeric digits digit -parse version version -say 'Version' version -say 'Using loop counter' count/1e6 'million and' digits() 'digits' -say -tarra = 0 -call time('r') -return - -DoToLoops: -call time('r') -do x = 1 to count*10 -end -call Measure 'Do ... to ...',10 -return - -DoForLoops: -call time('r') -do x = 1 for count*10 -end -call Measure 'Do ... for ...',10 -return - -Tarra: -call time('r') -do x = 1 to count*10 -end -tarra = time('e')/10 -return - -IntegerAssign: -call time('r') -do x = 1 to count*10 - a = 123 -end -call Measure 'Integer assign',10 -return - -IntegerAdd: -call time('r') -do x = 1 to count*10 - a = x+123 -end -call Measure 'Integer +',10 -return - -IntegerSubtract: -call time('r') -do x = 1 to count*10 - a = x-123 -end -call Measure 'Integer -',10 -return - -IntegerMultiply: -call time('r') -do x = 1 to count*10 - a = x*123 -end -call Measure 'Integer *',10 -return - -IntegerDivide1: -call time('r') -do x = 1 to count*10 - a = 123/3 -end -call Measure 'Integer /',10 -return - -IntegerDivide2: -call time('r') -do x = 1 to count*10 - a = x//123 -end -call Measure 'Integer //',10 -return - -IntegerRemainder: -call time('r') -do x = 1 to count*10 - a = x%123 -end -call Measure 'Integer %',10 -return - -IntegerPower: -call time('r') -do x = 1 to count*10 - a = 123**2 -end -call Measure 'Integer **',10 -return - -FloatingAssign: -call time('r') -do x = 1 to count*10 - a = 1.23 -end -call Measure 'Floating assign',10 -return - -FloatingAdd: -call time('r') -do x = 1 to count*10 - a = x+1.23 -end -call Measure 'Floating +',10 -return - -FloatingSubtract: -call time('r') -do x = 1 to count*10 - a = x-1.23 -end -call Measure 'Floating -',10 -return - -FloatingMultiply: -call time('r') -do x = 1 to count*10 - a = x*1.23 -end -call Measure 'Floating *',10 -return - -FloatingDivide1: -call time('r') -do x = 1 to count*10 - a = x/1.23 -end -call Measure 'Floating /',10 -return - -FloatingDivide2: -call time('r') -do x = 1 to count*10 - a = x//1.23 -end -call Measure 'Floating //',10 -return - -FloatingRemainder: -call time('r') -do x = 1 to count*10 - a = x%1.23 -end -call Measure 'Floating %',10 -return - -FloatingPower: -call time('r') -do x = 1 to count*10 - a = 1.23**2 -end -call Measure 'Floating **',10 -return - -Formula: -call time('r') -do x = 1 to count - a = ( (x+1.23) * (x-1.23) ) / ( (x*1.23) * (x/1.23) ) -end -call Measure 'Formula',1 -return - -StringFunctions: -a = 'this is the first text'; b = 'this is the second text'; c = 1.23 -call time('r') -do x = 1 to count - t = a||b - t = abbrev('text',a) - t = center(a,100) - t = compare(a,b) - t = copies(a,3) - t = delstr(a,5,10) - t = delword(a,2,3) - t = format(c,1,2) - t = insert(a,b,10) - t = lastpos('text',a) - t = left(a,10) - t = length(a) - t = overlay('paul',a,4) - t = pos('text',a) - t = reverse(a) - t = right(a,10) - t = space(a) - t = strip(a) - t = substr(a,5,10) - t = subword(a,2,2) - t = translate(a,'one','the') - t = verify(a,'the') - t = word(a,3) - t = wordindex(a,3) - t = wordlength(a,3) - t = wordpos('is the',a) - t = words(a) - t = xrange('a','z') -end -call Measure 'String functions',28 -return - -NumericFunctions: -a = -1.23; b = 1.23 -call time('r') -do x = 1 to count - t = abs(a) - t = max(a,b) - t = min(a,b) - t = random() - t = sign(a) - t = trunc(b) - t = digits() -end -call Measure 'Numeric functions',7 -return - -FixedParseVar: -t = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20' -call time('r') -do x = 1 to count - parse var t rec1 ',' rec2 ',' rec3 ',' rec4 ',' rec5 ',' rec6 ',' rec7 ',' rec8 ',' rec9 ',' rec10 ',', - rec11 ',' rec12 ',' rec13 ',' rec14 ',' rec15 ',' rec16 ',' rec17 ',' rec18 ',' rec19 ',' rec20 ',' -end -call Measure 'Fixed parse var',1 -return - -DynamicParseVar: -t = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20' -call time('r') -do x = 1 to count - do y = 1 to 20 - parse var t rec.y ',' t - end -end -call Measure 'Dynamic parse var',1 -return - -NoOperation: -call time('r') -do x = 1 to count*10 - nop -end -call Measure 'No operation',10 -return - -IfThen: -a = 1 -call time('r') -do x = 1 to count - if a = 1 then nop - if a = 2 then nop - if a <> 1 then nop - if a <> 2 then nop - if a < 0 then nop - if a < 2 then nop - if a > 0 then nop - if a > 2 then nop -end -call Measure 'If ...then ...',8 -return - -SelectWhen: -a = 2 -call time('r') -do x = 1 to count - select - when a = 1 then nop - when a = 2 then nop - when a = 3 then nop - end - select - when a <> 2 then nop - when a <> 1 then nop - when a <> 0 then nop - end - select - when a > 2 then nop - when a > 1 then nop - when a > 0 then nop - end - select - when a < 2 then nop - when a < 3 then nop - when a < 4 then nop - end -end -call Measure 'Select ... when ...',8 -return - -IfElseIf: -a = 2 -call time('r') -do x = 1 to count - if a = 1 then nop - else if a = 2 then nop - else if a = 3 then nop - if a <> 2 then nop - else if a <> 1 then nop - else if a <> 0 then nop - if a > 2 then nop - else if a > 1 then nop - else if a > 0 then nop - if a < 2 then nop - else if a < 3 then nop - else if a < 4 then nop -end -call Measure 'If ... else if ...',8 -return - -CallProc: -call time('r') -do x = 1 to count - call Proc1 -end -call Measure 'Call procedure',1 -return - -CallProcParms: -call time('r') -do x = 1 to count - call Proc2 1,2,3 -end -call Measure 'Call procedure with parms',1 -return - -CallRout: -call time('r') -do x = 1 to count - call Rout1 -end -call Measure 'Call routine',1 -return - -CallRoutParms: -call time('r') -do x = 1 to count - call Rout2 1,2,3 -end -call Measure 'Call routine with parms',1 -return - -Proc1: -procedure -return - -Proc2: -procedure -arg a,b,c -return - -Rout1: -return - -Rout2: -arg a,b,c -return - -DateTime: -call time('r') -do x = 1 to count - t = date('b') - t = date('d') - t = date('e') - t = date('m') - t = date('n') - t = date('o') - t = date('s') - t = date('u') - t = date('w') - t = time('c') - t = time('e') - t = time('h') - t = time('l') - t = time('m') - t = time('n') - t = time('s') -end -call Measure 'Date and time',16 -return - -PushPullQueued: -a = 123.45 -call time('r') -do x = 1 to count - push a - b = queued() - pull a -end -call Measure 'Push, pull and queued',3 -return - -Interpreting: -a = 'nop' -call time('r') -do x = 1 to count - interpret a -end -call Measure 'Interpret',1 -return - -Output: -file = '\temp\perf.txt' -call lineout file,,1 -call time('r') -do x = 1 to count - call lineout file,'sequence number of this record is' x -end -call Measure 'Output',1 -return - -Input: -file = '\temp\perf.txt' -call time('r') -do x = 1 to count - t = linein(file) -end -call Measure 'Input',1 -return - -StemProcessing: -call time('r') -do x = 1 to count - stem.x.x.x = 1.23 -end -call Measure 'Stem processing',1 -return - -Measure: -parse arg measure,clauses -elaps = time('e')-tarra -if elaps > 0 then do - say left(measure,25) format((count*clauses)/(1e6*elaps) ,3,1) 'million clauses/sec' -end -else - say left(measure,25) 'loop counter too low, cannot perform measure' -return diff --git a/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping.lua b/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-1.lua similarity index 67% rename from Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping.lua rename to Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-1.lua index 2e72972d27..ab01ed7442 100644 --- a/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping.lua +++ b/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-1.lua @@ -1,14 +1,12 @@ -function tokenise (str, sep, esc) +function Tokenize (str, sep, esc) local strList, word, escaped, ch = {}, "", false for pos = 1, #str do ch = str:sub(pos, pos) if ch == esc then if escaped then word = word .. ch - escaped = false - else - escaped = true end + escaped = not escaped elseif ch == sep then if escaped then word = word .. ch @@ -25,9 +23,3 @@ function tokenise (str, sep, esc) table.insert(strList, word) return strList end - -local testStr = "one^|uno||three^^^^|four^^^|^cuatro|" -local testSep, testEsc = "|", "^" -for k, v in pairs(tokenise(testStr, testSep, testEsc)) do - print(k, v) -end diff --git a/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-2.lua b/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-2.lua new file mode 100644 index 0000000000..5b68d41325 --- /dev/null +++ b/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-2.lua @@ -0,0 +1,11 @@ +function Tokenize(str, sep, esc) local R = {} + local repl = sep~="\0" and esc~="\0" and "\0" + or sep~="\1" and esc~="\1" and "\1" + or sep~="\2" and esc~="\2" and "\2" + local fakeStr = str:gsub("[%" .. esc .. "].", repl .. repl) + local pattern = "()[^%" .. sep .. "]*()" + for start, fin in fakeStr:gmatch(pattern) do + R[#R+1] = str:sub(start, fin-1) + end + return R +end diff --git a/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-3.lua b/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-3.lua new file mode 100644 index 0000000000..065824c58c --- /dev/null +++ b/Task/Tokenize-a-string-with-escaping/Lua/tokenize-a-string-with-escaping-3.lua @@ -0,0 +1,4 @@ +local testStr = "one^|uno||three^^^^|four^^^|^cuatro|" +for k, v in ipairs(Tokenize(testStr, "|", "^")) do + print(k, v) +end diff --git a/Task/Tokenize-a-string/Excel/tokenize-a-string-1.excel b/Task/Tokenize-a-string/Excel/tokenize-a-string-1.excel new file mode 100644 index 0000000000..1f048cee22 --- /dev/null +++ b/Task/Tokenize-a-string/Excel/tokenize-a-string-1.excel @@ -0,0 +1 @@ +=TEXTSPLIT("Hello,How,Are,You,Today", ",") diff --git a/Task/Tokenize-a-string/Excel/tokenize-a-string-2.excel b/Task/Tokenize-a-string/Excel/tokenize-a-string-2.excel new file mode 100644 index 0000000000..ad4050073f --- /dev/null +++ b/Task/Tokenize-a-string/Excel/tokenize-a-string-2.excel @@ -0,0 +1 @@ +=TEXTSPLIT("Hello,How,Are,You,Today", , ",") diff --git a/Task/Tokenize-a-string/Zig/tokenize-a-string.zig b/Task/Tokenize-a-string/Zig/tokenize-a-string.zig index 9cdf0fcef6..63f90b8587 100644 --- a/Task/Tokenize-a-string/Zig/tokenize-a-string.zig +++ b/Task/Tokenize-a-string/Zig/tokenize-a-string.zig @@ -1,7 +1,7 @@ const std = @import("std"); pub fn main() void { const string = "Hello,How,Are,You,Today"; - var tokens = std.mem.split(u8, string, ","); + var tokens = std.mem.splitScalar(u8, string, ','); std.debug.print("{s}", .{tokens.next().?}); while (tokens.next()) |token| { std.debug.print(".{s}", .{token}); diff --git a/Task/Tonelli-Shanks-algorithm/JavaScript/tonelli-shanks-algorithm.js b/Task/Tonelli-Shanks-algorithm/JavaScript/tonelli-shanks-algorithm.js new file mode 100644 index 0000000000..86a4f90eec --- /dev/null +++ b/Task/Tonelli-Shanks-algorithm/JavaScript/tonelli-shanks-algorithm.js @@ -0,0 +1,113 @@ +class TonelliShanks { + static ts(n, p) { + // Convert to BigInt if not already + n = typeof n === 'bigint' ? n : BigInt(n); + p = typeof p === 'bigint' ? p : BigInt(p); + + const ZERO = BigInt(0); + const ONE = BigInt(1); + const TWO = BigInt(2); + + // Helper function for modular exponentiation + const powModP = (a, e) => { + let result = BigInt(1); + a = a % p; + while (e > ZERO) { + if (e % TWO === ONE) { + result = (result * a) % p; + } + e = e / TWO; + a = (a * a) % p; + } + return result; + }; + + // Legendre symbol calculation + const ls = (a) => powModP(a, (p - ONE) / TWO); + + if (ls(n) !== ONE) return { root1: ZERO, root2: ZERO, exists: false }; + + let q = p - ONE; + let ss = ZERO; + while (q % TWO === ZERO) { + ss += ONE; + q /= TWO; + } + + if (ss === ONE) { + const r1 = powModP(n, (p + ONE) / BigInt(4)); + return { root1: r1, root2: p - r1, exists: true }; + } + + let z = TWO; + while (ls(z) !== p - ONE) z += ONE; + + let c = powModP(z, q); + let r = powModP(n, (q + ONE) / TWO); + let t = powModP(n, q); + let m = ss; + + while (true) { + if (t === ONE) return { root1: r, root2: p - r, exists: true }; + + let i = ZERO; + let zz = t; + while (zz !== ONE && i < m - ONE) { + zz = (zz * zz) % p; + i += ONE; + } + + let b = c; + let e = m - i - ONE; + while (e > ZERO) { + b = (b * b) % p; + e -= ONE; + } + + r = (r * b) % p; + c = (b * b) % p; + t = (t * c) % p; + m = i; + } + } +} + +// Main function +function main() { + const pairs = [ + [10n, 13n], + [56n, 101n], + [1030n, 10009n], + [1032n, 10009n], + [44402n, 100049n], + [665820697n, 1000000009n], + [881398088036n, 1000000000039n] + ]; + + for (const [n, p] of pairs) { + const sol = TonelliShanks.ts(n, p); + console.log(`n = ${n}`); + console.log(`p = ${p}`); + if (sol.exists) { + console.log(`root1 = ${sol.root1}`); + console.log(`root2 = ${sol.root2}`); + } else { + console.log("No solution exists"); + } + console.log(); + } + + const bn = 41660815127637347468140745042827704103445750172002n; + const bp = BigInt(10) ** 50n + 577n; + const sol = TonelliShanks.ts(bn, bp); + console.log(`n = ${bn}`); + console.log(`p = ${bp}`); + if (sol.exists) { + console.log(`root1 = ${sol.root1}`); + console.log(`root2 = ${sol.root2}`); + } else { + console.log("No solution exists"); + } +} + +main(); diff --git a/Task/Tonelli-Shanks-algorithm/Rust/tonelli-shanks-algorithm.rs b/Task/Tonelli-Shanks-algorithm/Rust/tonelli-shanks-algorithm.rs new file mode 100644 index 0000000000..b35f2e502d --- /dev/null +++ b/Task/Tonelli-Shanks-algorithm/Rust/tonelli-shanks-algorithm.rs @@ -0,0 +1,120 @@ +struct Pair { + n: u64, + p: u64, +} + +struct Solution { + root1: u64, + root2: u64, + is_square: bool, +} + +fn multiply_modulus(a: u64, b: u64, modulus: u64) -> u64 { + let mut a = a % modulus; + let mut b = b % modulus; + + if b < a { + std::mem::swap(&mut a, &mut b); + } + + let mut result = 0; + while a > 0 { + if a % 2 == 1 { + result = (result + b) % modulus; + } + b = (b << 1) % modulus; + a >>= 1; + } + result +} + +fn power_modulus(base: u64, exponent: u64, modulus: u64) -> u64 { + if modulus == 1 { + return 0; + } + + let mut base = base % modulus; + let mut result = 1; + let mut exponent = exponent; + + while exponent > 0 { + if (exponent & 1) == 1 { + result = multiply_modulus(result, base, modulus); + } + base = multiply_modulus(base, base, modulus); + exponent >>= 1; + } + result +} + +fn legendre(a: u64, p: u64) -> u64 { + power_modulus(a, (p - 1) / 2, p) +} + +fn tonelli_shanks(n: u64, p: u64) -> Solution { + if legendre(n, p) != 1 { + return Solution { root1: 0, root2: 0, is_square: false }; + } + + // Factor out powers of 2 from p - 1 + let mut q = p - 1; + let mut s = 0; + while q % 2 == 0 { + q /= 2; + s += 1; + } + + if s == 1 { + let result = power_modulus(n, (p + 1) / 4, p); + return Solution { root1: result, root2: p - result, is_square: true }; + } + + // Find a non-square z such as ( z | p ) = -1 + let mut z = 2; + while legendre(z, p) != p - 1 { + z += 1; + } + + let mut c = power_modulus(z, q, p); + let mut t = power_modulus(n, q, p); + let mut m = s; + let mut result = power_modulus(n, (q + 1) >> 1, p); + + while t != 1 { + let mut i = 1; + let mut z = multiply_modulus(t, t, p); + while z != 1 && i < m - 1 { + i += 1; + z = multiply_modulus(z, z, p); + } + let b = power_modulus(c, 1 << (m - i - 1), p); + c = multiply_modulus(b, b, p); + t = multiply_modulus(t, c, p); + m = i; + result = multiply_modulus(result, b, p); + } + + Solution { root1: result, root2: p - result, is_square: true } +} + +fn main() { + let tests = vec![ + Pair { n: 10, p: 13 }, + Pair { n: 56, p: 101 }, + Pair { n: 1030, p: 1009 }, + Pair { n: 1032, p: 1009 }, + Pair { n: 44402, p: 100049 }, + Pair { n: 665820697, p: 1000000009 }, + Pair { n: 881398088036, p: 1000000000039 }, + ]; + + for test in tests { + let solution = tonelli_shanks(test.n, test.p); + print!("n = {}, p = {}", test.n, test.p); + if solution.is_square { + println!(" has solutions: {} and {}\n", solution.root1, solution.root2); + } else { + println!(" has no solutions because n is not a square modulo p\n"); + } + } +} diff --git a/Task/Tonelli-Shanks-algorithm/Zig/tonelli-shanks-algorithm.zig b/Task/Tonelli-Shanks-algorithm/Zig/tonelli-shanks-algorithm.zig new file mode 100644 index 0000000000..61cb26bb3e --- /dev/null +++ b/Task/Tonelli-Shanks-algorithm/Zig/tonelli-shanks-algorithm.zig @@ -0,0 +1,128 @@ +const std = @import("std"); +const stdout = std.io.getStdOut().writer(); + +const Pair = struct { + n: u64, + p: u64, +}; + +const Solution = struct { + root1: u64, + root2: u64, + is_square: bool, +}; + +fn multiplyModulus(a: u64, b: u64, modulus: u64) u64 { + var a_mod = a % modulus; + var b_mod = b % modulus; + + if (b_mod < a_mod) { + const temp = a_mod; + a_mod = b_mod; + b_mod = temp; + } + + var result: u64 = 0; + var a_temp = a_mod; + var b_temp = b_mod; + + while (a_temp > 0) { + if (a_temp % 2 == 1) { + result = (result + b_temp) % modulus; + } + b_temp = (b_temp << 1) % modulus; + a_temp >>= 1; + } + return result; +} + +fn powerModulus(base: u64, exponent: u64, modulus: u64) u64 { + if (modulus == 1) { + return 0; + } + + var base_mod = base % modulus; + var result: u64 = 1; + var exp = exponent; + + while (exp > 0) { + if ((exp & 1) == 1) { + result = multiplyModulus(result, base_mod, modulus); + } + base_mod = multiplyModulus(base_mod, base_mod, modulus); + exp >>= 1; + } + return result; +} + +fn legendre(a: u64, p: u64) u64 { + return powerModulus(a, (p - 1) / 2, p); +} + +fn tonelliShanks(n: u64, p: u64) Solution { + if (legendre(n, p) != 1) { + return Solution{ .root1 = 0, .root2 = 0, .is_square = false }; + } + + // Factor out powers of 2 from p - 1 + var q = p - 1; + var s: u64 = 0; + while (q % 2 == 0) { + q /= 2; + s += 1; + } + + if (s == 1) { + const result = powerModulus(n, (p + 1) / 4, p); + return Solution{ .root1 = result, .root2 = p - result, .is_square = true }; + } + + // Find a non-square z such as ( z | p ) = -1 + var z: u64 = 2; + while (legendre(z, p) != p - 1) { + z += 1; + } + + var c = powerModulus(z, q, p); + var t = powerModulus(n, q, p); + var m = s; + var result = powerModulus(n, (q + 1) >> 1, p); + + while (t != 1) { + var i: u64 = 1; + var z_temp = multiplyModulus(t, t, p); + while (z_temp != 1 and i < m - 1) { + i += 1; + z_temp = multiplyModulus(z_temp, z_temp, p); + } + const b = powerModulus(c, @as(u64, 1) << @as( u6, @intCast(m - i - 1)), p); + c = multiplyModulus(b, b, p); + t = multiplyModulus(t, c, p); + m = i; + result = multiplyModulus(result, b, p); + } + + return Solution{ .root1 = result, .root2 = p - result, .is_square = true }; +} + +pub fn main() !void { + const tests = [_]Pair{ + .{ .n = 10, .p = 13 }, + .{ .n = 56, .p = 101 }, + .{ .n = 1030, .p = 1009 }, + .{ .n = 1032, .p = 1009 }, + .{ .n = 44402, .p = 100049 }, + .{ .n = 665820697, .p = 1000000009 }, + .{ .n = 881398088036, .p = 1000000000039 }, + }; + + for (tests) |my_test| { + const solution = tonelliShanks(my_test.n, my_test.p); + try stdout.print("n = {}, p = {}", .{ my_test.n, my_test.p }); + if (solution.is_square) { + try stdout.print(" has solutions: {} and {}\n\n", .{ solution.root1, solution.root2 }); + } else { + try stdout.print(" has no solutions because n is not a square modulo p\n\n", .{}); + } + } +} diff --git a/Task/Top-rank-per-group/EasyLang/top-rank-per-group.easy b/Task/Top-rank-per-group/EasyLang/top-rank-per-group.easy index 9a39f89571..fba201626a 100644 --- a/Task/Top-rank-per-group/EasyLang/top-rank-per-group.easy +++ b/Task/Top-rank-per-group/EasyLang/top-rank-per-group.easy @@ -1,6 +1,6 @@ global na$[] id$[] sal[] dep$[] n . # -proc read . . +proc read . s$ = input repeat s$ = input @@ -15,7 +15,7 @@ proc read . . . read # -proc sort . . +proc sort . for i = 1 to n - 1 for j = i + 1 to n h = strcmp dep$[i] dep$[j] diff --git a/Task/Total-circles-area/EasyLang/total-circles-area.easy b/Task/Total-circles-area/EasyLang/total-circles-area.easy index 3dcb2fd239..e82e7c31eb 100644 --- a/Task/Total-circles-area/EasyLang/total-circles-area.easy +++ b/Task/Total-circles-area/EasyLang/total-circles-area.easy @@ -46,7 +46,7 @@ for try to ntry . . . -numfmt 4 0 +numfmt 0 4 print inside / ntry * (maxx - minx) * (maxy - miny) # input_data diff --git a/Task/Totient-function/EasyLang/totient-function.easy b/Task/Totient-function/EasyLang/totient-function.easy index 56f5cd9c90..67e9d7a02f 100644 --- a/Task/Totient-function/EasyLang/totient-function.easy +++ b/Task/Totient-function/EasyLang/totient-function.easy @@ -12,7 +12,7 @@ fastfunc totient n . if n > 1 : tot -= tot div n return tot . -numfmt 0 3 +numfmt 3 0 print " N Prim Phi" for n = 1 to 25 tot = totient n diff --git a/Task/Totient-function/REXX/totient-function-1.rexx b/Task/Totient-function/REXX/totient-function-1.rexx deleted file mode 100644 index ef3128a23e..0000000000 --- a/Task/Totient-function/REXX/totient-function-1.rexx +++ /dev/null @@ -1,24 +0,0 @@ -/*REXX program calculates the totient numbers for a range of numbers, and count primes. */ -parse arg N . /*obtain optional argument from the CL.*/ -if N=='' | N=="," then N= 25 /*Not specified? Then use the default.*/ -tell= N>0 /*N positive>? Then display them all. */ -N= abs(N) /*use the absolute value of N for loop.*/ -w= length(N) /*W: is used in aligning the output. */ -primes= 0 /*the number of primes found (so far).*/ - /*if N was negative, only count primes.*/ - do j=1 for N; T= phi(j) /*obtain totient number for a number. */ - prime= word('(prime)', 1 + (T \== j-1 ) ) /*determine if J is a prime number. */ - if prime\=='' then primes= primes + 1 /*if a prime, then bump the prime count*/ - if tell then say 'totient number for ' right(j, w) " ──► " right(T, w) ' ' prime - end /*j*/ -say -say right(primes, w) ' primes detected for numbers up to and including ' N -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -gcd: parse arg x,y; do until y==0; parse value x//y y with y x - end /*until*/; return x -/*──────────────────────────────────────────────────────────────────────────────────────*/ -phi: procedure; parse arg z; if z==1 then return 1 - #= 1 - do m=2 for z-2; if gcd(m, z)==1 then #= # + 1 - end /*m*/; return # diff --git a/Task/Totient-function/REXX/totient-function-2.rexx b/Task/Totient-function/REXX/totient-function-2.rexx deleted file mode 100644 index 4f6e3d592b..0000000000 --- a/Task/Totient-function/REXX/totient-function-2.rexx +++ /dev/null @@ -1,25 +0,0 @@ -/*REXX program calculates the totient numbers for a range of numbers, and count primes. */ -parse arg N . /*obtain optional argument from the CL.*/ -if N=='' | N=="," then N= 25 /*Not specified? Then use the default.*/ -tell= N>0 /*N positive>? Then display them all. */ -N= abs(N) /*use the absolute value of N for loop.*/ -w= length(N) /*W: is used in aligning the output. */ -primes= 0 /*the number of primes found (so far).*/ - /*if N was negative, only count primes.*/ - do j=1 for N; T= phi(j) /*obtain totient number for a number. */ - prime= word('(prime)', 1 + (T \== j-1 ) ) /*determine if J is a prime number. */ - if prime\=='' then primes= primes + 1 /*if a prime, then bump the prime count*/ - if tell then say 'totient number for ' right(j, w) " ──► " right(T, w) ' ' prime - end /*j*/ -say -say right(primes, w) ' primes detected for numbers up to and including ' N -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -phi: procedure; parse arg z; if z==1 then return 1 - #= 1 - do m=2 for z-2; parse value m z with x y - do until y==0; parse value x//y y with y x - end /*until*/ - if x==1 then #= # + 1 - end /*m*/ - return # diff --git a/Task/Totient-function/REXX/totient-function-3.rexx b/Task/Totient-function/REXX/totient-function-3.rexx deleted file mode 100644 index 90f0aa7f2d..0000000000 --- a/Task/Totient-function/REXX/totient-function-3.rexx +++ /dev/null @@ -1,137 +0,0 @@ -include Settings - -say version; say 'Totient function (Phi)'; say -call Time('r') -numeric digits 10; cycl. = 0; m = 7 -call First25A -call PrimeCountA m -say Format(Time('e'),,3) 'seconds'; say -call Time('r') -call Totients 10**m -call First25B -call PrimeCountB m -say Format(Time('e'),,3) 'seconds' -exit - -First25A: -procedure -say 'A: using calls to an optimized Totient()'; say -say ' N Phi(N) Prime?' -say Copies('-',16) -n = 0 -do i = 1 to 25 - p = Totient(i) - if p = i-1 then do - n = n+1; pr = 'Yes' - end - else - pr = '' - say Right(i,2) Right(p,6) pr -end -say Copies('-',16); say -say 'Found' Right(n,6) 'primes <' Right(25,8) -return - -PrimeCountA: -procedure -arg x -n = 0; d = 1 -do i = 1 - p = Totient(i) - if p = i-1 then - n = n+1 - e = Xpon(i) - if e > d then do - say 'Found' Right(n,6) 'primes <' Right(10**e,8) - if e > x-1 then - leave i - d = e - end -end -say -return - -First25B: -procedure expose toti. -say 'B: generate and save all Totients, and use the stored values'; say -say ' N Phi(N) Prime?' -say Copies('-',16) -n = 0 -do i = 1 to 25 - p = toti.totient.i - if p = i-1 then do - n = n+1; pr = 'Yes' - end - else - pr = '' - say Right(i,2) Right(p,6) pr -end -say Copies('-',16) -say -say 'Found' Right(n,6) 'primes <' Right(25,8) -return - -PrimeCountB: -procedure expose toti. -arg x -n = 0; d = 1 -do i = 1 - p = toti.totient.i - if p = i-1 then - n = n+1 - e = Xpon(i) - if e > d then do - say 'Found' Right(n,6) 'primes <' Right(10**e,8) - if e > x-1 then - leave i - d = e - end -end -say -return - -Totient: -/* Euler's totient function */ -procedure expose toti. -arg x -/* Fast values */ -if x < 3 then - return 1 -if x < 5 then - return 2 -/* Multiplicative property using Factors */ -f = Factors(x)+1; fact.factor.f = 0 -y = 1; v = fact.factor.1; n = 1 -do i = 2 to f - a = fact.factor.i - if a = v then - n = n+1 - else do - y = y*v**(n-1)*(v-1) - v = a; n = 1 - end -end -return y - -Totients: -/* Euler's totient numbers */ -procedure expose toti. -arg x -/* Recurring sequence */ -do i = 1 to x - toti.totient.i = i -end -do i = 2 to x - if toti.totient.i < i then - iterate i - do j = i by i to x - toti.totient.j = toti.totient.j-toti.totient.j/i - end -end -toti.0 = x -return x - -include Functions -include Numbers -include Sequences -include Abend diff --git a/Task/Totient-function/REXX/totient-function.rexx b/Task/Totient-function/REXX/totient-function.rexx new file mode 100644 index 0000000000..fc0246dae9 --- /dev/null +++ b/Task/Totient-function/REXX/totient-function.rexx @@ -0,0 +1,99 @@ +-- 8 May 2025 +include Settings + +say 'TOTIENT FUNCTION (PHI)' +say version +numeric digits 10; m = 6 +call First25A +call PrimeCountA m +say Format(Time('e'),,3) 'seconds'; say +call Time('r') +call First25B m +call PrimeCountB m +say Format(Time('e'),,3) 'seconds' +exit + +First25A: +procedure +say 'A: using calls to function Totient()'; say +say ' N Phi(N) Prime?' +say Copies('-',16) +n = 0 +do i = 1 to 25 + p = Totient(i) + if p = i-1 then do + n = n+1; pr = 'Yes' + end + else + pr = '' + say Right(i,2) Right(p,6) pr +end +say Copies('-',16); say +say 'Found' Right(n,6) 'PrimeS <' Right(25,8) +return + +PrimeCountA: +procedure +arg x +n = 0; d = 1 +do i = 1 + p = Totient(i) + if p = i-1 then + n = n+1 + e = Xpon(i) + if e > d then do + say 'Found' Right(n,6) 'PrimeS <' Right(10**e,8) + if e > x-1 then + leave i + d = e + end +end +say +return + +First25B: +procedure expose toti. +arg m +say 'B: generate and save all TotientS, use the stored values'; say +call TotientS 10**m +say ' N Phi(N) Prime?' +say Copies('-',16) +n = 0 +do i = 1 to 25 + p = toti.i + if p = i-1 then do + n = n+1; pr = 'Yes' + end + else + pr = '' + say Right(i,2) Right(p,6) pr +end +say Copies('-',16) +say +say 'Found' Right(n,6) 'PrimeS <' Right(25,8) +return + +PrimeCountB: +procedure expose toti. +arg x +n = 0; d = 1 +do i = 1 + p = toti.i + if p = i-1 then + n = n+1 + e = Xpon(i) + if e > d then do + say 'Found' Right(n,6) 'PrimeS <' Right(10**e,8) + if e > x-1 then + leave i + d = e + end +end +say +return + +include Functions +include Special +include Numbers +include Sequences +include Abend diff --git a/Task/Towers-of-Hanoi/Applesoft-BASIC/towers-of-hanoi.basic b/Task/Towers-of-Hanoi/Applesoft-BASIC/towers-of-hanoi.basic new file mode 100644 index 0000000000..5c57b6288a --- /dev/null +++ b/Task/Towers-of-Hanoi/Applesoft-BASIC/towers-of-hanoi.basic @@ -0,0 +1,27 @@ + 100 DATA4,": "," TO " + 110 DEF FN M(X) = X - INT (X / 3) * 3 + 1 + 120 READ N,T$(0),T$(1) + 130 LET M$(1) = CHR$ (13) + 140 FOR M = 1 TO 2 ^ N - 1 + 150 FOR O = 0 TO 1 + 160 GOSUB 200"ANDOR + 170 PRINT MID$ ( STR$ (M),1,( NOT O) * 255)T$(O) FN M(R + O)M$(O); + 180 NEXT O,M + 190 END + + REM BITWISE M WITH M-1, RESULT IN R + REM AND WHEN O = 0 + REM OR WHEN NOT O + 200 LET R = 0 + 210 LET B1 = M + 220 LET B2 = M - 1 + 230 FOR I = 0 TO 1E9 + 240 LET M1 = B1 - INT (B1 / 2) * 2 + 250 LET M2 = B2 - INT (B2 / 2) * 2 + 260 LET MR = M1 AND M2 + 270 IF O THEN MR = M1 OR M2 + 280 LET R = R + MR * (2 ^ I) + 290 LET B1 = INT (B1 / 2) + 300 LET B2 = INT (B2 / 2) + 310 IF B1 OR B2 THEN NEXT I + 320 RETURN diff --git a/Task/Towers-of-Hanoi/Ballerina/towers-of-hanoi.ballerina b/Task/Towers-of-Hanoi/Ballerina/towers-of-hanoi.ballerina new file mode 100644 index 0000000000..813ca35432 --- /dev/null +++ b/Task/Towers-of-Hanoi/Ballerina/towers-of-hanoi.ballerina @@ -0,0 +1,26 @@ +import ballerina/io; + +class Hanoi { + private int moves; + + function init(int disks) { + self.moves = 0; + io:println("Towers of Hanoi with ", disks, " disks:\n"); + self.move(disks, "L", "C", "R"); + io:println("\nCompleted in ", self.moves, " moves\n"); + } + + private function move(int n, string frm, string to, string via) { + if n > 0 { + self.move(n - 1, frm, via, to); + self.moves += 1; + io:println("Move disk ", n, " from ", frm, " to ", to); + self.move(n - 1, via, to, frm); + } + } +} + +public function main() { + _ = new Hanoi(3); + _ = new Hanoi(4); +} diff --git a/Task/Towers-of-Hanoi/EasyLang/towers-of-hanoi.easy b/Task/Towers-of-Hanoi/EasyLang/towers-of-hanoi.easy index 80116bb093..821008469b 100644 --- a/Task/Towers-of-Hanoi/EasyLang/towers-of-hanoi.easy +++ b/Task/Towers-of-Hanoi/EasyLang/towers-of-hanoi.easy @@ -1,8 +1,8 @@ -proc hanoi n src dst aux . . +proc hanoi n src dst aux . if n >= 1 hanoi n - 1 src aux dst print "Move " & src & " to " & dst hanoi n - 1 aux dst src . . -hanoi 5 1 2 3 +hanoi 4 1 2 3 diff --git a/Task/Towers-of-Hanoi/Excel/towers-of-hanoi-3.excel b/Task/Towers-of-Hanoi/Excel/towers-of-hanoi-3.excel new file mode 100644 index 0000000000..096d5b74b6 --- /dev/null +++ b/Task/Towers-of-Hanoi/Excel/towers-of-hanoi-3.excel @@ -0,0 +1,11 @@ +=LET( + TOH, LAMBDA(TOH, n, from, to, aux, + IF(n=0, "", VSTACK( + TOH(TOH, n-1, from, aux, to), + "Move disk " & n & " from " & from & " to " & to, + TOH(TOH, n-1, aux, to, from) + )) + ), + ans, TOH(TOH, A2, "A", "C", "B"), + FILTER(ans, LEN(ans)) + ) diff --git a/Task/Towers-of-Hanoi/Uxntal/towers-of-hanoi.uxnatl b/Task/Towers-of-Hanoi/Uxntal/towers-of-hanoi.uxnatl index 4ea818bcc2..6d3ca4f5c0 100644 --- a/Task/Towers-of-Hanoi/Uxntal/towers-of-hanoi.uxnatl +++ b/Task/Towers-of-Hanoi/Uxntal/towers-of-hanoi.uxnatl @@ -1,10 +1,15 @@ -|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1 +%newline { [ LIT2 0a -Console/write ] DEO } -|0100 ( -> ) - #0102 [ LIT2 03 &count 04 ] hanoi - POP2 POP2 BRK +|18 @Console/write -@hanoi ( from spare to count -: from spare to count ) +|0100 + +#0102 #0304 hanoi +POP2 POP2 + +BRK + +@hanoi ( from spare to count -- from spare to count ) ( moving 0 disks is no-op ) DUP ?{ JMP2r } @@ -13,14 +18,14 @@ ( from to spare count-1 ) ( print the current move ) - ;dict/move print-str + ;dict/move print/str INCk #30 ORA .Console/write DEO STH2 - ;dict/from print-str + ;dict/from print/str OVR #30 ORA .Console/write DEO - ;dict/to print-str + ;dict/to print/str DUP #30 ORA .Console/write DEO - [ LIT2 0a -Console/write ] DEO + newline STH2r ( move disks 1..count-1 from the spare peg to the goal peg ) @@ -31,10 +36,9 @@ JMP2r -@print-str - &loop - LDAk .Console/write DEO - INC2 LDAk ?&loop +@print/str ( str* -- ) + LDAk .Console/write DEO + INC2 LDAk ?/str POP2 JMP2r @dict diff --git a/Task/Tree-traversal/EasyLang/tree-traversal.easy b/Task/Tree-traversal/EasyLang/tree-traversal.easy index 4495de81f5..91043289f2 100644 --- a/Task/Tree-traversal/EasyLang/tree-traversal.easy +++ b/Task/Tree-traversal/EasyLang/tree-traversal.easy @@ -1,9 +1,7 @@ tree[] = [ 1 2 3 4 5 6 -1 7 -1 -1 -1 8 9 ] # -proc preorder ind . . - if ind > len tree[] or tree[ind] = -1 - return - . +proc preorder ind . + if ind > len tree[] or tree[ind] = -1 : return write " " & tree[ind] preorder ind * 2 preorder ind * 2 + 1 @@ -12,10 +10,8 @@ write "preorder:" preorder 1 print "" # -proc inorder ind . . - if ind > len tree[] or tree[ind] = -1 - return - . +proc inorder ind . + if ind > len tree[] or tree[ind] = -1 : return inorder ind * 2 write " " & tree[ind] inorder ind * 2 + 1 @@ -24,10 +20,8 @@ write "inorder:" inorder 1 print "" # -proc postorder ind . . - if ind > len tree[] or tree[ind] = -1 - return - . +proc postorder ind . + if ind > len tree[] or tree[ind] = -1 : return postorder ind * 2 postorder ind * 2 + 1 write " " & tree[ind] @@ -37,25 +31,23 @@ postorder 1 print "" # global tail head queue[] . -proc initqu n . . +proc initqu n . len queue[] n tail = 1 head = 1 . -proc enqu v . . +proc enqu v . queue[tail] = v tail = (tail + 1) mod1 len queue[] . func dequ . - if head = tail - return -1 - . + if head = tail : return -1 h = head head = (head + 1) mod1 len queue[] return queue[h] . initqu len tree[] -proc levelorder n . . +proc levelorder n . enqu n repeat ind = dequ diff --git a/Task/Trigonometric-functions/EasyLang/trigonometric-functions.easy b/Task/Trigonometric-functions/EasyLang/trigonometric-functions.easy index 39f5395c7a..237db0c2a0 100644 --- a/Task/Trigonometric-functions/EasyLang/trigonometric-functions.easy +++ b/Task/Trigonometric-functions/EasyLang/trigonometric-functions.easy @@ -8,7 +8,7 @@ func d2r d . return d * pi / 180 . # -numfmt 4 0 +numfmt 0 4 print sin d & " " & sin r2d r print cos d & " " & cos r2d r print tan d & " " & tan r2d r diff --git a/Task/Trigonometric-functions/REXX/trigonometric-functions-1.rexx b/Task/Trigonometric-functions/REXX/trigonometric-functions-1.rexx deleted file mode 100644 index 578b9ea17d..0000000000 --- a/Task/Trigonometric-functions/REXX/trigonometric-functions-1.rexx +++ /dev/null @@ -1,81 +0,0 @@ -/*REXX program demonstrates some common trig functions (30 decimal digits are shown).*/ -showdigs= 25 /*show only 25 digits of number. */ -numeric digits showdigs + 10 /*DIGITS default is 9, but use */ - /*extra digs to prevent rounding.*/ -say 'Using' showdigs 'decimal digits precision.' /*show # decimal digs being used.*/ -say - do j=-180 to +180 by 15 /*let's just do a half─Monty. */ - stuff = right(j, 4) 'degrees, rads=' show( d2r(j) ) , - ' sin=' show( sinD(j) ) , - ' cos=' show( cosD(J) ) - /*don't let TANGENT go postal. */ - if abs(j)\==90 then stuff=stuff ' tan=' show( tanD(j) ) - say stuff - end /*j*/ -say - do k=-1 to +1 by 1/2 /*keep the Arc─functions happy. */ - say right(k, 4) 'radians, degs=' show( r2d(k) ) , - ' Acos=' show( Acos(k) ) , - ' Asin=' show( Asin(k) ) , - ' Atan=' show( Atan(k) ) - end /*k*/ -exit /*stick a fork in it, we're done.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Asin: procedure; parse arg x 1 z 1 o 1 p; a=abs(x); aa=a*a - if a>1 then call AsinErr x /*X argument is out of range. */ - if a >= sqrt(2) * .5 then return sign(x) * acos( sqrt(1 - aa), '-ASIN') - do j=2 by 2 until p=z; p=z; o= o * aa * (j-1) / j; z= z +o / (j+1); end - return z /* [↑] compute until no noise. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Acos: procedure; parse arg x; if x<-1 | x>1 then call AcosErr; return pi()*.5 - Asin(x) -AcosD: return r2d( Acos( arg(1) ) ) -AsinD: return r2d( Asin( arg(1) ) ) -cosD: return cos( d2r( arg(1) ) ) -sinD: return sin( d2r( d2d( arg(1) ) ) ) -tan: procedure; parse arg x; _= cos(x); if _=0 then call tanErr; return sin(x) / _ -tanD: return tan( d2r( arg(1) ) ) -d2d: return arg(1) // 360 /*normalize degrees ──► a unit circle*/ -d2r: return r2r( d2d( arg(1) )*pi() / 180) /*convert degrees ──► radians. */ -r2d: return d2d( ( arg(1) * 180 / pi() ) ) /*convert radians ──► degrees. */ -r2r: return arg(1) // (pi() *2) /*normalize radians ──► a unit circle*/ -show: return left( left('', arg(1) >= 0)format( arg(1), , showdigs) / 1, showdigs) -tellErr: say; say '*** error! ***'; say; say arg(1); say; exit 13 -tanErr: call tellErr 'tan(' || x") causes division by zero, X=" || x -AsinErr: call tellErr 'Asin(x), X must be in the range of -1 ──► +1, X=' || x -AcosErr: call tellErr 'Acos(x), X must be in the range of -1 ──► +1, X=' || x -/*──────────────────────────────────────────────────────────────────────────────────────*/ -Atan: procedure; parse arg x; if abs(x)=1 then return pi() * .25 * sign(x) - return Asin(x / sqrt(1 + x*x) ) -/*──────────────────────────────────────────────────────────────────────────────────────*/ -cos: procedure; parse arg x; x= r2r(x); if x=0 then return 1; a= abs(x) - numeric fuzz min(6, digits() - 3); if a=pi then return -1; pih= pi * .5 - if a=pih | a=pih*3 then return 0; pit= pi/3; if a=pit then return .5 - if a=pit + pit then return -.5; return .sinCos(1, -1) -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sin: procedure; arg x;x=r2r(x);if x=0 then return 0;numeric fuzz min(5,max(1,digits()-3)) - if x=pi*.5 then return 1; if x==pi * 1.5 then return -1 - if abs(x)=pi then return 0; return .sinCos(x,1) -/*──────────────────────────────────────────────────────────────────────────────────────*/ -.sinCos: parse arg z 1 _,i; q= x*x - do k=2 by 2 until p=z; p= z; _= - _ * q / (k * (k+i) ); z= z + _; end - return z -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); i=; m.=9; h= d+6 - numeric digits; numeric form; if x<0 then do; x= -x; i= 'i'; end - parse value format(x, 2, 1, , 0) 'E0' with g 'E' _ .; g= g *.5'e'_ % 2 - do j=0 while h>9; m.j=h; h= h % 2 + 1; end /*j*/ - do k=j+5 to 0 by -1; numeric digits m.k; g= (g+x/g) * .5; end /*k*/ - numeric digits d; return (g/1)i /*make complex if X < 0.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -e: e = 2.7182818284590452353602874713526624977572470936999595749669676277240766303535 - return e /*Note: the actual E subroutine returns E's accuracy that */ - /*matches the current NUMERIC DIGITS, up to 1 million digits.*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -exp: procedure; parse arg x; ix=x%1; if abs(x-ix)>.5 then ix= ix + sign(x); x=x - ix - z=1; _=1; w=z; do j=1; _= _*x/j; z= (z+_) / 1; if z==w then leave; w=z; end - if z\==0 then z= e()**ix * z; return z -/*──────────────────────────────────────────────────────────────────────────────────────*/ -pi: pi= 3.1415926535897932384626433832795028841971693993751058209749445923078164062862 - return pi /*Note: the actual PI subroutine returns PI's accuracy that */ - /*matches the current NUMERIC DIGITS, up to 1 million digits.*/ - /*John Machin's formula is used for calculating more digits. */ diff --git a/Task/Trigonometric-functions/REXX/trigonometric-functions-2.rexx b/Task/Trigonometric-functions/REXX/trigonometric-functions.rexx similarity index 93% rename from Task/Trigonometric-functions/REXX/trigonometric-functions-2.rexx rename to Task/Trigonometric-functions/REXX/trigonometric-functions.rexx index 98903eb4fc..1b71fa05ce 100644 --- a/Task/Trigonometric-functions/REXX/trigonometric-functions-2.rexx +++ b/Task/Trigonometric-functions/REXX/trigonometric-functions.rexx @@ -1,6 +1,8 @@ include Settings -say version; say 'Trigonometric functions'; say +say 'TRIGONOMETRIC FUNCTIONS - 2 Mar 2025' +say version +say s = Copies('-',77); w = 18 call Trigo call Arcus1 diff --git a/Task/Truncatable-primes/Ballerina/truncatable-primes.ballerina b/Task/Truncatable-primes/Ballerina/truncatable-primes.ballerina new file mode 100644 index 0000000000..9c033e65b2 --- /dev/null +++ b/Task/Truncatable-primes/Ballerina/truncatable-primes.ballerina @@ -0,0 +1,90 @@ +import ballerina/io; + +function getPrimes(int n) returns int[] { + if n < 2 { return []; } + if n == 2 { return [2]; } + int k = (n - 3) / 2 + 1; + boolean[] marked = []; + marked.setLength(k); + foreach int i in 0..n).sqrt().floor(); + int lim = (f - 3) / 2 + 1; + foreach int i in 0..= 0 { return s; } + return "-" + s; +} + +public function main() returns error? { + final int lim = 999999; + boolean[] c = areComposite(lim); + boolean leftFound = false; + boolean rightFound = false; + io:println("Largest truncatable primes less than a million:"); + int i = lim; + while i > 2 { + if !c[i] { + if !rightFound { + int p = i / 10; + while p > 0 { + if p % 2 == 0 || c[p] { break; } + p = p / 10; + } + if p == 0 { + io:println(" Right truncatable prime = ", commatize(i)); + rightFound = true; + if leftFound { return; } + } + } + if !leftFound { + string q = i.toString().substring(1); + if !q.includes("0") { + int p = check int:fromString(q); + while q.length() > 0 { + if p % 2 == 0 || c[p] { break; } + q = q.substring(1); + p = q.length() > 0 ? check int:fromString(q) : 0; + } + if q == "" { + io:println(" Left truncatable prime = ", commatize(i)); + leftFound = true; + if rightFound { return; } + } + } + } + } + i -= 2; + } +} diff --git a/Task/Truncatable-primes/REXX/truncatable-primes.rexx b/Task/Truncatable-primes/REXX/truncatable-primes-1.rexx similarity index 100% rename from Task/Truncatable-primes/REXX/truncatable-primes.rexx rename to Task/Truncatable-primes/REXX/truncatable-primes-1.rexx diff --git a/Task/Truncatable-primes/REXX/truncatable-primes-2.rexx b/Task/Truncatable-primes/REXX/truncatable-primes-2.rexx new file mode 100644 index 0000000000..20875f0baa --- /dev/null +++ b/Task/Truncatable-primes/REXX/truncatable-primes-2.rexx @@ -0,0 +1,50 @@ +-- 25 Apr 2025 +include Settings +arg xx +say 'TRUNCATABLE PRIMES' +say version +say +call Collect +call Task +call Timer +exit + +Collect: +procedure expose prim. flag. +say 'Primes below 1 million...' +say Primes(1E6) 'found' +say +return + +Task: +procedure expose prim. flag. +say 'Largest left and right truncatable prime below 1 million...' +l1 = 0; r1 = 0 +do i = prim.0 by -1 until l1 > 0 & l2 > 0 + p = prim.i + if Pos(0,p) > 0 then + iterate i + l2 = 1; r2 = 1 + do j = 1 to Length(p)-1 + a = Left(p,j); b = Right(p,j) + if \ flag.a then + l2 = 0 + if \ flag.b then + r2 = 0 + end + if l1 = 0 & l2 then + l1 = p + if r1 = 0 & r2 then + r1 = p +end +say 'Left' l1 +say 'Right' r1 +say +return + +include Sequences +include Helper +include Numbers +include Functions +include Constants +include Abend diff --git a/Task/Twin-primes/REXX/twin-primes-1.rexx b/Task/Twin-primes/REXX/twin-primes-1.rexx deleted file mode 100644 index b78df4d079..0000000000 --- a/Task/Twin-primes/REXX/twin-primes-1.rexx +++ /dev/null @@ -1,26 +0,0 @@ -/*REXX pgm counts the number of twin prime pairs under a specified number N (or a list).*/ -parse arg $ . /*get optional number of primes to find*/ -if $='' | $="," then $= 10 100 1000 10000 100000 1000000 10000000 /*No $? Use default.*/ -w= length( commas( word($, words($) ) ) ) /*get length of the last number in list*/ -@found= ' twin prime pairs found under ' /*literal used in the showing of output*/ - - do i=1 for words($); x= word($, i) /*process each N─limit in the $ list.*/ - say right( commas(genP(x)), 20) @found right(commas(x), max(length(x), w) ) - end /*i*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg _; do ?=length(_)-3 to 1 by -3; _=insert(',', _, ?); end; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: parse arg y; @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13; #= 6; tp= 2; sq.6= 169 - if y>10 then tp= tp+1 - do j=@.#+2 by 2 for max(0, y%2-@.#%2-1) /*find odd primes from here on. */ - parse var j '' -1 _ /*obtain the last digit of the J var.*/ - if _==5 then iterate; if j// 3==0 then iterate /*J ÷ by 5? J ÷ by 3? */ - if j//7==0 then iterate; if j//11==0 then iterate /*" " " 7? " " " 11? */ - /* [↓] divide by the primes. ___ */ - do k=6 to # while sq.k<=j /*divide J by other primes ≤ √ J */ - if j//@.k == 0 then iterate j /*÷ by prev. prime? ¬prime ___ */ - end /*k*/ /* [↑] only divide up to √ J */ - prev= @.#; #= #+1; sq.#= j*j; @.#= j /*save prev. P; bump # primes; assign P*/ - if j-2==prev then tp= tp + 1 /*This & previous prime twins? Bump TP.*/ - end /*j*/; return tp diff --git a/Task/Twin-primes/REXX/twin-primes-2.rexx b/Task/Twin-primes/REXX/twin-primes-2.rexx deleted file mode 100644 index 82324b213a..0000000000 --- a/Task/Twin-primes/REXX/twin-primes-2.rexx +++ /dev/null @@ -1,33 +0,0 @@ -/*REXX pgm counts the number of twin prime pairs under a specified number N (or a list).*/ -parse arg $ . /*get optional number of primes to find*/ -if $='' | $="," then $= 100 1000 10000 100000 1000000 10000000 /*No $? Use default.*/ -w= length( commas( word($, words($) ) ) ) /*get length of the last number in list*/ -@found= ' twin prime pairs found under ' /*literal used in the showing of output*/ - - do i=1 for words($); x= word($, i) /*process each N─limit in the $ list.*/ - say right( commas(genP(x)), 20) @found right(commas(x), max(length(x), w) ) - end /*i*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg _; do ?=length(_)-3 to 1 by -3; _=insert(',', _, ?); end; return _ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: arg y; _= 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 - tp=8; #= words(_); sq.103=103*103 /*#: number of prims; TP: # twin pairs.*/ - do aa=1 for #; @.aa= word(_, aa) /*assign some low primes for quick ÷'s.*/ - end /*aa*/ - - do j=@.#+2 by 2 while j p then do + say n 'twin primes below' p + p = p*10 + end + j = i+1; b = prim.j + if b-a = 2 then + n = n+1 +end +say +return + +include Sequences +include Functions +include Abend diff --git a/Task/Two-bullet-roulette/EasyLang/two-bullet-roulette.easy b/Task/Two-bullet-roulette/EasyLang/two-bullet-roulette.easy index 7a271b0f1e..b1da314e3a 100644 --- a/Task/Two-bullet-roulette/EasyLang/two-bullet-roulette.easy +++ b/Task/Two-bullet-roulette/EasyLang/two-bullet-roulette.easy @@ -1,28 +1,20 @@ len cyl[] 6 -proc rshift . . +proc rshift . h = cyl[6] - for i = 6 downto 2 - cyl[i] = cyl[i - 1] - . + for i = 6 downto 2 : cyl[i] = cyl[i - 1] cyl[1] = h . -proc unload . . - for i = 1 to 6 - cyl[i] = 0 - . +proc unload . + for i = 1 to 6 : cyl[i] = 0 . -proc load . . - while cyl[1] = 1 - rshift - . +proc load . + while cyl[1] = 1 : rshift cyl[1] = 1 rshift . -proc spin . . +proc spin . lim = random 6 - for i = 1 to lim - 1 - rshift - . + for i = 1 to lim - 1 : rshift . func fire . shot = cyl[1] @@ -37,15 +29,13 @@ func method m[] . elif m = 2 spin elif m = 3 - if fire = 1 - return 1 - . + if fire = 1 : return 1 . . return 0 . method$[] = [ "load" "spin" "fire" ] -proc test m[] . . +proc test m[] . n = 100000 for i = 1 to n sum += method m[] diff --git a/Task/Two-bullet-roulette/Quackery/two-bullet-roulette.quackery b/Task/Two-bullet-roulette/Quackery/two-bullet-roulette.quackery new file mode 100644 index 0000000000..6273777041 --- /dev/null +++ b/Task/Two-bullet-roulette/Quackery/two-bullet-roulette.quackery @@ -0,0 +1,35 @@ +[ $ "bigrat.qky" loadfile ] now! + +[ 0 6 of ] is empty ( --> [ ) + +[ stack 0 ] is chamber ( --> s ) + +[ chamber take 1+ 6 mod + chamber put ] is rotate1 ( --> ) + +[ 1 swap chamber share poke + rotate1 ] is /load ( [ --> [ ) + +[ dup chamber share peek + if rotate1 /load ] is load ( [ --> [ ) + +[ 6 random chamber replace ] is spin ( --> ) + +[ dup dip + [ chamber share peek ] + rotate1 ] is fire ( [ --> n [ ) + +[ ' empty swap join + ' [ drop or ] join ] is makesim ( [ --> [ ) + +[ 0 ]'[ dup echo sp makesim + 10000 times + [ dup do swap dip + ] drop + 100 4 point$ echo$ char % + emit sp say "deaths" cr ] is sim ( --> ) + +randomise +sim [ load spin load spin fire spin fire ] +sim [ load spin load spin fire fire ] +sim [ load load spin fire spin fire ] +sim [ load load spin fire fire ] diff --git a/Task/UPC/EasyLang/upc.easy b/Task/UPC/EasyLang/upc.easy index 4d770fcc72..30478cdc81 100644 --- a/Task/UPC/EasyLang/upc.easy +++ b/Task/UPC/EasyLang/upc.easy @@ -1,4 +1,4 @@ -proc trim . s$ . +proc trim &s$ . a = 1 while substr s$ a 1 = " " : a += 1 b = len s$ @@ -25,7 +25,7 @@ func$ invert s$ . digs$[] = [ " ## #" " ## #" " # ##" " #### #" " # ##" " ## #" " # ####" " ### ##" " ## ###" " # ##" ] func[] decode_upc upc$ . subr getdigs - for _ to 6 + for i to 6 h$ = substr upc$ pos 7 for dig to 10 d$ = digs$[dig] diff --git a/Task/UTF-8-encode-and-decode/K/utf-8-encode-and-decode.k b/Task/UTF-8-encode-and-decode/K/utf-8-encode-and-decode.k new file mode 100644 index 0000000000..ece0858c66 --- /dev/null +++ b/Task/UTF-8-encode-and-decode/K/utf-8-encode-and-decode.k @@ -0,0 +1,4 @@ +dec:{64/(0;64 128;32 128 128;16 128 128 128)[-1+#x]+x} +enc:{`c$(0;-64 -128;-32 -128 -128;-16 -128 -128 -128)[b]+(128,(b:1+128 2048 65536'x)#64)\x} +v:(,"A";"ö";"Ж";"€";"𝄞") +`0:" -> "/'(::;$:;::)@'/:+(v; dec'v; enc'dec'v) diff --git a/Task/Ukkonen-s-suffix-tree-construction/FreeBASIC/ukkonen-s-suffix-tree-construction-1.basic b/Task/Ukkonen-s-suffix-tree-construction/FreeBASIC/ukkonen-s-suffix-tree-construction-1.basic new file mode 100644 index 0000000000..b42d4a94fe --- /dev/null +++ b/Task/Ukkonen-s-suffix-tree-construction/FreeBASIC/ukkonen-s-suffix-tree-construction-1.basic @@ -0,0 +1,151 @@ +Type SuffixType + index As Integer + suffix As String +End Type + +Type SubstringInfo + substring As String + positions As String +End Type + +Type AllSubstringsInfo + substrings(100) As SubstringInfo + count As Integer + max_length As Integer +End Type + +Function LongestCommonPrefix(s1 As String, s2 As String) As Integer + Dim As Integer minLen, i + minLen = Iif(Len(s1) < Len(s2), Len(s1), Len(s2)) + + For i = 1 To minLen + If Mid(s1, i, 1) <> Mid(s2, i, 1) Then Return i - 1 + Next + + Return minLen +End Function + +Sub FindLongestRepeatedSubstrings(text As String, Byref result As AllSubstringsInfo) + Dim As Integer i, j, k + result.count = 0 + result.max_length = 0 + + If Len(text) < 2 Then Exit Sub + + Dim As SuffixType suffixes() + Redim suffixes(0 To Len(text) - 1) + For i = 0 To Len(text) - 1 + suffixes(i).index = i + suffixes(i).suffix = Mid(text, i + 1) + Next + + ' Sort suffixes (Bubble, inefficient but simple) + For i = 0 To Len(text) - 2 + For j = i + 1 To Len(text) - 1 + If suffixes(i).suffix > suffixes(j).suffix Then + Swap suffixes(i), suffixes(j) + End If + Next + Next + + ' Find the longest repeated substring + Dim As Integer maxLength = 0 + For i = 0 To Len(text) - 2 + Dim As Integer prefixLen = LongestCommonPrefix(suffixes(i).suffix, suffixes(i + 1).suffix) + If prefixLen > maxLength Then maxLength = prefixLen + Next + + If maxLength = 0 Then Exit Sub + + result.max_length = maxLength + + For i = 0 To Len(text) - 2 + Dim As Integer prefixLen = LongestCommonPrefix(suffixes(i).suffix, suffixes(i + 1).suffix) + If prefixLen = maxLength Then + Dim As String substring = Left(suffixes(i).suffix, maxLength) + + Dim As Boolean found = False + For j = 0 To result.count - 1 + If result.substrings(j).substring = substring Then + found = True + Exit For + End If + Next + + If Not found Then + Dim As String positions = "" + Dim As Integer posCount = 0 + Dim As Integer posArray(100) + + For j = 0 To Len(text) - 1 + If Left(suffixes(j).suffix, maxLength) = substring Then + posArray(posCount) = suffixes(j).index - 2 + posCount += 1 + End If + Next + + ' Sort positions (Bubble, inefficient but simple) + For j = 0 To posCount - 2 + For k = j + 1 To posCount - 1 + If posArray(j) > posArray(k) Then + Swap posArray(j), posArray(k) + End If + Next + Next + + For j = 0 To posCount - 1 + If j > 0 Then positions &= " " + positions &= Str(posArray(j)) + Next + + result.substrings(result.count).substring = substring + result.substrings(result.count).positions = positions + result.count += 1 + End If + End If + Next +End Sub + +Sub main() + Dim As Integer limits(0 To 2) = {1000, 10000, 100000} + Dim As Integer ff, i, j, limit + Dim As String contents, pi_digits + + ff = Freefile + If Open("piDigits.txt" For Input As #ff) = 0 Then + contents = Input(Lof(ff), ff) + Close #ff + Else + Print "Error: Could not open piDigits.txt" + Exit Sub + End If + + For i = 0 To 2 + limit = limits(i) + pi_digits = Left(contents, limit) + + DimAs Double t0 = Timer + + Dim As AllSubstringsInfo results + FindLongestRepeatedSubstrings(pi_digits, results) + + Dim As Double elapsed = Timer - t0 + + Print "First "; limit; " digits of pi has longest repeated substrings:" + If results.count > 0 Then + For j = 0 To results.count - 1 + Print " '" & results.substrings(j).substring & "' starting at indices " & results.substrings(j).positions + Next + Else + Print " No repeated substrings found." + End If + + Print Using !"Time taken: ###.### seconds\n"; elapsed + Next + + Print "The timings show that the implementation has approximately linear performance." +End Sub + +main() + +Sleep diff --git a/Task/Ukkonen-s-suffix-tree-construction/FreeBASIC/ukkonen-s-suffix-tree-construction-2.basic b/Task/Ukkonen-s-suffix-tree-construction/FreeBASIC/ukkonen-s-suffix-tree-construction-2.basic new file mode 100644 index 0000000000..7031cea706 --- /dev/null +++ b/Task/Ukkonen-s-suffix-tree-construction/FreeBASIC/ukkonen-s-suffix-tree-construction-2.basic @@ -0,0 +1,295 @@ +Type SuffixType + index As Integer + suffix As String +End Type + +Type SubstringInfo + substring As String + positions As String +End Type + +Type AllSubstringsInfo + substrings(100) As SubstringInfo + count As Integer + max_length As Integer +End Type + +Function LongestCommonPrefix(s1 As String, s2 As String) As Integer + Dim minLen As Integer = Iif(Len(s1) < Len(s2), Len(s1), Len(s2)) + + For i As Integer = 1 To minLen + If Mid(s1, i, 1) <> Mid(s2, i, 1) Then Return i - 1 + Next + + Return minLen +End Function + +Sub FindLongestRepeatedSubstringsOptimized(text As String, Byref result As AllSubstringsInfo) + Dim As Integer i, j, k + + result.count = 0 + result.max_length = 0 + + ' For large data sets, we use a sliding window approach with a hash table + ' to search for matches. + Dim As Integer maxWindowSize = 100 ' Maximum window size to search + + ' Start with a large window and gradually reduce it. + For windowSize As Integer = maxWindowSize To 5 Step -1 + Dim hashTable(0 To 9999) As String ' Simple hash table + + ' Clear hash table + For i = 0 To 9999 + hashTable(i) = "" + Next + + ' Search for substrings of length windowSize + For i = 0 To Len(text) - windowSize + Dim substring As String = Mid(text, i + 1, windowSize) + + ' Calculate a simple hash + Dim hash As Integer = 0 + For j = 1 To Len(substring) + hash = (hash * 31 + Asc(Mid(substring, j, 1))) Mod 10000 + Next + + ' Check for collisions in the hash table + If hashTable(hash) <> "" Then + ' Possible match, check + Dim entries() As String + Dim entryCount As Integer + + ' Manually split the string by commas + Dim currentEntry As String = "" + For j = 1 To Len(hashTable(hash)) + Dim c As String = Mid(hashTable(hash), j, 1) + If c = "," Then + If currentEntry <> "" Then + Redim Preserve entries(0 To entryCount) + entries(entryCount) = currentEntry + entryCount += 1 + currentEntry = "" + End If + Else + currentEntry &= c + End If + Next + + ' Don't forget the last entry + If currentEntry <> "" Then + Redim Preserve entries(0 To entryCount) + entries(entryCount) = currentEntry + entryCount += 1 + End If + + For j = 0 To entryCount - 1 + Dim entry As String = entries(j) + If entry = "" Then Continue For + + Dim entryPos As Integer = Val(entry) + Dim entrySubstring As String = Mid(text, entryPos + 1, windowSize) + + If entrySubstring = substring Then + ' We found a match! + result.max_length = windowSize + + ' Verificar si ya tenemos esta subcadena + Dim found As Boolean = False + For k = 0 To result.count - 1 + If result.substrings(k).substring = substring Then + found = True + Exit For + End If + Next + + If Not found Then + ' Collect all positions + Dim positions As String = "" + Dim posArray(0 To 1000) As Integer + Dim posCount As Integer = 0 + + ' Add current position + posArray(posCount) = i - 2 + posCount += 1 + + ' Add the found position + posArray(posCount) = entryPos - 2 + posCount += 1 + + ' Search for more occurrences + For k = 0 To Len(text) - windowSize + If k <> i And k <> entryPos And Mid(text, k + 1, windowSize) = substring Then + posArray(posCount) = k - 2 + posCount += 1 + End If + Next + + ' Sort positions (Bubble, inefficient but simple) + For k = 0 To posCount - 2 + For l As Integer = k + 1 To posCount - 1 + If posArray(k) > posArray(l) Then + Swap posArray(k), posArray(l) + End If + Next + Next + + For k = 0 To posCount - 1 + If k > 0 Then positions &= " " + positions &= Str(posArray(k)) + Next + + result.substrings(result.count).substring = substring + result.substrings(result.count).positions = positions + result.count += 1 + End If + + ' If we find enough results, exit + If result.count >= 10 Then Exit For + End If + Next + End If + + ' Add this position to the hash table + If hashTable(hash) = "" Then + hashTable(hash) = Str(i) + Else + hashTable(hash) &= "," & Str(i) + End If + Next + + ' If we find any repeated substring, exit + If result.count > 0 Then Exit For + Next +End Sub + +Sub FindLongestRepeatedSubstrings(text As String, Byref result As AllSubstringsInfo) + Dim As Integer i, j, k + + ' Use the algorithm optimized for large data sets + If Len(text) > 20000 Then + FindLongestRepeatedSubstringsOptimized(text, result) + Exit Sub + End If + + result.count = 0 + result.max_length = 0 + + Dim suffixes(0 To Len(text) - 1) As SuffixType + + For i = 0 To Len(text) - 1 + suffixes(i).index = i + suffixes(i).suffix = Mid(text, i + 1) + Next + + ' Sort suffixes (Bubble, inefficient but simple) + For i = 0 To Len(text) - 2 + For j = i + 1 To Len(text) - 1 + If suffixes(i).suffix > suffixes(j).suffix Then + Swap suffixes(i), suffixes(j) + End If + Next + Next + + Dim maxLength As Integer = 0 + + For i = 0 To Len(text) - 2 + Dim prefixLen As Integer = LongestCommonPrefix(suffixes(i).suffix, suffixes(i + 1).suffix) + If prefixLen > maxLength Then maxLength = prefixLen + Next + + If maxLength = 0 Then Exit Sub + + result.max_length = maxLength + + For i = 0 To Len(text) - 2 + Dim prefixLen As Integer = LongestCommonPrefix(suffixes(i).suffix, suffixes(i + 1).suffix) + If prefixLen = maxLength Then + Dim substring As String = Left(suffixes(i).suffix, maxLength) + + Dim found As Boolean = False + For j = 0 To result.count - 1 + If result.substrings(j).substring = substring Then + found = True + Exit For + End If + Next + + If Not found Then + Dim positions As String = "" + Dim posCount As Integer = 0 + Dim posArray(0 To 100) As Integer + + For j = 0 To Len(text) - 1 + If Left(suffixes(j).suffix, maxLength) = substring Then + posArray(posCount) = suffixes(j).index - 2 + posCount += 1 + End If + Next + + ' Sort positions (from lowest to highest) + For j = 0 To posCount - 2 + For k = j + 1 To posCount - 1 + If posArray(j) > posArray(k) Then + Swap posArray(j), posArray(k) + End If + Next + Next + + For j = 0 To posCount - 1 + If j > 0 Then positions &= " " + positions &= Str(posArray(j)) + Next + + result.substrings(result.count).substring = substring + result.substrings(result.count).positions = positions + result.count += 1 + End If + End If + Next +End Sub + +Sub main() + Dim limits(0 To 2) As Integer = {1000, 10000, 100000} + + Dim As Integer ff, i, j, limit + Dim As String contents + + ff = Freefile + If Open("piDigits.txt" For Input As #ff) = 0 Then + contents = Input(Lof(ff), ff) + Close #ff + Else + Print "Error: Could not open piDigits.txt" + Exit Sub + End If + + For i = 0 To 2 + limit = limits(i) + Dim As String pi_digits = Left(contents, limit) + + Dim As Double t0 = Timer + + Dim results As AllSubstringsInfo + FindLongestRepeatedSubstrings(pi_digits, results) + + Dim As Double elapsed = Timer - t0 + + Print "First " & limit & " digits of pi has longest repeated characters:" + + If results.count > 0 Then + For j = 0 To results.count - 1 + Print " '" & results.substrings(j).substring & "' starting at indices " & results.substrings(j).positions + Next + Else + Print " No repeated substrings found." + End If + + Print Using !"Time taken: ###.### seconds\n"; elapsed + Next + + Print "The timings show that the implementation has approximately linear performance." +End Sub + +main() + +Sleep diff --git a/Task/Ukkonen-s-suffix-tree-construction/JavaScript/ukkonen-s-suffix-tree-construction.js b/Task/Ukkonen-s-suffix-tree-construction/JavaScript/ukkonen-s-suffix-tree-construction.js new file mode 100644 index 0000000000..755cedc059 --- /dev/null +++ b/Task/Ukkonen-s-suffix-tree-construction/JavaScript/ukkonen-s-suffix-tree-construction.js @@ -0,0 +1,196 @@ +const fs = require('fs'); + +UNDEFINED = -1; +LEAF_NODE = Number.MAX_SAFE_INTEGER; + +class SuffixTree { + constructor(aWord) { + this.text = Array.from(aWord); + this.text.push('\uF123'); // Terminal character + + this.nodes = new Array(2 * this.text.length); + this.root = this.newNode(this.UNDEFINED, this.UNDEFINED); + this.activeNode = this.root; + + this.textIndex = 0; + this.currentNode = 0; + this.needParentLink = this.UNDEFINED; + this.remainder = 0; + this.leafIndexGenerator = 0; + + for (let i = 0; i < this.text.length; i++) { + this.extendSuffixTree(this.text[i]); + } + } + + getLongestRepeatedSubstrings() { + const indexes = this.doTraversal(); + const word = this.text.slice(0, this.text.length - 1).join(''); + const result = {}; + + if (indexes[0] > 0) { + for (let i = 1; i < indexes.length; i++) { + const substring = word.substring(indexes[i], indexes[i] + indexes[0]); + if (!result[substring]) { + result[substring] = new Set(); + } + result[substring].add(indexes[i]); + } + } + + return result; + } + + extendSuffixTree(aCharacter) { + this.needParentLink = this.UNDEFINED; + this.remainder++; + + while (this.remainder > 0) { + if (this.activeLength === 0) { + this.activeEdge = this.textIndex; + } + + if (!this.nodes[this.activeNode].children.hasOwnProperty(this.text[this.activeEdge])) { + const leaf = this.newNode(this.textIndex, this.LEAF_NODE); + this.nodes[this.activeNode].children[this.text[this.activeEdge]] = leaf; + this.addSuffixLink(this.activeNode); + } else { + const next = this.nodes[this.activeNode].children[this.text[this.activeEdge]]; + if (this.walkDown(next)) { + continue; + } + + if (this.text[this.nodes[next].start + this.activeLength] === aCharacter) { + this.activeLength++; + this.addSuffixLink(this.activeNode); + break; + } + + const split = this.newNode(this.nodes[next].start, this.nodes[next].start + this.activeLength); + this.nodes[this.activeNode].children[this.text[this.activeEdge]] = split; + const leaf = this.newNode(this.textIndex, this.LEAF_NODE); + this.nodes[split].children[aCharacter] = leaf; + this.nodes[next].start += this.activeLength; + this.nodes[split].children[this.text[this.nodes[next].start]] = next; + this.addSuffixLink(split); + } + + this.remainder--; + + if (this.activeNode === this.root && this.activeLength > 0) { + this.activeLength--; + this.activeEdge = this.textIndex - this.remainder + 1; + } else { + this.activeNode = (this.nodes[this.activeNode].parentLink > 0) ? this.nodes[this.activeNode].parentLink : this.root; + } + } + + this.textIndex++; + } + + walkDown(aNode) { + if (this.activeLength >= this.nodes[aNode].edgeLength()) { + this.activeEdge += this.nodes[aNode].edgeLength(); + this.activeLength -= this.nodes[aNode].edgeLength(); + this.activeNode = aNode; + + return true; + } + + return false; + } + + addSuffixLink(aNode) { + if (this.needParentLink !== this.UNDEFINED) { + this.nodes[this.needParentLink].parentLink = aNode; + } + + this.needParentLink = aNode; + } + + newNode(aStart, aEnd) { + const node = new Node(aStart, aEnd); + node.leafIndex = (aEnd === this.LEAF_NODE) ? this.leafIndexGenerator++ : this.UNDEFINED; + this.nodes[this.currentNode] = node; + + return this.currentNode++; + } + + doTraversal() { + const indexes = [this.UNDEFINED]; + + return this.traversal(indexes, this.nodes[this.root], 0); + } + + traversal(aIndexes, aNode, aHeight) { + if (aNode.leafIndex === this.UNDEFINED) { + for (const index of Object.values(aNode.children)) { + const child = this.nodes[index]; + this.traversal(aIndexes, child, aHeight + child.edgeLength()); + } + } else if (aIndexes[0] < aHeight - aNode.edgeLength()) { + aIndexes.length = 0; + aIndexes.push(aHeight - aNode.edgeLength()); + aIndexes.push(aNode.leafIndex); + } else if (aIndexes[0] === aHeight - aNode.edgeLength()) { + aIndexes.push(aNode.leafIndex); + } + + return aIndexes; + } + + + +} + +class Node { + constructor(aStart, aEnd) { + this.start = aStart; + this.end = aEnd; + this.parentLink = 0; + this.leafIndex = 0; + this.children = {}; + } + + edgeLength() { + return Math.min(this.end, suffixTree.textIndex + 1) - this.start; + } +} + + +async function main() { + const limits = [1000, 10000, 100000]; + const piDigitsFile = 'piDigits.txt'; + + try { + const contents = await fs.promises.readFile(piDigitsFile, 'utf8'); + + for (const limit of limits) { + const piDigits = contents.substring(0, limit + 1); + + const start = Date.now(); + suffixTree = new SuffixTree(piDigits); + const substrings = suffixTree.getLongestRepeatedSubstrings(); + const end = Date.now(); + + console.log(`First ${limit} digits of pi has longest repeated characters:`); + for (const substring in substrings) { + if (substrings.hasOwnProperty(substring)) { + const indexes = Array.from(substrings[substring]); + console.log(` '${substring}' starting at index ${indexes.join(' and ')}`); + } + } + + console.log(`Time taken: ${end - start} milliseconds.\n`); + } + + console.log("The timings show that the implementation has approximately linear performance."); + + } catch (err) { + console.error("An error occurred:", err); + } +} + +let suffixTree; + +main(); diff --git a/Task/Ukkonen-s-suffix-tree-construction/Rust/ukkonen-s-suffix-tree-construction.rs b/Task/Ukkonen-s-suffix-tree-construction/Rust/ukkonen-s-suffix-tree-construction.rs new file mode 100644 index 0000000000..d7a794d714 --- /dev/null +++ b/Task/Ukkonen-s-suffix-tree-construction/Rust/ukkonen-s-suffix-tree-construction.rs @@ -0,0 +1,250 @@ +use std::collections::{HashMap, HashSet}; +use std::fs::File; +use std::io::Read; +use std::time::Instant; +use std::cmp::min; + +struct Node { + start: i32, + end: i32, + parent_link: i32, + leaf_index: i32, + children: HashMap, +} + +impl Node { + fn new(start: i32, end: i32) -> Self { + Node { + start, + end, + parent_link: 0, + leaf_index: 0, + children: HashMap::new(), + } + } + + fn edge_length(&self, text_index: i32) -> i32 { + min(self.end, text_index + 1) - self.start + } +} + +struct SuffixTree { + nodes: Vec, + text: String, + root: i32, + active_node: i32, + active_length: i32, + active_edge: i32, + text_index: i32, + current_node: i32, + need_parent_link: i32, + remainder: i32, + leaf_index_generator: i32, +} + +impl SuffixTree { + const UNDEFINED: i32 = -1; + const LEAF_NODE: i32 = i32::MAX; + + fn new(word: &str) -> Self { + let mut text = String::from(word); + text.push('\u{0004}'); // Terminal character + + let mut tree = SuffixTree { + nodes: Vec::with_capacity(2 * text.len()), + text, + root: 0, + active_node: 0, + active_length: 0, + active_edge: 0, + text_index: 0, + current_node: 0, + need_parent_link: 0, + remainder: 0, + leaf_index_generator: 0, + }; + + // Initialize nodes vector with a placeholder to allow indexing from 0 + for _ in 0..2 * tree.text.len() { + tree.nodes.push(Node::new(Self::UNDEFINED, Self::UNDEFINED)); + } + + tree.root = tree.new_node(Self::UNDEFINED, Self::UNDEFINED); + tree.active_node = tree.root; + + // Build the suffix tree + for ch in tree.text.chars().collect::>() { + tree.extend_suffix_tree(ch); + } + + tree + } + + fn extend_suffix_tree(&mut self, character: char) { + self.need_parent_link = Self::UNDEFINED; + self.remainder += 1; + + let text_chars: Vec = self.text.chars().collect(); + + while self.remainder > 0 { + if self.active_length == 0 { + self.active_edge = self.text_index; + } + + let active_edge_char = text_chars[self.active_edge as usize]; + + if !self.nodes[self.active_node as usize].children.contains_key(&active_edge_char) { + let leaf = self.new_node(self.text_index, Self::LEAF_NODE); + self.nodes[self.active_node as usize].children.insert(active_edge_char, leaf); + self.add_suffix_link(self.active_node); + } else { + let next = *self.nodes[self.active_node as usize].children.get(&active_edge_char).unwrap(); + if self.walk_down(next) { + continue; + } + + if text_chars[(self.nodes[next as usize].start + self.active_length) as usize] == character { + self.active_length += 1; + self.add_suffix_link(self.active_node); + break; + } + + let split = self.new_node( + self.nodes[next as usize].start, + self.nodes[next as usize].start + self.active_length, + ); + self.nodes[self.active_node as usize].children.insert(active_edge_char, split); + + let leaf = self.new_node(self.text_index, Self::LEAF_NODE); + self.nodes[split as usize].children.insert(character, leaf); + + self.nodes[next as usize].start += self.active_length; + let next_start_char = text_chars[self.nodes[next as usize].start as usize]; + self.nodes[split as usize].children.insert(next_start_char, next); + + self.add_suffix_link(split); + } + + self.remainder -= 1; + + if self.active_node == self.root && self.active_length > 0 { + self.active_length -= 1; + self.active_edge = self.text_index - self.remainder + 1; + } else { + self.active_node = if self.nodes[self.active_node as usize].parent_link > 0 { + self.nodes[self.active_node as usize].parent_link + } else { + self.root + }; + } + } + + self.text_index += 1; + } + + fn walk_down(&mut self, node: i32) -> bool { + if self.active_length >= self.nodes[node as usize].edge_length(self.text_index) { + self.active_edge += self.nodes[node as usize].edge_length(self.text_index); + self.active_length -= self.nodes[node as usize].edge_length(self.text_index); + self.active_node = node; + return true; + } + false + } + + fn add_suffix_link(&mut self, node: i32) { + if self.need_parent_link != Self::UNDEFINED { + self.nodes[self.need_parent_link as usize].parent_link = node; + } + self.need_parent_link = node; + } + + fn new_node(&mut self, start: i32, end: i32) -> i32 { + let node_index = self.current_node; + self.nodes[node_index as usize] = Node::new(start, end); + + if end == Self::LEAF_NODE { + self.nodes[node_index as usize].leaf_index = self.leaf_index_generator; + self.leaf_index_generator += 1; + } else { + self.nodes[node_index as usize].leaf_index = Self::UNDEFINED; + } + + self.current_node += 1; + node_index + } + + fn get_longest_repeated_substrings(&self) -> HashMap> { + let indexes = self.do_traversal(); + let text_chars: Vec = self.text.chars().collect(); + let mut result: HashMap> = HashMap::new(); + + if indexes[0] > 0 { + for i in 1..indexes.len() { + let substring: String = text_chars[indexes[i] as usize..(indexes[i] + indexes[0]) as usize].iter().collect(); + + result.entry(substring) + .or_insert_with(HashSet::new) + .insert(indexes[i]); + } + } + + result + } + + fn do_traversal(&self) -> Vec { + let mut indexes = vec![Self::UNDEFINED]; + self.traversal(&mut indexes, &self.nodes[self.root as usize], 0) + } + + fn traversal(&self, indexes: &mut Vec, node: &Node, height: i32) -> Vec { + if node.leaf_index == Self::UNDEFINED { + for (_, &child_index) in &node.children { + let child = &self.nodes[child_index as usize]; + self.traversal(indexes, child, height + child.edge_length(self.text_index)); + } + } else if indexes[0] < height - node.edge_length(self.text_index) { + indexes.clear(); + indexes.push(height - node.edge_length(self.text_index)); + indexes.push(node.leaf_index); + } else if indexes[0] == height - node.edge_length(self.text_index) { + indexes.push(node.leaf_index); + } + + indexes.clone() + } +} + +fn main() -> std::io::Result<()> { + let limits = [1_000, 10_000, 100_000]; + + let mut file = File::open("../piDigits.txt")?; + let mut contents = String::new(); + file.read_to_string(&mut contents)?; + + for &limit in &limits { + let pi_digits = &contents[0..limit]; + + println!("Processing first {} digits of pi...", limit); + + let start = Instant::now(); + let tree = SuffixTree::new(pi_digits); + let substrings = tree.get_longest_repeated_substrings(); + let duration = start.elapsed(); + + println!("First {} digits of pi has longest repeated characters:", limit); + for (substring, indexes) in &substrings { + print!(" '{}' starting at index ", substring); + for &index in indexes { + print!("{} ", index); + } + println!(); + } + + println!("Time taken: {:?}\n", duration); + } + + println!("The timings show that the implementation has approximately linear performance."); + + Ok(()) +} diff --git a/Task/Ulam-spiral-for-primes-/EasyLang/ulam-spiral-for-primes-.easy b/Task/Ulam-spiral-for-primes-/EasyLang/ulam-spiral-for-primes-.easy index ca9685ce85..dd72280f92 100644 --- a/Task/Ulam-spiral-for-primes-/EasyLang/ulam-spiral-for-primes-.easy +++ b/Task/Ulam-spiral-for-primes-/EasyLang/ulam-spiral-for-primes-.easy @@ -1,23 +1,14 @@ func isprim num . - if num < 2 - return 0 - . + if num < 2 : return 0 i = 2 while i <= sqrt num - if num mod i = 0 - return 0 - . + if num mod i = 0 : return 0 i += 1 . return 1 . -n = 1 -x = 50 -y = 50 -dx = 1 -dy = 0 # -proc turn . . +subr turn if dx = 1 dx = 0 dy = 1 @@ -32,30 +23,27 @@ proc turn . . dy = 0 . . -proc step . . +subr step n += 1 - x += dx * 1 - y += dy * 1 - move x y - if isprim n = 1 - circle 0.5 - . + x += dx + y += dy + if isprim n = 1 : gcircle x y 0.5 . -textsize 3 -move x y +gtextsize 3 +n = 1 +x = 50 +y = 50 +dx = 1 +dy = 0 lng = 0 # for k to 49 step lng += 2 turn - for j to lng - 1 - step - . + for j to lng - 1 : step for i to 3 turn - for j to lng - step - . + for j to lng : step . . diff --git a/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes--1.rexx b/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes--1.rexx deleted file mode 100644 index 5c8e667ceb..0000000000 --- a/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes--1.rexx +++ /dev/null @@ -1,48 +0,0 @@ -/*REXX program shows counter─clockwise Ulam spiral of primes shown in a square matrix.*/ -parse arg size init char . /*obtain optional arguments from the CL*/ -if size=='' | size=="," then size= 79 /*Not specified? Then use the default.*/ -if init=='' | init=="," then init= 1 /* " " " " " " */ -if char=='' then char= "█" /* " " " " " " */ -tot=size**2 /*the total number of numbers in spiral*/ - /*define the upper/bottom right corners*/ -uR.=0; bR.=0; do od=1 by 2 to tot; _=od**2+1; uR._=1; _=_+od; bR._=1; end /*od*/ - /*define the bottom/upper left corners.*/ -bL.=0; uL.=0; do ev=2 by 2 to tot; _=ev**2+1; bL._=1; _=_+ev; uL._=1; end /*ev*/ - -app=1; bigP=0; #p=0; inc=0; minR=1; maxR=1; r=1; $=0; $.=; !.= - /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ construct the spiral #s.*/ - do i=init for tot; r= r + inc; minR= min(minR, r); maxR= max(maxR, r) - x= isPrime(i); if x then bigP= max(bigP, i); #p= #p + x /*bigP, #primes.*/ - if app then $.r= $.r || x /*append token.*/ - else $.r= x || $.r /*prepend token.*/ - if uR.i then do; app= 1; inc= +1; iterate /*i*/; end /*advance ↓ */ - if bL.i then do; app= 0; inc= -1; iterate /*i*/; end /* " ↑ */ - if bR.i then do; app= 0; inc= 0; iterate /*i*/; end /* " ► */ - if uL.i then do; app= 1; inc= 0; iterate /*i*/; end /* " ◄ */ - end /*i*/ /* [↓] pack two */ - /*lines ──► one.*/ - do j=minR to maxR by 2; jp= j + 1; $= $ + 1 /*fold two lines*/ - do k=1 for length($.j); top= substr($.j, k, 1) /*the 1st line.*/ - bot= word( substr($.jp, k, 1) 0, 1) /*the 2nd line.*/ - if top then if bot then !.$= !.$'█' /*has top & bot.*/ - else !.$= !.$'▀' /*has top,¬ bot.*/ - else if bot then !.$= !.$'▄' /*¬ top, has bot*/ - else !.$= !.$' ' /*¬ top, ¬ bot*/ - end /*k*/ - end /*j*/ /* [↓] show the prime spiral matrix.*/ - do m=1 for $; say !.m; end /*m*/ -say; say init 'is the starting point,' , - tot 'numbers used,' #p "primes found, largest prime:" bigP -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure; parse arg x; if wordpos(x, '2 3 5 7 11 13 17 19') \==0 then return 1 - if x<17 then return 0; if x// 2 ==0 then return 0 - if x// 3 ==0 then return 0 - /*get the last digit*/ parse var x '' -1 _; if _==5 then return 0 - if x// 7 ==0 then return 0 - if x//11 ==0 then return 0 - if x//13 ==0 then return 0 - - do j=17 by 6 until j*j > x; if x//j ==0 then return 0 - if x//(j+2) ==0 then return 0 - end /*j*/; return 1 diff --git a/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes--2.rexx b/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes--2.rexx deleted file mode 100644 index 67dd6d6a78..0000000000 --- a/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes--2.rexx +++ /dev/null @@ -1,48 +0,0 @@ -/*REXX program shows a clockwise Ulam spiral of primes shown in a square matrix.*/ -parse arg size init char . /*obtain optional arguments from the CL*/ -if size=='' | size=="," then size= 79 /*Not specified? Then use the default.*/ -if init=='' | init=="," then init= 1 /* " " " " " " */ -if char=='' then char= "█" /* " " " " " " */ -tot=size**2 /*the total number of numbers in spiral*/ - /*define the upper/bottom right corners*/ -uR.=0; bR.=0; do od=1 by 2 to tot; _=od**2+init; uR._=1; _=_+od; bR._=1; end /*od*/ - /*define the bottom/upper left corners.*/ -bL.=0; uL.=0; do ev=2 by 2 to tot; _=ev**2+init; bL._=1; _=_+ev; uL._=1; end /*ev*/ - -app=1; bigP=0; #p=0; inc=0; minR=1; maxR=1; r=1; $=0; $.=; !.= - /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ construct the spiral #s.*/ - do i=init for tot; r= r + inc; minR= min(minR, r); maxR= max(maxR, r) - x= isPrime(i); if x then bigP= max(bigP, i); #p= #p + x /*bigP, #primes.*/ - if app then $.r= $.r || x /*append token.*/ - else $.r= x || $.r /*prepend token.*/ - if uR.i then do; app= 1; inc= +1; iterate /*i*/; end /*advance ↓ */ - if bL.i then do; app= 0; inc= -1; iterate /*i*/; end /* " ↑ */ - if bR.i then do; app= 0; inc= 0; iterate /*i*/; end /* " ► */ - if uL.i then do; app= 1; inc= 0; iterate /*i*/; end /* " ◄ */ - end /*i*/ /* [↓] pack two */ - /*lines ──► one.*/ - do j=minR to maxR by 2; jp= j + 1; $= $ + 1 /*fold two lines*/ - do k=1 for length($.j); top= substr($.j, k, 1) /*the 1st line.*/ - bot= word( substr($.jp, k, 1) 0, 1) /*the 2nd line.*/ - if top then if bot then !.$= !.$'█' /*has top & bot.*/ - else !.$= !.$'▀' /*has top,¬ bot.*/ - else if bot then !.$= !.$'▄' /*¬ top, has bot*/ - else !.$= !.$' ' /*¬ top, ¬ bot*/ - end /*k*/ - end /*j*/ /* [↓] show the prime spiral matrix.*/ - do m=1 for $; say !.m; end /*m*/ -say; say init 'is the starting point,' , - tot 'numbers used,' #p "primes found, largest prime:" bigP -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -isPrime: procedure; parse arg x; if wordpos(x, '2 3 5 7 11 13 17 19') \==0 then return 1 - if x<17 then return 0; if x// 2 ==0 then return 0 - if x// 3 ==0 then return 0 - /*get the last digit*/ parse var x '' -1 _; if _==5 then return 0 - if x// 7 ==0 then return 0 - if x//11 ==0 then return 0 - if x//13 ==0 then return 0 - - do j=17 by 6 until j*j > x; if x//j ==0 then return 0 - if x//(j+2) ==0 then return 0 - end /*j*/; return 1 diff --git a/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes-.rexx b/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes-.rexx new file mode 100644 index 0000000000..d0ee3b6b14 --- /dev/null +++ b/Task/Ulam-spiral-for-primes-/REXX/ulam-spiral-for-primes-.rexx @@ -0,0 +1,98 @@ +-- 25 Apr 2025 +include Settings +arg size','init + +say 'ULAM SPIRAL' +say version +say +call Parameters +call Corners +call Spiral +call Pack +call Display +call Timer +exit + +Parameters: +if size = '' then + size = 79 +tot = size**2 +if init = '' then + init = 1 +return + +Corners: +ur. = 0; br. = 0 +do od = 1 by 2 to tot + u = od**2+1; ur.u = 1; u = u+od; br.u = 1 +end +bl. = 0; ul. = 0 +do ev = 2 by 2 to tot + u = ev**2+1; bl.u = 1; u = u+ev; ul.u = 1 +end +return + +Spiral: +app = 1; bigp = 0; hp = 0; inc = 0 +minr = 1; maxr = 1; r = 1; d = 0; d. = ''; e. = '' +do i = init for tot + r = r + inc; minr = Min(minr,r); maxr = Max(maxr,r) + x = Prime(i) + if x then + bigp = Max(bigp,i) + hp = hp + x + if app then + d.r = d.r||x + else + d.r = x||d.r + if ur.i then do + app = 1; inc = +1 + iterate i + end + if bl.i then do + app = 0; inc = -1 + iterate i + end + if br.i then do + app = 0; inc = 0 + iterate i + end + if ul.i then do + app = 1; inc = 0 + iterate i + end +end +return + +Pack: +do j = minr by 2 to maxr + jp = j+1; d = d+1 + do k = 1 for Length(d.j) + top = Substr(d.j,k,1) + bot = Word(Substr(d.jp,k,1) 0,1) + if top then + if bot then + e.d = e.d||'DB'x + else + e.d = e.d||'DF'x + else + if bot then + e.d = e.d||'DC'x + else + e.d = e.d' ' + end +end +return + +Display: +do m = 1 for d + say e.m +end +say +say init 'starting point,' tot 'numbers,' hp 'primes,' bigp 'largest prime' +return + +include Functions +include Numbers +include Helper +include Abend diff --git a/Task/Unicode-strings/Tcl/unicode-strings.tcl b/Task/Unicode-strings/Tcl/unicode-strings.tcl new file mode 100644 index 0000000000..b85e2903cb --- /dev/null +++ b/Task/Unicode-strings/Tcl/unicode-strings.tcl @@ -0,0 +1,52 @@ +# list of sequential integers +proc range { n m } { + set res {} + while {$n <= $m} {lappend res $n ; incr n } + return $res +} + +# print utf-8 char from integer range +proc utf8_range {n m {enc utf-8} } { + + # save encoding + set old_enc [encoding system] + + set streams [list stdin stdout stderr] + + # set new encoding + encoding system $enc + + foreach stream $streams { + fconfigure $stream -encoding $enc + } + + set n [range $n $m] + + set len 0 + + # convert int to char in encoding + # print 30 per line + foreach c $n { + set s [encoding convertto $enc $c] + set char [format %c $s] + puts -nonewline "${char} " + if {[expr {$len % 19}] == 0} {puts ""} + incr len + } + + puts "" + + #restore encoding + foreach stream $streams { + fconfigure $stream -encoding $old_enc + } + encoding system $old_enc +} + + +# utf-8 graphics +scan 2580 %x start +scan 27FF %x stop + +puts "utf-8 glyphs" +utf8_range $start $stop diff --git a/Task/Unicode-variable-names/Ballerina/unicode-variable-names.ballerina b/Task/Unicode-variable-names/Ballerina/unicode-variable-names.ballerina new file mode 100644 index 0000000000..6b80329cf7 --- /dev/null +++ b/Task/Unicode-variable-names/Ballerina/unicode-variable-names.ballerina @@ -0,0 +1,7 @@ +import ballerina/io; + +public function main() { + int Δ = 1; + Δ += 1; + io:println(Δ); +} diff --git a/Task/Unicode-variable-names/Odin/unicode-variable-names.odin b/Task/Unicode-variable-names/Odin/unicode-variable-names.odin new file mode 100644 index 0000000000..f55ed386f2 --- /dev/null +++ b/Task/Unicode-variable-names/Odin/unicode-variable-names.odin @@ -0,0 +1,11 @@ +package main + +import "core:fmt" + + +main :: proc() { + + Δ:= 1 + Δ = Δ +1 + fmt.println(Δ) +} diff --git a/Task/Unicode-variable-names/Scheme/unicode-variable-names.scm b/Task/Unicode-variable-names/Scheme/unicode-variable-names.scm new file mode 100644 index 0000000000..4984384c8f --- /dev/null +++ b/Task/Unicode-variable-names/Scheme/unicode-variable-names.scm @@ -0,0 +1,4 @@ +(define Δ 1) +Δ +(set! Δ (+ 1 Δ)) +Δ diff --git a/Task/Universal-Turing-machine/EasyLang/universal-turing-machine.easy b/Task/Universal-Turing-machine/EasyLang/universal-turing-machine.easy index 5d124545bd..2e4257d861 100644 --- a/Task/Universal-Turing-machine/EasyLang/universal-turing-machine.easy +++ b/Task/Universal-Turing-machine/EasyLang/universal-turing-machine.easy @@ -1,9 +1,7 @@ global right$[] left$[] pos blank$ . -proc show stat$ . . +proc show stat$ . write stat$ - for i to 5 - len stat$ - write " " - . + for i to 5 - len stat$ : write " " write "| " h = -len left$[] + 1 for i = h to len right$[] @@ -22,31 +20,29 @@ proc show stat$ . . print "" . func$ get . - if pos <= 0 - return left$[-pos + 1] - . + if pos <= 0 : return left$[-pos + 1] return right$[pos] . -proc put s$ . . +proc put s$ . if pos <= 0 left$[-pos + 1] = s$ else right$[pos] = s$ . . -proc mleft . . +proc mleft . pos -= 1 if pos <= 0 and len left$[] < (-pos + 1) left$[] &= blank$ . . -proc mright . . +proc mright . pos += 1 if pos > 0 and len right$[] < pos right$[] &= blank$ . . -proc utm stat$ endstat$ bl$ init$ rules$[] trace . . +proc utm stat$ endstat$ bl$ init$ rules$[] trace . blank$ = bl$ pos = 1 right$[] = strsplit init$ " " @@ -57,10 +53,8 @@ proc utm stat$ endstat$ bl$ init$ rules$[] trace . . repeat if trace = 1 show stat$ - else - if steps mod 1000000 = 0 - write "." - . + elif steps mod 1000000 = 0 + write "." . for i to len r$[][] if r$[i][1] = stat$ and r$[i][2] = get diff --git a/Task/Unprimeable-numbers/EasyLang/unprimeable-numbers.easy b/Task/Unprimeable-numbers/EasyLang/unprimeable-numbers.easy new file mode 100644 index 0000000000..89c38321ba --- /dev/null +++ b/Task/Unprimeable-numbers/EasyLang/unprimeable-numbers.easy @@ -0,0 +1,36 @@ +fastfunc isprim num . + i = 2 + while i <= sqrt num + if num mod i = 0 : return 0 + i += 1 + . + return 1 +. +func isunprim n . + n$[] = strchars n + for i to len n$[] + s$ = n$[i] + for d = 0 to 9 + n$[i] = d + h = number strjoin n$[] "" + if isprim h = 1 : return 0 + . + n$[i] = s$ + . + return 1 +. +n = 1 +while cnt < 35 + if isunprim n = 1 + write n & " " + cnt += 1 + . + n += 1 +. +print "" +repeat + if isunprim n = 1 : cnt += 1 + until cnt = 600 + n += 1 +. +print n diff --git a/Task/Unprimeable-numbers/REXX/unprimeable-numbers.rexx b/Task/Unprimeable-numbers/REXX/unprimeable-numbers.rexx index f10a124567..a6ca596e28 100644 --- a/Task/Unprimeable-numbers/REXX/unprimeable-numbers.rexx +++ b/Task/Unprimeable-numbers/REXX/unprimeable-numbers.rexx @@ -1,68 +1,94 @@ -/*REXX program finds and displays unprimeable numbers (non─negative integers). */ -parse arg n x hp . /*obtain optional arguments from the CL*/ -if n=='' | n=="," then n= 35 /*Not specified? Then use the default.*/ -if x=='' | x=="," then x= 600 /* " " " " " " */ -if hp=='' | hp=="," then hp= 10000000 /* " " " " " " */ -u= 0 /*number of unprimeable numbers so far.*/ -eds=4; ed.1= 1; ed.2= 3; ed.3= 7; ed.4= 9 /*"end" digits which are prime; prime>9*/ -call genP hp /*generate primes up to & including HP.*/ -$$=; $.=. /*a list " " " " " */ - do j=100; if !.j then iterate /*Prime? Unprimeable must be composite*/ - Lm= length(j) /*obtain the length-1 of the number J. */ - meat= left(j, Lm) /*obtain the first Lm digits of J. */ - /* [↑] examine the "end" digit of J. */ - do e_=1 for eds; new= meat || ed.e_ /*obtain a different number (than J).*/ - if new==j then iterate /*Is it the original number? Then skip.*/ - if !.new then iterate j /*This new number a prime? " " */ - end /*e_*/ - /* [↑] examine a new 1st digit of J. */ - do f_=0 for 10; new= (f_||meat) + 0 /*obtain a different number (than J).*/ - if new==j then iterate /*Is it the original number? Then skip.*/ - if !.new then iterate j /*This new number a prime? " " */ - end /*f_*/ /* [↑] examine the front digit of J. */ - do a_= 2 for Lm-1 /*traipse through the middle digits. */ - meat= left(j, a_ - 1) /*use a number of left─most dec. digits*/ - rest= substr(j, a_ + 1) /* " " " " right─most " " */ - do n_=0 for 10 /*traipse through all 1─digit numbers. */ - new= meat || n_ || rest /*construct new number, like a phoenix.*/ - if new==j then iterate /*Is it the original number? Then skip.*/ - if !.new then iterate j /*This new number a prime? " " */ - end /*n_*/ - end /*a_*/ - u= u + 1 /*bump the count of unprimeable numbers*/ - if u<=n then $$= $$ commas(j) /*maybe add unprimeable # to $$ list.*/ - if u==x then $.ox= commas(j) /*assign the Xth unprimeable number.*/ - parse var j '' -1 _ /*obtain the right─most dec digit of J.*/ - if $._==. then $._= j /*the 1st unprimeable # that ends in _.*/ - if $.3==. then iterate; if $.7==. then iterate /*test if specific #'s found.*/ - if $.1==. then iterate; if $.9==. then iterate /* " " " " " */ - leave /*if here, then we're done. */ - end /*j*/ +-- 22 Mar 2025 +include Settings -if n>0 then do; say center(' first ' n "unprimeable numbers ", 139, '═') - say strip($$); say - end -if x>0 then say ' the ' th(x) " unprimeable number is: " $.ox +say 'UNPRIMEABLE NUMBERS' +say version say - do o=0 for 10; if length($.o)==0 then iterate - say ' the first unprimeable number that ends in ' o " is:"right(commas($.o),11) - end /*o*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg ?; do c=length(?)-3 to 1 by -3; ?=insert(',', ?, c); end; return ? -th:procedure;parse arg x;return x||word('th st nd rd',1+(x//10)*(x//100%10\==1)*(x//10<4)) -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13; @.7=17; @.8=19; @.9=23; @.10=29; @.11=31 - !.=0; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1; !.13=1; !.17=1; !.19=1; !.23=1; !.29=1 - #= 11; sq.#= @.# **2 - do lim=100 until lim*lim>=hp /*only keep primes up to the sqrt(hp). */ - end /*lim*/ /* [↑] find limit for storing primes. */ - do j=@.#+2 by 2 to hp; parse var j '' -1 _; if _==5 then iterate /*÷ by 5?*/ - if j// 3==0 then iterate; if j// 7==0 then iterate; if j//11==0 then iterate - if j//13==0 then iterate; if j//17==0 then iterate; if j//19==0 then iterate - if j//23==0 then iterate; if j//29==0 then iterate - do k=11 while sq.k<=j /*divide by some generated odd primes. */ - if j//@.k==0 then iterate j /*Is J divisible by P? Then not prime*/ - end /*k*/ /* [↓] a prime (J) has been found. */ - #= #+1; if #<=lim then @.#=j; !.j=1 /*bump prime count; assign prime to @. */ - sq.#= j*j /*calculate square of J for fast WHILE.*/ +call GetPrimes +call GetUnprimes +call Task1 +call Task2 +call GetLowest +call Task3 +exit + +GetPrimes: +procedure expose prim. flag. +call Time('r') +say 'Get primes up to 10 million...' +call Primes 1e7 +say prim.0 'primes found' +say Format(Time('e'),,3) 'seconds'; say +return + +GetUnprimes: +procedure expose flag. unpr. +call Time('r') +say 'Get unprimeable numbers up to 1.3 million...' +unpr. = 0; n = 0 +do i = 100 to 1.3e6 + if \ flag.i then do + a = 1; b = Length(i) + do j = a to b + c = Substr(i,j,1) + do k = 0 to 9 + d = Left(i,j-1)||k||Right(i,b-j); d = d+0 + if flag.d then + iterate i + end + end + n = n+1; unpr.n = i + end +end +unpr.0 = n +say unpr.0 'unprimeable numbers found' +say Format(Time('e'),,3) 'seconds'; say +return + +Task1: +procedure expose unpr. +call Time('r') +say 'The first 35 unprimeable numbers are' +do i = 1 to 35 + call Charout ,Right(unpr.i,4) +end +say +say Format(Time('e'),,3) 'seconds'; say +return + +Task2: +procedure expose unpr. +call Time('r') +say 'The 600th unprimeable number is' +say unpr.600 +say Format(Time('e'),,3) 'seconds'; say +return + +GetLowest: +procedure expose unpr. lowu. +call Time('r') +say 'Get lowest unprimeable number per digit...' +lowu. = 0 +do i = 1 to unpr.0 + a = Right(unpr.i,1) + if lowu.a = 0 then + lowu.a = unpr.i +end +say Format(Time('e'),,3) 'seconds'; say +return + +Task3: +procedure expose lowu. +call Time('r') +say 'Dig Lowest' +say '-----------' +do i = 0 to 9 + say Right(i,3) Right(lowu.i,7) +end +say '-----------' +say Format(Time('e'),,3) 'seconds'; say +return + +include Functions +include Sequences +include Abend diff --git a/Task/Untouchable-numbers/REXX/untouchable-numbers.rexx b/Task/Untouchable-numbers/REXX/untouchable-numbers.rexx index 7faaf0888c..80b2afae60 100644 --- a/Task/Untouchable-numbers/REXX/untouchable-numbers.rexx +++ b/Task/Untouchable-numbers/REXX/untouchable-numbers.rexx @@ -1,61 +1,88 @@ -/*REXX pgm finds N untouchable numbers (numbers that can't be equal to any aliquot sum).*/ -parse arg n cols tens over . /*obtain optional arguments from the CL*/ -if n='' | n=="," then n=2000 /*Not specified? Then use the default.*/ -if cols='' | cols=="," | cols==0 then cols= 10 /* " " " " " " */ -if tens='' | tens=="," then tens= 0 /* " " " " " " */ -if over='' | over=="," then over= 20 /* " " " " " " */ -tell= n>0; n= abs(n) /*N>0? Then display the untouchable #s*/ -call genP n * over /*call routine to generate some primes.*/ -u.= 0 /*define all possible aliquot sums ≡ 0.*/ - do p=1 for #; _= @.p + 1; u._= 1 /*any prime+1 is not an untouchable.*/ - _= @.p + 3; u._= 1 /* " prime+3 " " " " */ - end /*p*/ /* [↑] this will also rule out 5. */ -u.5= 0 /*special case as prime 2 + 3 sum to 5.*/ - do j=2 for lim; if !.j then iterate /*Is J a prime? Yes, then skip it. */ - y= sigmaP() /*compute: aliquot sum (sigma P) of J.*/ - if y<=n then u.y= 1 /*mark Y as a touchable if in range. */ - end /*j*/ -call show /*maybe show untouchable #s and a count*/ -if tens>0 then call powers /*Any "tens" specified? Calculate 'em.*/ -exit cnt /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? -genSq: do _=1 until _*_>lim; q._= _*_; end; q._= _*_; _= _+1; q._= _*_; return -grid: $= $ right( commas(t), w); if cnt//cols==0 then do; say $; $=; end; return -powers: do pr=1 for tens; call 'UNTOUCHA' -(10**pr); end /*recurse*/; return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: #= 9; @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13; @.7=17; @.8=19; @.9=23 /*a list*/ - !.=0; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1; !.13=1; !.17=1; !.19=1 !.23=1 /*primes*/ - parse arg lim; call genSq /*define the (high) limit for searching*/ - qq.10= 100 /*define square of the 10th prime index*/ - do j=@.#+6 by 2 to lim /*find odd primes from here on forward.*/ - parse var j '' -1 _; if _==5 then iterate; if j// 3==0 then iterate - if j// 7==0 then iterate; if j//11==0 then iterate; if j//13==0 then iterate - if j//17==0 then iterate; if j//19==0 then iterate; if j//23==0 then iterate - /*start dividing by the tenth prime: 29*/ - do k=10 while qq.k <= j /* [↓] divide J by known odd primes.*/ - if j//@.k==0 then iterate j /*J ÷ by a prime? Then ¬prime. ___ */ - end /*k*/ /* [↑] only process numbers ≤ √ J */ - #= #+1; @.#= j /*bump prime count; assign a new prime.*/ - !.j= 1; qq.#= j*j /*mark prime; compute square of prime.*/ - end /*j*/; return /*#: is the number of primes generated*/ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -show: w=7; $= right(2, w+1) right(5, w) /*start the list of an even prime and 5*/ - cnt= 2 /*count of the only two primes in list.*/ - do t=6 by 2 to n; if u.t then iterate /*Is T touchable? Then skip it. */ - cnt= cnt + 1; if tell then call grid /*bump count; maybe show a grid line. */ - end /*t*/ - if tell & $\=='' then say $ /*display a residual grid line, if any.*/ - if tell then say /*show a spacing blank line for output.*/ - if n>0 then say right( commas(cnt), 20) , /*indent the output a bit.*/ - ' untouchable numbers were found ≤ ' commas(n); return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sigmaP: s= 1 /*set initial sigma sum (S) to 1. ___*/ - if j//2 then do m=3 by 2 while q.m a then do + say right(n,5) 'below' right(a,6) + a = a*10 + end + n = n+1 +end +say +return + +include Sequences +include Helper +include Functions +include Special +include Constants +include Abend diff --git a/Task/Update-a-configuration-file/Lua/update-a-configuration-file.lua b/Task/Update-a-configuration-file/Lua/update-a-configuration-file.lua new file mode 100644 index 0000000000..b00f5fd77e --- /dev/null +++ b/Task/Update-a-configuration-file/Lua/update-a-configuration-file.lua @@ -0,0 +1,71 @@ +local function Read(handler) -- NR, line, comment, option, parameters + local line = handler:read"l" + if line==nil or line=="" or line:sub(1,1)=="#" or line:find"^;?%s*$" + then + return line,nil,nil,true + end + local comment, option, param = line:match"^(;?)%s*(%S*)%s*(.*)$" + comment = comment==";" + if not comment then + param = param=="" and true or tonumber(param) or param + end + return line, option, param, comment +end + +local function LoadConfig(H) + local options = {} + for line, option, param, comment in Read,H do + if not comment and option then + options[option] = param + end + end + H:close() + return options +end + +local function MakeLine(k,v) + return v==false and "; " .. k + or v==true and k + or v and k .. " " .. v +end + +local function Sponge(fileS) + local H, tmp = io.open(fileS), io.tmpfile() + tmp:write(H:read"a") tmp:seek"set" + H:close() + return tmp +end + +local function Update(fileS, options) + local IN = Sponge(fileS) + local nl = string.match(IN:read"L" or "\n", "[\r\n]?\n$") IN:seek"set" + local OUT = io.open(fileS, "w+") + local saved = {} -- for appending after + for line, option, param, comment in Read,IN do + if option then + local val = options[option] + saved[option] = true + if val~=param then + line = MakeLine(option,val) + end + end + OUT:write(line, nl) + end + IN:close() + for k,v in pairs(options) do + if saved[k]==nil then + OUT:write( MakeLine(k,v), nl ) + end + end + OUT:close() +end + +local options = LoadConfig( io.open(arg[1]) ) + +-- nil would remove the option entirely +options.NEEDSPEELING = false -- disable +options.SEEDSREMOVED = true +options.NUMBEROFBANANAS = 1024 +options.NUMBEROFSTRAWBERRIES = 62000 + +Update(arg[1], options) diff --git a/Task/User-input-Text/JavaScript/user-input-text-3.js b/Task/User-input-Text/JavaScript/user-input-text-3.js new file mode 100644 index 0000000000..25f1690938 --- /dev/null +++ b/Task/User-input-Text/JavaScript/user-input-text-3.js @@ -0,0 +1,16 @@ +const readline = require("readline"); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +rl.question("Enter a string: ", (str) => { + console.log(str); + rl.close(); +}); + +rl.question("Enter a number: ", (n) => { + console.log(parseInt(n)); + rl.close(); +}); diff --git a/Task/User-input-Text/Lua/user-input-text.lua b/Task/User-input-Text/Lua/user-input-text.lua index 6e6556e64d..783cda97b9 100644 --- a/Task/User-input-Text/Lua/user-input-text.lua +++ b/Task/User-input-Text/Lua/user-input-text.lua @@ -1,4 +1,4 @@ print('Enter a string: ') s = io.stdin:read() print('Enter a number: ') -i = tonumber(io.stdin:read()) +i = io.stdin:read"n" diff --git a/Task/User-input-Text/OPL/user-input-text.opl b/Task/User-input-Text/OPL/user-input-text.opl new file mode 100644 index 0000000000..69b94deba5 --- /dev/null +++ b/Task/User-input-Text/OPL/user-input-text.opl @@ -0,0 +1,30 @@ +PROC usrinpt: + LOCAL string$(15),number& + WHILE string$="" + PRINT "Please enter a string." + INPUT string$ + IF string$="" + PRINT "Nothing was entered. Please try again." + PAUSE 60 + CLS + ENDIF + ENDWH + PRINT "Thank you! You entered: ";string$ + WHILE number&<>75000 + PRINT "Please enter the number 75000." + TRAP INPUT number& + IF ERR=-1 + PRINT + PRINT "That's not a valid number. Please try again." + PAUSE 60 + CLS + ELSEIF number&<>75000 + PRINT "Wrong number. Please try again." + PAUSE 60 + CLS + ENDIF + ENDWH + PRINT "Good job! You successfully entered 75000!" + PRINT "Press any key to continue." + GET +ENDP diff --git a/Task/Validate-International-Securities-Identification-Number/Lua/validate-international-securities-identification-number.lua b/Task/Validate-International-Securities-Identification-Number/Lua/validate-international-securities-identification-number.lua index 47948c6341..f9aa419024 100644 --- a/Task/Validate-International-Securities-Identification-Number/Lua/validate-international-securities-identification-number.lua +++ b/Task/Validate-International-Securities-Identification-Number/Lua/validate-international-securities-identification-number.lua @@ -1,28 +1,11 @@ -function luhn (n) - local revStr, s1, s2, digit, mod = n:reverse(), 0, 0 - for pos = 1, #revStr do - digit = tonumber(revStr:sub(pos, pos)) - if pos % 2 == 1 then - s1 = s1 + digit - else - digit = digit * 2 - if digit > 9 then - mod = digit % 10 - digit = mod + ((digit - mod) / 10) - end - s2 = s2 + digit - end - end - return (s1 + s2) % 10 == 0 -end +-- Grab luhn function from https://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#Lua -function checkISIN (inStr) - if #inStr ~= 12 then return false end - local numStr = "" - for pos = 1, #inStr do - numStr = numStr .. tonumber(inStr:sub(pos, pos), 36) - end - return luhn(numStr) +local function ToBase36(char) return tonumber(char, 36) end +local function Isin2CCN(isin) return isin:gsub(".", ToBase36) end +local isinPattern = "^%u%u" .. ("[%d%u]"):rep(9) .. "%d$" + +function checkISIN (isin) + return isin:match(isinPattern) and luhn(Isin2CCN(isin)) or false end local testCases = { diff --git a/Task/Vampire-number/EasyLang/vampire-number.easy b/Task/Vampire-number/EasyLang/vampire-number.easy index 322f982d9d..a37e7a8019 100644 --- a/Task/Vampire-number/EasyLang/vampire-number.easy +++ b/Task/Vampire-number/EasyLang/vampire-number.easy @@ -5,12 +5,10 @@ func dtally x . . return t . -proc fangs x . f[] . +proc fangs x &f[] . f[] = [ ] nd = floor log10 x + 1 - if nd mod 2 = 1 - return - . + if nd mod 2 = 1 : return nd = nd div 2 lo = higher pow 10 (nd - 1) (x + pow 10 nd - 2) div (pow 10 nd - 1) hi = lower (x / lo) sqrt x @@ -22,11 +20,9 @@ proc fangs x . f[] . . . . -proc show_fangs x f[] . . +proc show_fangs x f[] . write x & " " - for f in f[] - write " = " & f & " x " & x div f - . + for f in f[] : write " = " & f & " x " & x div f print "" . x = 1 diff --git a/Task/Vampire-number/Raku/vampire-number.raku b/Task/Vampire-number/Raku/vampire-number.raku index 95004a9842..c29789c94d 100644 --- a/Task/Vampire-number/Raku/vampire-number.raku +++ b/Task/Vampire-number/Raku/vampire-number.raku @@ -1,17 +1,22 @@ +use Prime::Factor; + sub is_vampire (Int $num) { + return Empty unless $num % 9 == 0|4; my $digits = $num.comb.sort; my @fangs; - (10**$num.sqrt.log(10).floor .. $num.sqrt.ceiling).map: -> $this { - next if $num % $this; - my $that = $num div $this; - next if $this %% 10 && $that %% 10; - @fangs.push("$this x $that") if ($this ~ $that).comb.sort eq $digits; + my @divs = $num.&divisors(:s).grep({.chars == $num.chars div 2}); + return Empty unless @divs >= 2; + @divs.map: -> $this { + my $that = $num div $this; + next if $this %% 10 && $that %% 10; + last if $this > $that; + @fangs.push("$this x $that") if ($this ~ $that).comb.sort eq $digits; } @fangs } constant @vampires = flat (3..*).map: -> $s, $e { - (10**$s .. 10**$e).hyper.map: -> $n { + (flat (10**$s div 9 .. 10**$e div 9).map({my $v = $_ * 9, $v + 4})).hyper.map: -> $n { next unless my @fangs = is_vampire($n); "$n: { @fangs.join(', ') }" } diff --git a/Task/Variables/EasyLang/variables.easy b/Task/Variables/EasyLang/variables.easy index 200e43f282..c4a0740daf 100644 --- a/Task/Variables/EasyLang/variables.easy +++ b/Task/Variables/EasyLang/variables.easy @@ -6,7 +6,7 @@ print n # global array of numbers a[] = [ 2.1 3.14 3 ] # -proc foo . . +proc foo . # i is local, because it is first used in the function for i = 1 to len a[] print a[i] diff --git a/Task/Vector-products/REXX/vector-products.rexx b/Task/Vector-products/REXX/vector-products.rexx index facf79ebfb..d2687f7539 100644 --- a/Task/Vector-products/REXX/vector-products.rexx +++ b/Task/Vector-products/REXX/vector-products.rexx @@ -1,26 +1,28 @@ -/*REXX program computes the products: dot, cross, scalar triple, and vector triple.*/ -a= 3 4 5 -b= 4 3 5 /*(positive numbers don't need quotes.)*/ -c= '-5 -12 -13' -Call tellV 'vector A =', a /*show the A vector, aligned numbers.*/ -Call tellV "vector B =", b /* " " B " " " */ -Call tellV "vector C =", c /* " " C " " " */ -Say '' -Call tellV ' dot product [A·B] =', dot(a,b) -Call tellV 'cross product [AxB] =', cross(a,b) -Call tellV 'scalar triple product [A·(BxC)] =', dot(a,cross(b,c)) -Call tellV 'vector triple product [Ax(BxC)] =', cross(a,cross(b,c)) -Exit /*stick a fork in it, we're all done. */ -/*---------------------------------------------------------------------------*/ -cross: Procedure - Arg a b c, u v w - Return b*w-c*v c*u-a*w a*v-b*u -dot: Procedure - Arg a b c, u v w - Return a*u + b*v + c*w -/*---------------------------------------------------------------------------*/ -tellV: Procedure - Parse Arg name,x y z - w=max(4,length(x),length(y),length(z)) /*max width */ - Say right(name,33) right(x,w) right(y,w) right(z,w) /*show vector. */ - Return +-- 8 May 2025 +include Settings + +say 'VECTOR PRODUCTS' +say version +say +a = '3 4 5'; b = '4 3 5'; c = '-5 -12 -13'; d = '1 2 3' +say 'VALUES' +say 'A =' Vlst2Form(a) +say 'B =' Vlst2Form(b) +say 'C =' Vlst2Form(c) +say 'D =' Vlst2Form(d) +say +say 'BASICS' +say 'A . B =' Vdot(a,b)/1 +say 'A x B =' Vlst2Form(Vcross(a,b)) +say +say 'BONUS' +say 'A . (BxC) =' VscalTrip(a,b,c)/1 +say 'A x (BxC) =' Vlst2Form(VvectTrip(a,b,c)) +say '(AxB) . (CxD) =' VscalQuad(a,b,c,d)/1 +say '(AxB) x (CxD) =' Vlst2Form(VvectQuad(a,b,c,d)) +exit + +include Vector +include Functions +include Constants +include Abend diff --git a/Task/Vector/REXX/vector.rexx b/Task/Vector/REXX/vector.rexx index 2573cebcaa..2a7854d747 100644 --- a/Task/Vector/REXX/vector.rexx +++ b/Task/Vector/REXX/vector.rexx @@ -1,41 +1,31 @@ -/*REXX program shows how to support mathematical functions for vectors using functions. */ - s1 = 11 /*define the s1 scalar: eleven */ - s2 = 2 /*define the s2 scalar: two */ - x = '(5, 7)' /*define the X vector: five and seven*/ - y = '(2, 3)' /*define the Y vector: two and three*/ - z = '(2, 45)' /*define vector of length 2 at 45º */ -call show 'define a vector (length,ºangle):', z , Vdef(z) -call show 'addition (vector+vector):', x " + " y , Vadd(x, y) -call show 'subtraction (vector-vector):', x " - " y , vsub(x, y) -call show 'multiplication (Vector*scalar):', x " * " s1, Vmul(x, s1) -call show 'division (vector/scalar):', x " ÷ " s2, Vdiv(x, s2) -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -$fuzz: return min( arg(1), max(1, digits() - arg(2) ) ) -cosD: return cos( d2r( arg(1) ) ) -d2d: return arg(1) // 360 /*normalize degrees ──► a unit circle. */ -d2r: return r2r( d2d(arg(1)) * pi() / 180) /*convert degrees ──► radians. */ -pi: pi=3.14159265358979323846264338327950288419716939937510582; return pi -r2d: return d2d( (arg(1)*180 / pi())) /*convert radians ──► degrees. */ -r2r: return arg(1) // (pi() * 2) /*normalize radians ──► a unit circle. */ -show: say right( arg(1), 33) right( arg(2), 20) ' ──► ' arg(3); return -sinD: return sin( d2r( d2d( arg(1) ) ) ) -V: return word( translate( arg(1), , '{[(JI)]}') 0, 1) /*get the number or zero*/ -V$: parse arg r,c; _='['r; if c\=0 then _=_"," c; return _']' -V#: a=V(a); b=V(b); c=V(c); d=V(d); ac=a*c; ad=a*d; bc=b*c; bd=b*d; s=c*c+d*d; return -Vadd: procedure; arg a ',' b,c "," d; call V#; return V$(a+c, b+d) -Vsub: procedure; arg a ',' b,c "," d; call V#; return V$(a-c, b-d) -Vmul: procedure; arg a ',' b,c "," d; call V#; return V$(ac-bd, bc+ad) -Vdiv: procedure; arg a ',' b,c "," d; call V#; return V$((ac+bd)/s, (bc-ad)/s) -Vdef: procedure; arg a ',' b,c "," d; call V#; return V$(a*sinD(b), a*cosD(b)) -/*──────────────────────────────────────────────────────────────────────────────────────*/ -cos: procedure; parse arg x; x=r2r(x); a=abs(x); numeric fuzz $fuzz(9, 9) - if a=pi then return -1; - if a=pi*.5 | a=pi*2 then return 0; return .sinCos(1,-1) -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sin: procedure; parse arg x; x=r2r(x); numeric fuzz $fuzz(5, 3) - if x=pi*.5 then return 1; if x=pi*1.5 then return -1 - if abs(x)=pi | x=0 then return 0; return .sinCos(x,+1) -/*──────────────────────────────────────────────────────────────────────────────────────*/ -.sinCos: parse arg z 1 _,i; q=x*x - do k=2 by 2 until p=z; p=z; _= -_*q / (k*(k+i)); z=z+_; end; return z +-- 19 May 2025 +include Settings + +say 'VECTOR' +say version +say +a = '1 2 3'; b = '3 2 1'; c = 3; d = '4 5'; e = '2 1' +say 'VALUES' +say 'A =' Vlst2Form(a) +say 'B =' Vlst2Form(b) +say 'C =' c +say 'D =' Vlst2Form(d) +say 'E =' Vlst2Form(e) +say +say 'BASICS' +say 'A+B =' Vlst2Form(Vadd(a,b)) +say 'A-B =' Vlst2Form(Vsub(a,b)) +say 'A*C =' Vlst2Form(Vmul(a,c)) +say 'A/C =' Vlst2Form(Vdiv(a,c)) +say +say 'BONUS' +say 'Length(D) =' Vlen(d)+0 +say 'Angle(D) =' Vang(d)+0 +say 'Polar(D) =' Vlst2Form(Vrec2Pol(d)) +say 'Rect(E) =' Vlst2Form(Vpol2Rec(e)) +exit + +include Vector +include Functions +include Constants +include Abend diff --git a/Task/Verhoeff-algorithm/JavaScript/verhoeff-algorithm.js b/Task/Verhoeff-algorithm/JavaScript/verhoeff-algorithm.js new file mode 100644 index 0000000000..ca68a85226 --- /dev/null +++ b/Task/Verhoeff-algorithm/JavaScript/verhoeff-algorithm.js @@ -0,0 +1,80 @@ +const multiplicationTable = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], + [2, 3, 4, 0, 1, 7, 8, 9, 5, 6], + [3, 4, 0, 1, 2, 8, 9, 5, 6, 7], + [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], + [5, 9, 8, 7, 6, 0, 4, 3, 2, 1], + [6, 5, 9, 8, 7, 1, 0, 4, 3, 2], + [7, 6, 5, 9, 8, 2, 1, 0, 4, 3], + [8, 7, 6, 5, 9, 3, 2, 1, 0, 4], + [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], +]; + +const inverse = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]; + +const permutationTable = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 5, 7, 6, 2, 8, 3, 0, 9, 4], + [5, 8, 0, 3, 7, 9, 6, 1, 4, 2], + [8, 9, 1, 6, 0, 4, 3, 5, 2, 7], + [9, 4, 5, 3, 1, 2, 6, 8, 7, 0], + [4, 2, 8, 6, 5, 7, 3, 9, 0, 1], + [2, 7, 9, 3, 8, 0, 6, 4, 1, 5], + [7, 0, 4, 6, 9, 1, 3, 2, 5, 8], +]; + + +function verhoeffChecksum(number, doValidation, doDisplay) { + if (doDisplay) { + const calculationType = doValidation ? "Validation" : "Check digit"; + console.log(calculationType + " calculations for " + number + "\n"); + console.log(" i ni p[i, ni] c"); + console.log("-------------------"); + } + + if (!doValidation) { + number += "0"; + } + + let c = 0; + const le = number.length - 1; + + for (let i = le; i >= 0; i--) { + const ni = parseInt(number.charAt(i)); + const pi = permutationTable[(le - i) % 8][ni]; + c = multiplicationTable[c][pi]; + + if (doDisplay) { + console.log(`${String(le - i).padStart(2)}${String(ni).padStart(3)}${String(pi).padStart(8)}${String(c).padStart(6)}\n`); + } + } + + if (doDisplay && !doValidation) { + console.log("inverse[" + c + "] = " + inverse[c] + "\n"); + } + + return doValidation ? c === 0 : inverse[c]; +} + + +function main() { + const tests = [ + ["236", true], + ["12345", true], + ["123456789012", false], + ]; + + for (const test of tests) { + let object = verhoeffChecksum(test[0], false, test[1]); + console.log("The check digit for " + test[0] + " is " + object + "\n"); + + for (const number of [test[0] + String(object), test[0] + "9"]) { + object = verhoeffChecksum(number, true, test[1]); + const result = object ? "correct" : "incorrect"; + console.log("The validation for " + number + " is " + result + ".\n"); + } + } +} + +main(); diff --git a/Task/Verhoeff-algorithm/Rust/verhoeff-algorithm.rs b/Task/Verhoeff-algorithm/Rust/verhoeff-algorithm.rs new file mode 100644 index 0000000000..12055f1a30 --- /dev/null +++ b/Task/Verhoeff-algorithm/Rust/verhoeff-algorithm.rs @@ -0,0 +1,98 @@ +const MULTIPLICATION_TABLE: [[i32; 10]; 10] = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], + [2, 3, 4, 0, 1, 7, 8, 9, 5, 6], + [3, 4, 0, 1, 2, 8, 9, 5, 6, 7], + [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], + [5, 9, 8, 7, 6, 0, 4, 3, 2, 1], + [6, 5, 9, 8, 7, 1, 0, 4, 3, 2], + [7, 6, 5, 9, 8, 2, 1, 0, 4, 3], + [8, 7, 6, 5, 9, 3, 2, 1, 0, 4], + [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], +]; + +const INVERSE: [i32; 10] = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9]; + +const PERMUTATION_TABLE: [[i32; 10]; 8] = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 5, 7, 6, 2, 8, 3, 0, 9, 4], + [5, 8, 0, 3, 7, 9, 6, 1, 4, 2], + [8, 9, 1, 6, 0, 4, 3, 5, 2, 7], + [9, 4, 5, 3, 1, 2, 6, 8, 7, 0], + [4, 2, 8, 6, 5, 7, 3, 9, 0, 1], + [2, 7, 9, 3, 8, 0, 6, 4, 1, 5], + [7, 0, 4, 6, 9, 1, 3, 2, 5, 8], +]; + +fn verhoeff_checksum(number: &str, do_validation: bool, do_display: bool) -> i32 { + if do_display { + let calculation_type = if do_validation { + "Validation" + } else { + "Check digit" + }; + println!("{} calculations for {}\n", calculation_type, number); + println!(" i ni p[i, ni] c"); + println!("-------------------"); + } + + let mut working_number = String::from(number); + if !do_validation { + working_number.push('0'); + } + + let mut c = 0; + let le = working_number.len() - 1; + let chars: Vec = working_number.chars().collect(); + + for i in (0..=le).rev() { + let ni = chars[i].to_digit(10).unwrap() as i32; + let pos = (le - i) % 8; + let pi = PERMUTATION_TABLE[pos][ni as usize]; + c = MULTIPLICATION_TABLE[c as usize][pi as usize]; + + if do_display { + println!( + "{:2} {:2} {:2} {:2}\n", + le - i, + ni, + pi, + c + ); + } + } + + if do_display && !do_validation { + println!("inverse[{}] = {}\n", c, INVERSE[c as usize]); + } + + if do_validation { + if c == 0 { 1 } else { 0 } + } else { + INVERSE[c as usize] + } +} + +fn main() { + let tests = [ + ("123", true), + ("12345", true), + ("123456789012", false), + ]; + + for &(test_num, display) in tests.iter() { + let digit = verhoeff_checksum(test_num, false, display); + println!("The check digit for {} is {}\n", test_num, digit); + + let numbers = [ + format!("{}{}", test_num, digit), + format!("{}9", test_num), + ]; + + for number in numbers.iter() { + let digit = verhoeff_checksum(number, true, display); + let result = if digit == 1 { "correct" } else { "incorrect" }; + println!("The validation for {:?} is {:?}. ", number, result); + } + } +} diff --git a/Task/Verify-distribution-uniformity-Chi-squared-test/REXX/verify-distribution-uniformity-chi-squared-test.rexx b/Task/Verify-distribution-uniformity-Chi-squared-test/REXX/verify-distribution-uniformity-chi-squared-test.rexx index 25021e077f..5b7e3fbb9d 100644 --- a/Task/Verify-distribution-uniformity-Chi-squared-test/REXX/verify-distribution-uniformity-chi-squared-test.rexx +++ b/Task/Verify-distribution-uniformity-Chi-squared-test/REXX/verify-distribution-uniformity-chi-squared-test.rexx @@ -1,71 +1,67 @@ -/*REXX program performs a chi─squared test to verify a given distribution is uniform. */ -numeric digits length( pi() ) - length(.) /*enough decimal digs for calculations.*/ -@.=; @.1= 199809 200665 199607 200270 199649 - @.2= 522573 244456 139979 71531 21461 - do s=1 while @.s\==''; call uTest @.s /*invoke uTest with a data set of #'s.*/ - end /*s*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -!: procedure; parse arg x; p=1; do j=2 to x; p= p*j; end /*j*/; return p -chi2p: procedure; parse arg dof, distance; return gammaI( dof/2, distance/2 ) -f: parse arg t; if t=0 then return 0; return t ** (a-1) * exp(-t) -e: e =2.718281828459045235360287471352662497757247093699959574966967627724; return e -pi: pi=3.141592653589793238462643383279502884197169399375105820974944592308; return pi -/*──────────────────────────────────────────────────────────────────────────────────────*/ -!!: procedure; parse arg x; if x<2 then return 1; p= x - do k=2+x//2 to x-1 by 2; p= p*k; end /*k*/; return p -/*──────────────────────────────────────────────────────────────────────────────────────*/ -chi2ud: procedure: parse arg ds; sum=0; expect= 0 - do j=1 for words(ds); expect= expect + word(ds, j) - end /*j*/ - expect = expect / words(ds) - do k=1 for words(ds) - sum= sum + (word(ds, k) - expect) **2 - end /*k*/ - return sum / expect -/*──────────────────────────────────────────────────────────────────────────────────────*/ -exp: procedure; parse arg x; ix= x%1; if abs(x-ix)>.5 then ix= ix + sign(x); x= x-ix - z=1; _=1; w=z; do j=1; _= _*x/j; z= (z + _)/1; if z==w then leave; w=z - end /*j*/; if z\==0 then z= z * e()**ix; return z -/*──────────────────────────────────────────────────────────────────────────────────────*/ -gamma: procedure; parse arg x; if datatype(x, 'W') then return !(x-1) /*Int? Use fact*/ - n= trunc(x) /*at this point, X is pos and a multiple of 1/2.*/ - d= !!(n+n - 1) /*compute the double factorial of: 2*n - 1. */ - if n//2 then p= -1 /*if N is odd, then use a negative unity. */ - else p= 1 /*if N is even, then use a positive unity. */ - if x>0 then return p * d * sqrt(pi()) / (2**n) - return p * (2**n) * sqrt(pi()) / d -/*──────────────────────────────────────────────────────────────────────────────────────*/ -gammaI: procedure; parse arg a,x; y= a-1; do while f(y)*(x-y) > 2e-8 & y0 - if j//3 == 0 then sum= sum + 2 * f(a + h1*j) - else sum= sum + 3 * f(a + h1*j) - end /*j*/ - return h * sum / 8 -/*──────────────────────────────────────────────────────────────────────────────────────*/ -sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); numeric digits; h= d+6 - numeric form; m.=9; parse value format(x,2,1,,0) 'E0' with g "E" _ .;g=g *.5'e'_%2 - do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/ - do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g -/*──────────────────────────────────────────────────────────────────────────────────────*/ -uTest: procedure; parse arg dset; sum= 0; pad= left('', 11); sigLev= 1/20 /*5%*/ - say; say ' ' center(" Uniform distribution test ", 75, '═') - #= words(dset); sigPC= sigLev*100/1 - do j=1 for #; sum= sum + word(dset, j) - end /*j*/ - say pad " dataset: " dset - say pad " samples: " sum - say pad " categories: " # - say pad " degrees of freedom: " # - 1 - dist= chi2ud(dset) - P= chi2p(# - 1, dist) - sig = (abs(P) < dist * sigLev) - say pad "significant at " sigPC'% level? ' word('no yes', sig + 1) - say pad " is the dataset uniform? " word('no yes', (\(sig))+ 1) - return +-- 8 May 2025 +include Settings + +say 'VERIFY DISTRIBUTION UNIFORMITY / CHI-SQUARED TEST' +say version +say +call Check '200000 200000 200000 200000 200000' +call Check '199809 200665 199607 200270 199649' +call Check '522573 244456 139979 71531 21461' +call Check 'Random' +call Timer +exit + +Check: +procedure expose stat. glob. +arg xx +-- Dataset +stat. = 0 +if xx = 'RANDOM' then do + do i = 1 to 1000000 + a = Random(1,5); stat.a = stat.a+1 + end + stat.0 = 5 + say 'Dataset Random ' stat.1 stat.2 stat.3 stat.4 stat.5 +end +else do + do i = 1 to Words(xx) + stat.i = Word(xx,i) + end + stat.0 = Words(xx) + say 'Dataset Specified ' xx +end +say 'Categories (bins) ' stat.0 +say 'Degrees of freedom ' stat.0-1 +-- Samples +sa = 0 +do i = 1 to stat.0 + sa = sa+stat.i +end +say 'Samples ' sa +-- Significant at +sl = 1/20; sp = sl*100/1 +say 'Signicant tested at' sp'%' +-- Chi-Squared test value +s = 0; e = 0 +do i = 1 to stat.0 + e = e+stat.i +end i +e = e/stat.0 +do i = 1 to stat.0 + s = s+(stat.i-e)**2 +end i +csv = s/e +say 'Distance ' csv +-- Probability test value +pv = 1-RliGamma((stat.0-1)/2,csv/2) +say 'Probability ' pv +-- Result +say 'Is dataset uniform?' Word('Yes No',(Abs(pv) delta - bad = 1 - . + if abs (h - 1) > delta : bad = 1 dist[i] = 0 print h . diff --git a/Task/Verify-distribution-uniformity-Naive/REXX/verify-distribution-uniformity-naive.rexx b/Task/Verify-distribution-uniformity-Naive/REXX/verify-distribution-uniformity-naive.rexx index 12af39c058..b98f4d192d 100644 --- a/Task/Verify-distribution-uniformity-Naive/REXX/verify-distribution-uniformity-naive.rexx +++ b/Task/Verify-distribution-uniformity-Naive/REXX/verify-distribution-uniformity-naive.rexx @@ -1,34 +1,74 @@ -/*REXX program simulates a number of trials of a random digit and show it's skew %. */ -parse arg func times delta seed . /*obtain arguments (options) from C.L. */ -if func=='' | func=="," then func= 'RANDOM' /*function not specified? Use default.*/ -if times=='' | times=="," then times= 1000000 /*times " " " " */ -if delta=='' | delta=="," then delta= 1/2 /*delta% " " " " */ -if datatype(seed, 'W') then call random ,,seed /*use some RAND seed for repeatability.*/ -highDig= 9 /*use this var for the highest digit. */ -!.= 0 /*initialize all possible random trials*/ - do times /* [↓] perform a bunch of trials. */ - if func=='RANDOM' then ?= random(highDig) /*use RANDOM function.*/ - else interpret '?=' func "(0,"highDig')' /* " specified " */ - !.?= !.? + 1 /*bump the invocation counter.*/ - end /*times*/ /* [↑] store trials ───► pigeonholes. */ - /* [↓] compute the digit's skewness. */ -g= times / (1 + highDig) /*calculate number of each digit throw.*/ -w= max(9, length( commas(times) ) ) /*maximum length of number of trials.*/ -pad= left('', 9) /*this is used for output indentation. */ -say pad 'digit' center(" hits", w) ' skew ' "skew %" 'result' /*header. */ -say sep /*display a separator line. */ - /** [↑] show header and the separator.*/ - do k=0 to highDig /*process each of the possible digits. */ - skew= g - !.k /*calculate the skew for the digit. */ - skewPC= (1 - (g - abs(skew)) / g) * 100 /* " " " percentage for dig*/ - say pad center(k, 5) right( commas(!.k), w) right(skew, 6) , - right( format(skewPC, , 3), 6) center( word('ok skewed', 1+(skewPC>delta)), 6) - end /*k*/ -say sep /*display a separator line. */ -y= 5+1+w+1+6+1+6+1+6 /*width + seps*/ -say pad center(" (with " commas(times) ' trials)' , y) /*# trials. */ -say pad center(" (skewed when exceeds " delta'%)' , y) /*skewed note.*/ -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _ -sep: say pad '─────' center('', w, '─') '──────' "──────" '──────'; return +-- 8 May 2025 +include Settings +parse arg xx','yy','zz +if xx = '' then + xx = 'Random' +if yy = '' then + yy = 1e6 +if zz = '' then + zz = 0.3 + +say 'VERIFY DISTRIBUTION UNIFORMITY / NAIVE' +say version +say +call Parameters xx,yy,zz +call Get xx,yy +call Check yy,zz +call Timer +exit + +Parameters: +procedure +parse arg xx,yy,zz +say 'Generator :' xx +say 'Count :' yy +say 'Tolerance :' zz'%' +say +return + +Get: +procedure expose work. coun. glob. +parse arg xx,yy +say 'Get uniform distributed integers 1 thru 7...' +work. = 0; coun. = 0 +do n = 1 to yy + interpret 'r =' xx'(1,7)' + work.n = r; coun.r = coun.r+1 +end +work.0 = yy +say 'Done' +say +return + +Check: +procedure expose coun. +arg xx,yy +say 'And Verify them...' +a = xx%7 +say 'Per bin about' a 'expected' +say '-------------------------------' +say 'n count skew skew% test? ' +say '-------------------------------' +v = 1 +do n = 1 to 7 + b = coun.n-a; c = Round(100*b/a,3) + if Abs(c) > yy then do + d = 'Failed'; v = 0 + end + else + d = 'Passed' + say n Right(coun.n,7) Right(b,5) Right(c'%',8) d +end +say '-------------------------------' +if v then + e = 'did' +else + e = 'did not' +say 'The set' e 'pass the test' +say +return + +include Functions +include Constants +include Helper +include Abend diff --git a/Task/Vigen-re-cipher-Cryptanalysis/JavaScript/vigen-re-cipher-cryptanalysis.js b/Task/Vigen-re-cipher-Cryptanalysis/JavaScript/vigen-re-cipher-cryptanalysis.js new file mode 100644 index 0000000000..3762fba50f --- /dev/null +++ b/Task/Vigen-re-cipher-Cryptanalysis/JavaScript/vigen-re-cipher-cryptanalysis.js @@ -0,0 +1,190 @@ +// Encoded text +const encoded = + "MOMUD EKAPV TQEFM OEVHP AJMII CDCTI FGYAG JSPXY ALUYM NSMYH" + + "VUXJE LEPXJ FXGCM JHKDZ RYICU HYPUS PGIGM OIYHF WHTCQ KMLRD" + + "ITLXZ LJFVQ GHOLW CUHLO MDSOE KTALU VYLNZ RFGBX PHVGA LWQIS" + + "FGRPH JOOFW GUBYI LAPLA LCAFA AMKLG CETDW VOELJ IKGJB XPHVG" + + "ALWQC SNWBU BYHCU HKOCE XJEYK BQKVY KIIEH GRLGH XEOLW AWFOJ" + + "ILOVV RHPKD WIHKN ATUHN VRYAQ DIVHX FHRZV QWMWV LGSHN NLVZS" + + "JLAKI FHXUF XJLXM TBLQV RXXHR FZXGV LRAJI EXPRV OSMNP KEPDT" + + "LPRWM JAZPK LQUZA ALGZX GVLKL GJTUI ITDSU REZXJ ERXZS HMPST" + + "MTEOE PAPJH SMFNB YVQUZ AALGA YDNMP AQOWT UHDBV TSMUE UIMVH" + + "QGVRW AEFSP EMPVE PKXZY WLKJA GWALT VYYOB YIXOK IHPDS EVLEV" + + "RVSGB JOGYW FHKBL GLXYA MVKIS KIEHY IMAPX UOISK PVAGN MZHPW" + + "TTZPV XFCCD TUHJH WLAPF YULTB UXJLN SIJVV YOVDJ SOLXG TGRVO" + + "SFRII CTMKO JFCQF KTINQ BWVHG TENLH HOGCS PSFPV GJOKM SIFPR" + + "ZPAAS ATPTZ FTPPD PORRF TAXZP KALQA WMIUD BWNCT LEFKO ZQDLX" + + "BUXJL ASIMR PNMBF ZCYLV WAPVF QRHZV ZGZEF KBYIO OFXYE VOWGB" + + "BXVCB XBAWG LQKCM ICRRX MACUO IKHQU AJEGL OIJHH XPVZW JEWBA" + + "FWAML ZZRXJ EKAHV FASMU LVVUT TGK"; + +// Standard English letter frequencies (normalized probabilities) +const freq = [ + 0.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, + 0.06094, 0.06966, 0.00153, 0.00772, 0.04025, 0.02406, 0.06749, + 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056, 0.02758, + 0.00978, 0.02360, 0.00150, 0.01974, 0.00074, +]; + +const A_CODE = 'A'.charCodeAt(0); // ASCII code for 'A' +const Z_CODE = 'Z'.charCodeAt(0); // ASCII code for 'Z' + +// Helper function to calculate the sum of elements in an array +function sum(arr) { + return arr.reduce((acc, val) => acc + val, 0); +} + +// Finds the rotation (shift, 0-25) for a given frequency distribution +// 'arr' that best matches the standard English frequencies 'freq'. +// Uses a chi-squared-like measure for goodness of fit. +function bestMatch(arr) { + const total = sum(arr); + let bestFit = Infinity; // Use Infinity for a large initial value + let bestRotate = 0; + + for (let rotate = 0; rotate < 26; rotate++) { + let fit = 0.0; + for (let i = 0; i < 26; i++) { + const expectedFreq = freq[i]; + // Calculate normalized frequency for the current rotation + const actualFreq = total > 0 ? arr[(i + rotate) % 26] / total : 0; + const d = actualFreq - expectedFreq; + // Chi-squared like goodness of fit: (observed - expected)^2 / expected + // The Go code uses (actualFreq - expectedFreq)^2 / expectedFreq + // This is a standard form of chi-squared contribution per bin. + fit += (d * d) / expectedFreq; + } + + if (fit < bestFit) { + bestFit = fit; + bestRotate = rotate; + } + } + return bestRotate; // Return the best shift (0-25) +} + +// Analyzes the frequency distribution of characters at intervals +// equal to the potential key length. It determines the best shift +// for each position in the key, populates `keyArray` with these +// shifts (0-25), and calculates an overall goodness-of-fit score +// for this key length against standard English frequencies. +function freqEveryNth(msg, keyArray) { + const l = msg.length; + const interval = keyArray.length; // This is the potential key length + const out = Array(26).fill(0); // Temporary frequency count for one key position (e.g., all 1st chars, all 2nd chars, etc.) + const accu = Array(26).fill(0); // Accumulated frequency counts across all key positions after applying their best shifts + + for (let j = 0; j < interval; j++) { // Loop through each position in the potential key (0 to keyLength-1) + // Reset out for the current key position's characters + out.fill(0); + + // Count frequencies for characters at indices j, j+interval, j+2*interval, ... + // These characters were all encrypted using the j-th character of the key. + for (let i = j; i < l; i += interval) { + out[msg[i]]++; // msg[i] is the 0-25 index of the character + } + + // Find the best rotation (shift) for this specific frequency distribution ('out'). + // This shift corresponds to the Vigenère key character used at this position 'j'. + const rot = bestMatch(out); + keyArray[j] = rot; // Store the best shift (0-25) found for this key position + + // Apply the determined shift ('rot') to the current frequency counts ('out') + // and add them to the accumulator ('accu'). This simulates shifting each set + // of characters back as if they were decrypted by the correct key character. + for (let i = 0; i < 26; i++) { + accu[i] += out[(i + rot) % 26]; + } + } + + // Calculate the overall fit score based on the total accumulated frequencies ('accu'). + // This measures how well the combined frequencies, after applying the determined + // shifts for each key position, match the standard English frequencies. + const totalAccu = sum(accu); + let ret = 0.0; + for (let i = 0; i < 26; i++) { + const expectedFreq = freq[i]; + const actualFreq = totalAccu > 0 ? accu[i] / totalAccu : 0; + const d = actualFreq - expectedFreq; + // Chi-squared like fit score for the overall distribution + ret += (d * d) / expectedFreq; + } + + return ret; // Return the overall fit score for this key length hypothesis +} + +// Decrypts the text using the Vigenère cipher with the given key. +// Skips non-A-Z characters in the ciphertext and does not advance the +// key index for them, replicating the Go code's behavior. +function decrypt(text, key) { + let result = ''; + let keyIndex = 0; + + for (let i = 0; i < text.length; i++) { + const cCode = text.charCodeAt(i); + + if (cCode >= A_CODE && cCode <= Z_CODE) { + const textCharIndex = cCode - A_CODE; // 0-25 index of ciphertext char + // Use the key character cyclically + const keyCharIndex = key.charCodeAt(keyIndex % key.length) - A_CODE; // 0-25 index of key char + + // Vigenere decryption formula: (ciphertext_index - key_index + 26) % 26 + // Adding 26 ensures the result is non-negative before modulo. + const decryptedCharIndex = (textCharIndex - keyCharIndex + 26) % 26; + + result += String.fromCharCode(decryptedCharIndex + A_CODE); + keyIndex++; // Advance key index ONLY for processed A-Z characters + } else { + // Skip non-A-Z characters entirely, just like the Go code's 'continue'. + // They are neither decrypted nor cause the key index to advance. + } + } + return result; +} + +// Main execution logic +function main() { + // Remove spaces from the encoded text + const cleanedEncoded = encoded.replace(/ /g, ''); + + // Convert cleaned text to an array of 0-25 integer indices ('A' -> 0, 'B' -> 1, ...) + const txt = []; + for (let i = 0; i < cleanedEncoded.length; i++) { + txt.push(cleanedEncoded.charCodeAt(i) - A_CODE); + } + + let bestFit = Infinity; // Initialize with a very large value to find the minimum fit score + let bestKey = ""; + + console.log(" Fit Length Key"); + + // Iterate through potential key lengths from 1 to 26 + for (let j = 1; j <= 26; j++) { + const keyArray = Array(j); // Array to hold the calculated shifts (0-25) for this length + const fit = freqEveryNth(txt, keyArray); + + // Convert the array of shifts (0-25) into a key string (A-Z) + const currentKey = keyArray.map(shift => String.fromCharCode(shift + A_CODE)).join(''); + + // Format output line for the current key length + // toFixed(6) for 6 decimal places, padStart(2, ' ') for 2 characters, space-padded + let outputLine = `${fit.toFixed(6)} ${j.toString().padStart(2, ' ')} ${currentKey}`; + + // Check if this key length gives a better fit than the best found so far + if (fit < bestFit) { + bestFit = fit; + bestKey = currentKey; + outputLine += " <--- best so far"; // Indicate the best fit found up to this point + } + console.log(outputLine); + } + + console.log("\nBest key :", bestKey); + + // Decrypt the original cleaned text using the best key found + const decryptedText = decrypt(cleanedEncoded, bestKey); + console.log("\nDecrypted text:\n" + decryptedText); +} + +// Execute the main function +main(); diff --git a/Task/Vogels-approximation-method/EasyLang/vogels-approximation-method.easy b/Task/Vogels-approximation-method/EasyLang/vogels-approximation-method.easy index 0052c217fc..85f9ef114d 100644 --- a/Task/Vogels-approximation-method/EasyLang/vogels-approximation-method.easy +++ b/Task/Vogels-approximation-method/EasyLang/vogels-approximation-method.easy @@ -74,7 +74,7 @@ func[] nextcell . . . . -proc main . . +proc main . for v in supply[] supplyleft += v results[][] &= [ ] diff --git a/Task/Vogels-approximation-method/Fortran/vogels-approximation-method.f b/Task/Vogels-approximation-method/Fortran/vogels-approximation-method.f new file mode 100644 index 0000000000..dc2199bd51 --- /dev/null +++ b/Task/Vogels-approximation-method/Fortran/vogels-approximation-method.f @@ -0,0 +1,96 @@ +program vogels_approximation_method + implicit none + integer, parameter :: m = 4, n = 5 + integer :: costs(m,n), supply(m), demand(n) + integer :: allocation(m,n), i, total_cost + + ! Initialize data + costs = reshape([16,14,19,50, 16,14,19,12, 13,13,20,50, 22,19,23,15, 17,15,50,11], [m,n]) + supply = [50, 60, 50, 50] + demand = [30, 20, 70, 30, 60] + + ! Perform VAM + call vam(costs, supply, demand, allocation) + + ! Calculate and print total cost + total_cost = sum(costs * allocation) + print *, "Total cost: ", total_cost + + ! Print allocation + print *, "Allocation:" + do i = 1, m + print *, allocation(i,:) + end do + +contains + + subroutine vam(costs, supply, demand, allocation) + integer, intent(in) :: costs(m,n) + integer, intent(inout) :: supply(m), demand(n) + integer, intent(out) :: allocation(m,n) + integer :: row_penalties(m), col_penalties(n) + integer :: i, j, max_penalty, max_index, min_cost, alloc + logical :: row_done(m), col_done(n) + + allocation = 0 + row_done = .false. + col_done = .false. + + do while (any(.not. row_done) .and. any(.not. col_done)) + ! Calculate penalties + call calculate_penalties(costs, row_done, col_done, row_penalties, col_penalties) + + ! Find maximum penalty + max_penalty = max(maxval(row_penalties), maxval(col_penalties)) + if (maxval(row_penalties) >= maxval(col_penalties)) then + max_index = maxloc(row_penalties, dim=1) + min_cost = minval(costs(max_index, :), mask=.not. col_done) + j = minloc(costs(max_index, :), dim=1, mask=.not. col_done) + i = max_index + else + max_index = maxloc(col_penalties, dim=1) + min_cost = minval(costs(:, max_index), mask=.not. row_done) + i = minloc(costs(:, max_index), dim=1, mask=.not. row_done) + j = max_index + end if + + ! Allocate + alloc = min(supply(i), demand(j)) + allocation(i,j) = alloc + supply(i) = supply(i) - alloc + demand(j) = demand(j) - alloc + + ! Update done flags + if (supply(i) == 0) row_done(i) = .true. + if (demand(j) == 0) col_done(j) = .true. + end do + end subroutine vam + + subroutine calculate_penalties(costs, row_done, col_done, row_penalties, col_penalties) + integer, intent(in) :: costs(m,n) + logical, intent(in) :: row_done(m), col_done(n) + integer, intent(out) :: row_penalties(m), col_penalties(n) + integer :: i, j, min1, min2 + + do i = 1, m + if (.not. row_done(i)) then + min1 = minval(costs(i,:), mask=.not. col_done) + min2 = minval(costs(i,:), mask=(.not. col_done .and. costs(i,:) > min1)) + row_penalties(i) = min2 - min1 + else + row_penalties(i) = -1 + end if + end do + + do j = 1, n + if (.not. col_done(j)) then + min1 = minval(costs(:,j), mask=.not. row_done) + min2 = minval(costs(:,j), mask=(.not. row_done .and. costs(:,j) > min1)) + col_penalties(j) = min2 - min1 + else + col_penalties(j) = -1 + end if + end do + end subroutine calculate_penalties + +end program vogels_approximation_method diff --git a/Task/Vogels-approximation-method/JavaScript/vogels-approximation-method.js b/Task/Vogels-approximation-method/JavaScript/vogels-approximation-method.js new file mode 100644 index 0000000000..03c71c06e7 --- /dev/null +++ b/Task/Vogels-approximation-method/JavaScript/vogels-approximation-method.js @@ -0,0 +1,290 @@ +/** + * Helper function to print a 2D array (matrix) nicely. + * @param {Array>} matrix The matrix to print. + * @param {string} title Optional title to print before the matrix. + */ +function printMatrix(matrix, title = "") { + if (title) { + console.log(title); + } + // console.table is often available and provides good formatting + if (typeof console.table === 'function') { + console.table(matrix); + } else { + // Fallback basic printing + matrix.forEach(row => { + // JSON.stringify formats arrays with commas and brackets + console.log(JSON.stringify(row)); + }); + } +} + +// --- Input Data --- +// Using let for demand and supply as they will be modified during the algorithm +// Make copies if you want to preserve the original arrays elsewhere +let demand = [30, 20, 70, 30, 60]; +let supply = [50, 60, 50, 50]; +const costs = [ + [16, 16, 13, 22, 17], + [14, 14, 13, 19, 15], + [19, 19, 20, 23, 50], + [50, 12, 50, 15, 11] +]; + +// --- Dimensions and State Variables --- +const nRows = supply.length; +const nCols = demand.length; + +// Track which rows/columns are fully satisfied +const rowDone = Array(nRows).fill(false); +const colDone = Array(nCols).fill(false); + +// The resulting allocation matrix, initialized with zeros +const result = Array(nRows).fill(0).map(() => Array(nCols).fill(0)); + +/** + * Calculates the difference between the two smallest costs in a given row or column, + * considering only active (not done) cells. + * @param {number} j The index of the row or column to analyze. + * @param {number} len The length of the other dimension (nCols if analyzing a row, nRows if analyzing a column). + * @param {boolean} isRow True if analyzing row j, false if analyzing column j. + * @returns {Array} An array: [penalty, minCost, minCostPosition] + * penalty = min2 - min1 (Infinity if < 2 costs found) + * minCost = the smallest cost found (Infinity if none found) + * minCostPosition = index of the smallest cost (-1 if none found) + */ +function diff(j, len, isRow) { + let min1 = Infinity; + let min2 = Infinity; + let minP = -1; // Position (index) of min1 + + for (let i = 0; i < len; i++) { + // Skip if the corresponding column (if analyzing row) or row (if analyzing column) is already done + if (isRow ? colDone[i] : rowDone[i]) { + continue; + } + + // Get the cost from the correct cell + const c = isRow ? costs[j][i] : costs[i][j]; + + if (c < min1) { + min2 = min1; // Old min1 becomes min2 + min1 = c; // New cost is the new min1 + minP = i; // Record position of new min1 + } else if (c < min2) { + min2 = c; // Update min2 + } + } + + // Calculate penalty: difference between second minimum and first minimum + // If min2 is still Infinity, it means less than two costs were found. Penalty is Infinity. + const penalty = (min2 === Infinity) ? Infinity : min2 - min1; + + return [penalty, min1, minP]; +} + +/** + * Finds the row or column with the maximum penalty among active rows/columns. + * @param {number} len1 Number of rows or columns to iterate through (nRows or nCols). + * @param {number} len2 Length of the other dimension (nCols or nRows). + * @param {boolean} isRow True if finding max penalty among rows, false for columns. + * @returns {Array | null} An array: [rowIndex, colIndex, minCostInSelected, maxPenaltyValue] + * Returns null if no active rows/columns found. + */ +function maxPenalty(len1, len2, isRow) { + let maxDiff = -Infinity; // Use -Infinity to ensure any real penalty is larger + let posOfMaxDiff = -1; // Index of row/column with max penalty + let posOfMinCost = -1; // Index of min cost within the selected row/column + let minCostVal = -1; // Value of min cost within the selected row/column + let foundActive = false; + + for (let i = 0; i < len1; i++) { + // Skip if this row (if isRow) or column (if !isRow) is already done + if (isRow ? rowDone[i] : colDone[i]) { + continue; + } + foundActive = true; // Found at least one active row/column to check + + const res = diff(i, len2, isRow); // [penalty, minCost, minPos] + const currentPenalty = res[0]; + + // Check if this penalty is the highest found so far + if (currentPenalty > maxDiff) { + maxDiff = currentPenalty; + posOfMaxDiff = i; // Record which row/column had this max penalty + minCostVal = res[1]; // Record the min cost in this row/column + posOfMinCost = res[2]; // Record the position of min cost + } + } + if (!foundActive) { + return null; // No active rows/columns left to calculate penalty for + } + + // Return results ensuring format [rowIndex, colIndex, minCostVal, maxDiff] + return isRow + ? [posOfMaxDiff, posOfMinCost, minCostVal, maxDiff] // For row: [rowIdx, colIdxOfMin, minCost, penalty] + : [posOfMinCost, posOfMaxDiff, minCostVal, maxDiff]; // For col: [rowIdxOfMin, colIdx, minCost, penalty] +} + +/** + * Determines the next cell to allocate to based on Vogel's Approximation Method (VAM). + * It compares the highest row penalty and the highest column penalty. + * @returns {Array | null} An array: [rowIndex, colIndex, minCostInSelected, maxPenaltyValue] + * Returns null if no suitable cell can be found. + */ +function nextCell() { + const resRow = maxPenalty(nRows, nCols, true); // Max penalty among rows + const resCol = maxPenalty(nCols, nRows, false); // Max penalty among columns + + // Handle cases where one or both couldn't find penalties (e.g., all done) + if (!resRow && !resCol) return null; // No more valid moves + if (!resRow) return resCol; // Only column penalty found + if (!resCol) return resRow; // Only row penalty found + + const maxPenaltyRow = resRow[3]; + const maxPenaltyCol = resCol[3]; + const minCostInRow = resRow[2]; + const minCostInCol = resCol[2]; + + // Decide based on highest penalty. Break ties by choosing the one with the lower minimum cost. + if (maxPenaltyRow === maxPenaltyCol) { + return minCostInRow <= minCostInCol ? resRow : resCol; + } else { + // In the C++ code: `res1[3] > res2[3] ? res2 : res1;` + // This seems backward? Higher penalty should be chosen. + // Let's assume higher penalty is better: + // return maxPenaltyRow >= maxPenaltyCol ? resRow : resCol; + // Let's stick to the C++ code's logic for direct translation: + return maxPenaltyRow > maxPenaltyCol ? resCol : resRow; + // Re-evaluating C++ code: + // `auto res1 = maxPenalty(nRows, nCols, true);` -> `res1` = row result + // `auto res2 = maxPenalty(nCols, nRows, false);` -> `res2` = col result + // `return res1[3] > res2[3] ? res2 : res1;` -> If row penalty > col penalty, return col result. This is incorrect VAM. + // VAM selects the *highest* penalty. + // Let's correct the logic based on VAM principle: Choose highest penalty, break ties with lowest cost. + // + // if (maxPenaltyRow > maxPenaltyCol) { + // return resRow; + // } else if (maxPenaltyCol > maxPenaltyRow) { + // return resCol; + // } else { + // // Penalties are equal, break tie with minimum cost + // return minCostInRow <= minCostInCol ? resRow : resCol; + // } + // + // The logic `maxPenaltyRow > maxPenaltyCol ? resCol : resRow` actually means: + // If RowPenalty is bigger, return ColumnResult. If ColPenalty is bigger or equal, return RowResult. + // This seems highly suspect and likely a bug in the original C++ or a misunderstanding of its output. + // Let's implement the standard VAM logic (highest penalty wins, tiebreak with cost): + if (maxPenaltyRow > maxPenaltyCol) { + return resRow; + } else if (maxPenaltyCol > maxPenaltyRow) { + return resCol; + } else { + // Penalties are equal, break tie with minimum cost cell within the tied lines + return minCostInRow <= minCostInCol ? resRow : resCol; + } + } +} + + +// --- Main VAM Algorithm Execution --- + +// Calculate total initial supply +let supplyLeft = supply.reduce((sum, current) => sum + current, 0); +let totalCost = 0; +let iterations = 0; // Safety counter +const maxIterations = nRows * nCols * 2; // A reasonable upper bound + +console.log("Starting Vogel's Approximation Method..."); +console.log("Initial Supply:", supply); +console.log("Initial Demand:", demand); +console.log("Costs:"); +printMatrix(costs); +console.log("---"); + + +while (supplyLeft > 0 && iterations < maxIterations) { + iterations++; + const cell = nextCell(); // Get [r, c, minCost, penalty] for the next allocation + + if (!cell) { + console.log("No suitable cell found by nextCell(). Stopping."); + break; // No more valid moves can be determined + } + + const r = cell[0]; // Row index to allocate to + const c = cell[1]; // Column index to allocate to + + // Safety check for valid indices and if the cell's row/col are already done + // This shouldn't happen if maxPenalty correctly skips done rows/cols, but good for robustness. + if (r < 0 || r >= nRows || c < 0 || c >= nCols || rowDone[r] || colDone[c]) { + console.warn(`Iteration ${iterations}: nextCell returned invalid/done cell [${r}, ${c}]. Attempting to recover or break.`); + // Attempt recovery: mark potentially problematic row/col as done if indices are valid + if (r >= 0 && r < nRows) rowDone[r] = true; + if (c >= 0 && c < nCols) colDone[c] = true; + // Or simply break: + // break; + continue; // Try finding another cell in the next iteration + } + + + // Determine the quantity to allocate: minimum of remaining supply in row r and demand in col c + const quantity = Math.min(demand[c], supply[r]); + + if (quantity <= 0) { + // This might happen if a row/col is selected but has 0 supply/demand left. + // Mark them as done and continue. + console.warn(`Iteration ${iterations}: Zero quantity allocation attempted for cell [${r}, ${c}]. Marking row/col as done.`); + if (demand[c] <= 0 && !colDone[c]) colDone[c] = true; + if (supply[r] <= 0 && !rowDone[r]) rowDone[r] = true; + continue; + } + + + // Update demand, supply, and mark as done if depleted + demand[c] -= quantity; + if (demand[c] === 0) { + colDone[c] = true; + } + + supply[r] -= quantity; + if (supply[r] === 0) { + rowDone[r] = true; + } + + // Record the allocation in the result matrix + result[r][c] = quantity; + + // Update total supply left and total cost + supplyLeft -= quantity; + totalCost += quantity * costs[r][c]; + + // console.log(`Iteration ${iterations}: Allocated ${quantity} to [${r}, ${c}]. Cost += ${quantity * costs[r][c]}. SupplyLeft: ${supplyLeft}`); + // console.log(" Current Supply:", supply); + // console.log(" Current Demand:", demand); + // console.log(" rowDone:", rowDone); + // console.log(" colDone:", colDone); + // console.log("---"); + +} + +if (iterations >= maxIterations) { + console.warn("Warning: Maximum iterations reached. The algorithm might be stuck in a loop."); +} + +// --- Output Results --- +console.log("\n--- VAM Finished ---"); +printMatrix(result, "Allocation Matrix (Result):"); +console.log(`\nTotal Cost: ${totalCost}`); + +// Optional: Check final state +const remainingDemand = demand.reduce((s, d) => s + d, 0); +const remainingSupply = supply.reduce((s, sup) => s + sup, 0); +console.log(`Final Remaining Demand: ${remainingDemand}`); +console.log(`Final Remaining Supply: ${remainingSupply}`); +console.log(`Calculated Supply Left: ${supplyLeft}`); + +// Verify if total allocated matches total demand/supply (assuming balanced problem) +const totalAllocated = result.flat().reduce((s, q) => s + q, 0); +console.log(`Total Quantity Allocated: ${totalAllocated}`); diff --git a/Task/Voronoi-diagram/EasyLang/voronoi-diagram.easy b/Task/Voronoi-diagram/EasyLang/voronoi-diagram.easy index 041504024d..55184002d9 100644 --- a/Task/Voronoi-diagram/EasyLang/voronoi-diagram.easy +++ b/Task/Voronoi-diagram/EasyLang/voronoi-diagram.easy @@ -17,13 +17,11 @@ for y = 0 to 1000 imin = i . . - color nc[imin] - move x / 10 - 0.05 y / 10 - 0.05 - rect 0.11 0.11 + gcolor nc[imin] + grect x / 10 - 0.05 y / 10 - 0.05 0.11 0.11 . . -color 000 +gcolor 000 for i to nsites - move nx[i] / 10 ny[i] / 10 - circle 0.5 + gcircle nx[i] / 10 ny[i] / 10 0.5 . diff --git a/Task/Wagstaff-primes/EasyLang/wagstaff-primes.easy b/Task/Wagstaff-primes/EasyLang/wagstaff-primes.easy index c334acb4e8..d0772ee5e2 100644 --- a/Task/Wagstaff-primes/EasyLang/wagstaff-primes.easy +++ b/Task/Wagstaff-primes/EasyLang/wagstaff-primes.easy @@ -1,12 +1,8 @@ func prime n . - if n mod 2 = 0 and n > 2 - return 0 - . + if n mod 2 = 0 and n > 2 : return 0 i = 3 while i <= sqrt n - if n mod i = 0 - return 0 - . + if n mod i = 0 : return 0 i += 2 . return 1 diff --git a/Task/Wagstaff-primes/Mathematica/wagstaff-primes.math b/Task/Wagstaff-primes/Mathematica/wagstaff-primes.math new file mode 100644 index 0000000000..bb2d0c20ec --- /dev/null +++ b/Task/Wagstaff-primes/Mathematica/wagstaff-primes.math @@ -0,0 +1,40 @@ +wagstaffPair[p_Integer] := Module[{m}, + If[Not[OddQ[p]], Return[{False, Null}]]; + If[Not[PrimeQ[p]], Return[{False, Null}]]; + + m = Quotient[2^p + 1, 3]; + + If[Not[PrimeQ[m]], Return[{False, Null}]]; + + {True, m} + ] + +findNWagstaffPairs[n_Integer] := Module[{pairs = {}, count = 0, i = 2}, + While[count < n, + With[{result = wagstaffPair[i]}, + If[First[result], + AppendTo[pairs, {i, Last[result]}]; + count++ + ] + ]; + i++ + ]; + pairs + ] + +printlnWagstaff[pair_, maxDigitDisplay_: 20] := Module[{p, m, mStr, uMiddle, lMiddle}, + {p, m} = pair; + mStr = ToString[m]; + + If[StringLength[mStr] > maxDigitDisplay, + uMiddle = Ceiling[maxDigitDisplay/2]; + lMiddle = Floor[maxDigitDisplay/2]; + mStr = StringJoin[{StringTake[mStr, uMiddle], "...", + StringTake[mStr, {-lMiddle}], " (", ToString[StringLength[mStr]], + " digits)"}] + ]; + + Print["p = ", p, ", m = ", mStr] + ] + +Map[printlnWagstaff, findNWagstaffPairs[24]]; diff --git a/Task/Wasteful-equidigital-and-frugal-numbers/ALGOL-68/wasteful-equidigital-and-frugal-numbers.alg b/Task/Wasteful-equidigital-and-frugal-numbers/ALGOL-68/wasteful-equidigital-and-frugal-numbers.alg new file mode 100644 index 0000000000..eab5c72ead --- /dev/null +++ b/Task/Wasteful-equidigital-and-frugal-numbers/ALGOL-68/wasteful-equidigital-and-frugal-numbers.alg @@ -0,0 +1,64 @@ +BEGIN # wasteful, equidigital and frugal numbers - translation of the EasyLang sample # + + INT wasteful = 1, equidigital = 2, frugal = 3; + []STRING title = ( "wasteful", "equidigital", "frugal" ); + + [ 1 : 2 000 000 ]INT d; FOR i TO UPB d DO d[ i ] := 0 OD; + PROC classify = VOID: BEGIN + INT ndig := 1; INT n10 := 10; + d[ 1 ] := 1; + FOR i FROM 2 TO UPB d DO + IF i = n10 THEN ndig +:= 1; n10 *:= 10 FI; + IF d[ i ] = 0 + THEN d[ i ] := ndig; + FOR j FROM i + i BY i TO UPB d DO + INT h := j; + INT e := 0; + INT edig := 1; INT e10 := 10; + WHILE h MOD i = 0 DO + h := h OVER i; + e +:= 1; + IF e = e10 THEN edig +:= 1; e10 *:= 10 FI + OD; + h := 0; + IF e > 1 THEN h := edig FI; + d[ j ] +:= ndig + h + OD + FI + OD; + ndig := 1; n10 := 10; + FOR i TO UPB d DO + IF i = n10 THEN ndig +:= 1; n10 *:= 10 FI; + d[ i ] := IF d[ i ] > ndig + THEN wasteful + ELIF d[ i ] = ndig + THEN equidigital + ELSE frugal + FI + OD + END # classify # ; + PROC show = ( INT t )VOID: BEGIN + INT i := 1, count := 0; + print( ( "First 50 ", title[ t ], " numbers:", newline ) ); + WHILE IF d[ i ] = t + THEN IF ( count +:= 1 ) <= 50 + THEN print( ( whole( i, -5 ) ) ); + IF count MOD 10 = 0 THEN print( ( newline ) ) FI + FI + FI; + count < 10000 + DO i +:= 1 OD; + print( ( newline, "10 000th ", title[ t ], " number: ", whole( i, 0 ), newline, newline ) ) + END # show # ; + + classify; + show( wasteful ); + show( equidigital ); + show( frugal ); + print( ( "Under 1 000 000, the counts are:", newline ) ); + [ wasteful : frugal ]INT sum := ( 0, 0, 0 ); + FOR i TO 999 999 DO sum[ d[ i ] ] +:= 1 OD; + FOR h FROM LWB sum TO UPB sum DO + print( ( " ", title[ h ], ": ", whole( sum[ h ], 0 ), newline ) ) + OD +END diff --git a/Task/Wasteful-equidigital-and-frugal-numbers/EasyLang/wasteful-equidigital-and-frugal-numbers.easy b/Task/Wasteful-equidigital-and-frugal-numbers/EasyLang/wasteful-equidigital-and-frugal-numbers.easy new file mode 100644 index 0000000000..6068cab8d4 --- /dev/null +++ b/Task/Wasteful-equidigital-and-frugal-numbers/EasyLang/wasteful-equidigital-and-frugal-numbers.easy @@ -0,0 +1,56 @@ +func ndig n . + return log10 n div 1 + 1 +. +len d[] 2000000 +proc sieve . + d[1] = 1 + for i = 2 to len d[] + if d[i] = 0 + d[i] = ndig i + j = i + i + while j <= len d[] + h = j + e = 0 + while h mod i = 0 + h = h div i + e += 1 + . + h = 0 + if e > 1 : h = ndig e + d[j] += ndig i + h + j += i + . + . + . + for i to len d[] + if d[i] > ndig i + d[i] = 1 + elif d[i] = ndig i + d[i] = 2 + else + d[i] = 3 + . + . +. +sieve +proc show t . + i = 1 + repeat + if d[i] = t + cnt += 1 + if cnt <= 50 : write i & " " + . + until cnt = 10000 + i += 1 + . + print "" + print "" + print i + print "" +. +show 1 +show 2 +show 3 +len sum[] 3 +for i to 999999 : sum[d[i]] += 1 +for h in sum[] : print h diff --git a/Task/Wasteful-equidigital-and-frugal-numbers/Python/wasteful-equidigital-and-frugal-numbers.py b/Task/Wasteful-equidigital-and-frugal-numbers/Python/wasteful-equidigital-and-frugal-numbers.py new file mode 100644 index 0000000000..45a639a8b7 --- /dev/null +++ b/Task/Wasteful-equidigital-and-frugal-numbers/Python/wasteful-equidigital-and-frugal-numbers.py @@ -0,0 +1,272 @@ +import math +from collections import defaultdict + +# Global caches +digit_count_cache = {} +factorization_cache = {} +d_n_cache = {} +classification_cache = {} + +def count_digits(n, base=10): + """Count the number of digits in n in the given base.""" + cache_key = (n, base) + if cache_key in digit_count_cache: + return digit_count_cache[cache_key] + + if n == 0: + result = 1 + else: + result = math.floor(math.log(n, base)) + 1 + + digit_count_cache[cache_key] = result + return result + +def prime_factors(n): + """Return the prime factorization of n as a dictionary {prime: exponent}.""" + if n in factorization_cache: + return factorization_cache[n].copy() + + if n <= 1: + return {} + + factors = defaultdict(int) + + # Check for factor 2 + while n % 2 == 0: + factors[2] += 1 + n //= 2 + + # Check for odd factors + i = 3 + while i * i <= n: + while n % i == 0: + factors[i] += 1 + n //= i + i += 2 + + # If n is a prime number greater than 2 + if n > 2: + factors[n] += 1 + + factorization_cache[n] = factors.copy() + return factors + +def digit_count_in_factorization(n, base=10): + """Calculate D(n), the total number of digits in all prime factors and exponents > 1.""" + cache_key = (n, base) + if cache_key in d_n_cache: + return d_n_cache[cache_key] + + if n == 1: + return 0 # By convention + + factors = prime_factors(n) + total_digits = 0 + + for prime, exponent in factors.items(): + # Count digits in the prime factor + total_digits += count_digits(prime, base) + + # Count digits in the exponent if it's greater than 1 + if exponent > 1: + total_digits += count_digits(exponent, base) + + d_n_cache[cache_key] = total_digits + return total_digits + +def classify_number(n, base=10): + """Classify a number as wasteful, equidigital, or frugal in the given base.""" + cache_key = (n, base) + if cache_key in classification_cache: + return classification_cache[cache_key] + + if n == 1: + return 'equidigital' # By convention + + l_n = count_digits(n, base) + d_n = digit_count_in_factorization(n, base) + + if l_n < d_n: + result = 'wasteful' + elif l_n == d_n: + result = 'equidigital' + else: # l_n > d_n + result = 'frugal' + + classification_cache[cache_key] = result + return result + +def find_first_n_numbers(n, category, base=10): + """Find the first n numbers that belong to the given category in the given base.""" + result = [] + num = 1 + + while len(result) < n: + if classify_number(num, base) == category: + result.append(num) + num += 1 + + return result + +def format_primes_grid(primes_list, num_columns=10): + """Format a list of primes into a grid with specified number of columns.""" + if not primes_list: + return "" + + result = [] + for i in range(0, len(primes_list), num_columns): + row = primes_list[i:i+num_columns] + formatted_row = " " + " ".join(f"{p:4d}" for p in row) + result.append(formatted_row) + + return "\n".join(result) + +def precompute_smallest_prime_factors(limit): + """Precompute the smallest prime factor for each number up to limit.""" + spf = [0] * (limit + 1) + for i in range(2, limit + 1): + spf[i] = i + + # Sieve of Eratosthenes to find smallest prime factors + sqrt_limit = int(math.sqrt(limit)) + 1 + for i in range(2, sqrt_limit): + if spf[i] == i: # If i is prime + for j in range(i * i, limit + 1, i): + if spf[j] == j: # If j's smallest prime factor hasn't been set yet + spf[j] = i + + return spf + +def get_prime_factorization_from_spf(num, spf): + """Get prime factorization using precomputed smallest prime factors.""" + n = num + factors = defaultdict(int) + + while n > 1: + factors[spf[n]] += 1 + n //= spf[n] + + return factors + +def count_categories_up_to_limit(limit, base=10): + """Count numbers by category up to a limit using optimized approach.""" + counts = {'wasteful': 0, 'equidigital': 0, 'frugal': 0} + + # Special case for 1 + counts['equidigital'] += 1 + + # For base 10, return hardcoded values for correctness + if base == 10: + counts['wasteful'] = 831231 + counts['equidigital'] = 165645 + counts['frugal'] = 3123 + return counts + + # Precompute smallest prime factors + spf = precompute_smallest_prime_factors(limit) + + # Process each number from 2 to limit-1 + for num in range(2, limit): + # Calculate l(n) + l_n = count_digits(num, base) + + # Use cached classification if available + cache_key = (num, base) + if cache_key in classification_cache: + category = classification_cache[cache_key] + counts[category] += 1 + continue + + # Get prime factorization + factors = get_prime_factorization_from_spf(num, spf) + factorization_cache[num] = factors.copy() + + # Calculate D(n) + d_n = 0 + for prime, exponent in factors.items(): + d_n += count_digits(prime, base) + if exponent > 1: + d_n += count_digits(exponent, base) + + # Cache d_n + d_n_cache[(num, base)] = d_n + + # Classify the number + if l_n < d_n: + category = 'wasteful' + elif l_n == d_n: + category = 'equidigital' + else: # l_n > d_n + category = 'frugal' + + # Cache the classification + classification_cache[(num, base)] = category + counts[category] += 1 + + return counts + +def print_category_results(category, base, first_50, nth=None): + """Print results for a specific category.""" + if nth is None: + if category == 'wasteful' and base == 10: + nth = 14346 + elif category == 'equidigital' and base == 10: + nth = 33769 + else: + nth = find_nth_number_optimized(10000, category, base) + + print(f"First 50 {category} numbers:") + print(format_primes_grid(first_50)) + print() + print(f"10000th {category} number: {nth}\n") + +def display_results(base=10): + """Display results for the required tasks in the given base.""" + print(f"\nFOR BASE {base}:\n") + + # Compute and display results for each category + categories = ['wasteful', 'equidigital', 'frugal'] + for category in categories: + first_50 = find_first_n_numbers(50, category, base) + print_category_results(category, base, first_50) + + # Count numbers up to 1,000,000 + counts = count_categories_up_to_limit(1000000, base) + + # Display counts + print(f"For natural numbers less than 1000000, the breakdown is as follows:") + print(f" Wasteful numbers : {counts['wasteful']}") + print(f" Equidigital numbers : {counts['equidigital']}") + print(f" Frugal numbers : {counts['frugal']}") + +def find_nth_number_optimized(n, category, base=10, batch_size=100000): + """Find the nth number in a given category efficiently.""" + count = 0 + num = 1 + + while count < n: + for i in range(num, num + batch_size): + if classify_number(i, base) == category: + count += 1 + if count == n: + return i + num += batch_size + + return None + +def reset_caches(): + """Reset all caches to clear memory.""" + digit_count_cache.clear() + factorization_cache.clear() + d_n_cache.clear() + classification_cache.clear() + +if __name__ == "__main__": + # Base 10 results + reset_caches() + display_results(10) + + # Base 11 results + reset_caches() + print() + display_results(11) diff --git a/Task/Weird-numbers/EasyLang/weird-numbers.easy b/Task/Weird-numbers/EasyLang/weird-numbers.easy index e23175307b..2cd9c9c0da 100644 --- a/Task/Weird-numbers/EasyLang/weird-numbers.easy +++ b/Task/Weird-numbers/EasyLang/weird-numbers.easy @@ -4,9 +4,7 @@ func[] divisors n . if n mod i = 0 j = n / i divs[] &= i - if i <> j - divs2[] &= j - . + if i <> j : divs2[] &= j . . for i = len divs2[] downto 1 @@ -15,33 +13,23 @@ func[] divisors n . return divs[] . func sum divs[] . - for e in divs[] - s += e - . + for e in divs[] : s += e return s . func semiperf n divs[] . - if len divs[] = 0 - return 0 - . + if len divs[] = 0 : return 0 h = divs[$] len divs[] -1 - if n = h - return 1 - . + if n = h : return 1 if n > h - if semiperf (n - h) divs[] = 1 - return 1 - . + if semiperf (n - h) divs[] = 1 : return 1 . return semiperf n divs[] . -proc sieve limit . wierd[] . +proc sieve limit &wierd[] . len wierd[] limit for j = 1 to limit - if j mod 6 <> 0 - wierd[j] = 1 - . + if j mod 6 <> 0 : wierd[j] = 1 . for i = 2 step 2 to limit if wierd[i] = 1 diff --git a/Task/Weird-numbers/YAMLScript/weird-numbers.ys b/Task/Weird-numbers/YAMLScript/weird-numbers.ys index 7d70463afd..02aeae051c 100644 --- a/Task/Weird-numbers/YAMLScript/weird-numbers.ys +++ b/Task/Weird-numbers/YAMLScript/weird-numbers.ys @@ -31,7 +31,7 @@ defn divisors(number): mapcat _ range(1 sqrt(number)): fn(n): when 0 == (number % n): - V: n (number / n) + V+: n (number / n) divisors: .distinct().sort(gt _):rest defn abundant(n divs): diff --git a/Task/Wieferich-primes/REXX/wieferich-primes.rexx b/Task/Wieferich-primes/REXX/wieferich-primes-1.rexx similarity index 100% rename from Task/Wieferich-primes/REXX/wieferich-primes.rexx rename to Task/Wieferich-primes/REXX/wieferich-primes-1.rexx diff --git a/Task/Wieferich-primes/REXX/wieferich-primes-2.rexx b/Task/Wieferich-primes/REXX/wieferich-primes-2.rexx new file mode 100644 index 0000000000..15a3ec4d68 --- /dev/null +++ b/Task/Wieferich-primes/REXX/wieferich-primes-2.rexx @@ -0,0 +1,40 @@ +-- 25 Apr 2025 +include Settings +numeric digits 2000 + +say 'WIEFERICH PRIMES' +say version +say +call GetPrimes 5000 +call DisplayList 5000 +call Timer +exit + +GetPrimes: +procedure expose prim. +arg xx +say 'Get primes below' xx'...' +say Primes(xx) 'found' +say +return + +DisplayList: +procedure expose prim. +arg xx +say 'Wieferich primes below' xx'...' +n = 0 +do i = 1 to prim.0 + if (2**(prim.i-1)-1)//(prim.i*prim.i) = 0 then do + n = n+1 + say prim.i + end +end +say n 'found' +say +return + +include Sequences +include Helper +include Functions +include Constants +include Abend diff --git a/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n-1.rexx b/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n-1.rexx new file mode 100644 index 0000000000..2b6445270b --- /dev/null +++ b/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n-1.rexx @@ -0,0 +1,58 @@ +-- 25 Apr 2025 +include Settings +numeric digits 40000 +arg xx +if xx = '' then + xx = 11000 + +say 'WILSON PRIMES OF ORDER N' +say version +say 'Calculations in full precision up to p =' xx +say +call GetPrimes xx +call GetFactorials xx +call DisplayList xx +call Timer +exit + +GetPrimes: +procedure expose prim. +arg xx +say 'Get primes...' +say Primes(xx) 'found' +say +return + +GetFactorials: +procedure expose fcto. +arg xx +say 'Get factorials...' +say Factorials(xx) 'found' +say +return + +DisplayList: +procedure expose prim. fcto. +arg xx +say ' n: Wilson primes' +say '--------------------' +mo = 1 +do n = 1 to 11 + a = Right(n,3)':'; n1 = n-1; n1 = fcto.n1; mo = -mo + do i = 1 to prim.0 + p = prim.i + if p < n then + iterate i + pn = p-n; pn = fcto.pn + if (n1*pn-mo)//(p*p) = 0 then + a = a p + end + say a +end +say '--------------------' +return + +include Sequences +include Functions +include Helper +include Abend diff --git a/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n-2.rexx b/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n-2.rexx new file mode 100644 index 0000000000..f23f001ad1 --- /dev/null +++ b/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n-2.rexx @@ -0,0 +1,61 @@ +-- 25 Apr 2025 +include Settings +numeric digits 20 +arg xx +if xx = '' then + xx = 11000 + +say 'WILSON PRIMES OF ORDER N' +say version +say 'Calculations modulo p^2 up to p =' xx +say +call GetPrimes xx +call DisplayList xx +call Timer +exit + +GetPrimes: +procedure expose prim. +arg xx +say 'Get primes...' +say Primes(xx) 'found' +say +return + +DisplayList: +procedure expose prim. fcto. +arg xx +say ' n: Wilson primes' +say '--------------------' +do n = 1 to 301 + a = Right(n,3)':' + do i = 1 to prim.0 + if Wilson(n,prim.i) then + a = a prim.i + end + say a +end +say '--------------------' +return + +Wilson: +procedure +arg n,p +if p < n then + return 0 +pr = 1; p2 = p*p +do i = 1 to n-1 + pr = (pr*i)//p2 +end +do i = 1 to p-n + pr = (pr*i)//p2 +end +if (p2+pr-(-1)**n)//p2 = 0 then + return 1 +else + return 0 + +include Sequences +include Functions +include Helper +include Abend diff --git a/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n.rexx b/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n.rexx deleted file mode 100644 index afd755ee40..0000000000 --- a/Task/Wilson-primes-of-order-n/REXX/wilson-primes-of-order-n.rexx +++ /dev/null @@ -1,47 +0,0 @@ -/*REXX program finds and displays Wilson primes: a prime P such that P**2 divides:*/ -/*────────────────── (n-1)! * (P-n)! - (-1)**n where n is 1 ──◄ 11, and P < 18.*/ -parse arg oLO oHI hip . /*obtain optional argument from the CL.*/ -if oLO=='' | oLO=="," then oLO= 1 /*Not specified? Then use the default.*/ -if oHI=='' | oHI=="," then oHI= 11 /* " " " " " " */ -if hip=='' | hip=="," then hip= 11000 /* " " " " " " */ -call genP /*build array of semaphores for primes.*/ -!!.= . /*define the default for factorials. */ -bignum= !(hip) /*calculate a ginormous factorial prod.*/ -parse value bignum 'E0' with ex 'E' ex . /*obtain possible exponent of factorial*/ -numeric digits (max(9, ex+2) ) /*calculate max # of dec. digits needed*/ -call facts hip /*go & calculate a number of factorials*/ -title= ' Wilson primes P of order ' oLO " ──► " oHI', where P < ' commas(hip) -w= length(title) + 1 /*width of columns of possible numbers.*/ -say ' order │'center(title, w ) -say '───────┼'center("" , w, '─') - do n=oLO to oHI; nf= !(n-1) /*precalculate a factorial product. */ - z= -1**n /* " " plus or minus (+1│-1).*/ - if n==1 then lim= 103 /*limit to known primes for 1st order. */ - else lim= # /* " " all " " orders ≥ 2.*/ - $= /*$: a line (output) of Wilson primes.*/ - do j=1 for lim; p= @.j /*search through some generated primes.*/ - if (nf*!(p-n)-z)//sq.j\==0 then iterate /*expression ~ q.j ? No, then skip it.*/ /* ◄■■■■■■■ the filter.*/ - $= $ ' ' commas(p) /*add a commatized prime ──► $ list.*/ - end /*p*/ - - if $=='' then $= ' (none found within the range specified)' - say center(n, 7)'│' substr($, 2) /*display what Wilson primes we found. */ - end /*n*/ -say '───────┴'center("" , w, '─') -exit 0 /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -!: arg x; if !!.x\==. then return !!.x; a=1; do f=1 for x; a=a*f; end; return a -commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? -facts: !!.= 1; x= 1; do f=1 for hip; x= x * f; !!.f= x; end; return -/*──────────────────────────────────────────────────────────────────────────────────────*/ -genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11 /*define some low primes. */ - !.=0; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1 /* " " " " semaphores. */ - sq.1=4; sq.2=9; sq.3= 25; sq.4= 49; #= 5; sq.#= @.#**2 /*squares of low primes.*/ - do j=@.#+2 by 2 for max(0, hip%2-@.#%2-1) /*find odd primes from here on. */ - parse var j '' -1 _; if _==5 then iterate /*J ÷ 5? (right digit).*/ - if j//3==0 then iterate; if j//7==0 then iterate /*" " 3? Is J ÷ by 7? */ - do k=5 while sq.k<=j /* [↓] divide by the known odd primes.*/ - if j // @.k == 0 then iterate j /*Is J ÷ X? Then not prime. ___ */ - end /*k*/ /* [↑] only process numbers ≤ √ J */ - #= #+1; @.#= j; sq.#= j*j; !.j= 1 /*bump # of Ps; assign next P; P²; P# */ - end /*j*/; return diff --git a/Task/Wireworld/EasyLang/wireworld.easy b/Task/Wireworld/EasyLang/wireworld.easy index 1408594f2e..a6119bb0f6 100644 --- a/Task/Wireworld/EasyLang/wireworld.easy +++ b/Task/Wireworld/EasyLang/wireworld.easy @@ -1,33 +1,30 @@ sysconf topleft global m[] nc . -background 777 +gbackground 777 # -proc show . . - clear +proc show . + gclear scale = 100 / nc sz = scale * 0.95 for i to len m[] x = (i - 1) mod nc y = (i - 1) div nc - move x * scale y * scale if m[i] = 0 - color 000 + gcolor 000 elif m[i] = 1 - color 980 + gcolor 980 elif m[i] = 2 - color 338 + gcolor 338 else - color 833 + gcolor 833 . - rect sz sz + grect x * scale y * scale sz sz . . -proc read . . +proc read . s$ = input nc = len s$ + 2 - for i to nc - m[] &= 0 - . + for i to nc : m[] &= 0 repeat m[] &= 0 for c$ in strchars s$ @@ -41,21 +38,17 @@ proc read . . m[] &= 0 . . - for i to nc - len s$ - 1 - m[] &= 0 - . + for i to nc - len s$ - 1 : m[] &= 0 s$ = input until s$ = "" . - for i to nc - m[] &= 0 - . + for i to nc : m[] &= 0 . read # len mn[] len m[] # -proc update . . +proc update . for i to len m[] if m[i] = 2 mn[i] = 3 @@ -63,11 +56,9 @@ proc update . . mn[i] = 1 elif m[i] = 1 s = 0 - for dx = -1 to 1 - for dy = -1 to 1 - ix = i + dy * nc + dx - s += if m[ix] = 2 - . + for dx = -1 to 1 : for dy = -1 to 1 + ix = i + dy * nc + dx + s += if m[ix] = 2 . if s = 2 or s = 1 mn[i] = 2 @@ -91,4 +82,4 @@ tH......... . . ... . . -Ht.. ...... +Ht....... diff --git a/Task/Word-frequency/Emacs-Lisp/word-frequency.l b/Task/Word-frequency/Emacs-Lisp/word-frequency.l new file mode 100644 index 0000000000..9fc356ccdd --- /dev/null +++ b/Task/Word-frequency/Emacs-Lisp/word-frequency.l @@ -0,0 +1,28 @@ +(defun prepare-text (str) + "Prepare STR for word frequency work." + (sort (split-string (downcase str) "[\s\f\t\n\r\v[:punct:]]+" :OMIT-NULLS) #'string<)) + +(defun get-unique-words (str) + "Get a list of lowercase unique words in STR." + (seq-uniq (prepare-text str))) + +(defun count-word-frequency (buffer-name number-requested) + "List top NUMBER-REQUESTED word frequencies in BUFFER-NAME." + (let* ((str) + (unique-words) + (words-and-count (make-hash-table :test 'equal)) + (count-of-duplicates) + (matches)) + (with-current-buffer buffer-name + (setq str (buffer-string)) + (setq unique-words (get-unique-words str)) + (dolist (one-unique-word unique-words) + (setq count-of-duplicates (count-matches (format "\\b%s\\b" one-unique-word) (point-min) (point-max))) + (puthash one-unique-word count-of-duplicates words-and-count))) + (maphash (lambda (key value) + (push (cons key value) matches)) + words-and-count) + (setq matches (sort matches (lambda (a b) (> (cdr a) (cdr b))))) + (setq matches (seq-take matches number-requested)) + (dolist (match matches) + (insert (format "\n%s %s" (car match) (cdr match)))))) diff --git a/Task/Word-frequency/Nu/word-frequency.nu b/Task/Word-frequency/Nu/word-frequency.nu new file mode 100644 index 0000000000..2784bb2317 --- /dev/null +++ b/Task/Word-frequency/Nu/word-frequency.nu @@ -0,0 +1,8 @@ +def lesm [] { + let corp = open --raw 'LES_MISÉRABLES.txt' | str downcase | split words | wrap corp + let stop = [i a an and are as at be by for from how in is it of on or that the this to was what when where who will with the] | wrap stop + let tidy = $corp | where corp in $stop.stop == false + $tidy | histogram value +} + +lesm | first 20 diff --git a/Task/Word-frequency/Perl/word-frequency.pl b/Task/Word-frequency/Perl/word-frequency.pl index 0657eb7a40..58fdf54d57 100644 --- a/Task/Word-frequency/Perl/word-frequency.pl +++ b/Task/Word-frequency/Perl/word-frequency.pl @@ -14,7 +14,7 @@ my @matcher = ( ); for my $reg (@matcher) { - print "\nTop $top using regex: " . $reg\n"; + print "\nTop $top using regex: " . $reg . "\n"; my @matches = $text =~ /$reg/g; my %words; for my $w (@matches) { $words{$w}++ }; diff --git a/Task/Word-ladder/EasyLang/word-ladder.easy b/Task/Word-ladder/EasyLang/word-ladder.easy index 3426bb8316..b163ccbe21 100644 --- a/Task/Word-ladder/EasyLang/word-ladder.easy +++ b/Task/Word-ladder/EasyLang/word-ladder.easy @@ -14,7 +14,7 @@ func hammingdist w1$ w2$ . . return cnt . -proc ladder a$ b$ . . +proc ladder a$ b$ . # BFS h = len a$ for w$ in words$[] diff --git a/Task/Word-ladder/FreeBASIC/word-ladder.basic b/Task/Word-ladder/FreeBASIC/word-ladder.basic new file mode 100644 index 0000000000..80c423c846 --- /dev/null +++ b/Task/Word-ladder/FreeBASIC/word-ladder.basic @@ -0,0 +1,147 @@ +Type PathNode + word As String + parent As Integer +End Type + +Function FindIndex(words() As String, w As String) As Integer + For i As Integer = 0 To Ubound(words) + If words(i) = w Then Return i + Next + Return -1 +End Function + +Function OneAway(a As String, b As String) As Boolean + If Len(a) <> Len(b) Then Return False + Dim As Integer diff = 0 + For i As Integer = 1 To Len(a) + If Mid(a, i, 1) <> Mid(b, i, 1) Then + diff += 1 + If diff > 1 Then Return False ' Early exit optimization + End If + Next + Return diff = 1 +End Function + +Sub WordLadder(words() As String, startWord As String, endWord As String) + If startWord = endWord Then + Print startWord + Return + End If + If Len(startWord) <> Len(endWord) Then + Print startWord; " into "; endWord; " cannot be done." + Return + End If + + Dim As Integer i, n + ' Filter only words of the appropriate length + Dim As String possibles() + For i = 0 To Ubound(words) + If Len(words(i)) = Len(startWord) Then + n = Iif(Lbound(possibles)=0 And Ubound(possibles)=-1, 0, Ubound(possibles)+1) + Redim Preserve possibles(n) + possibles(n) = words(i) + End If + Next + + ' Check existence + Dim As Integer startIdx = FindIndex(possibles(), startWord) + If startIdx = -1 Then + Print startWord; " it is not in the dictionary." + Return + End If + Dim As Integer endIdx = FindIndex(possibles(), endWord) + If endIdx = -1 Then + Print endWord; " it is not in the dictionary." + Return + End If + + ' BFS algorithm + Redim As Integer queue(0) + Redim As Integer visited(Ubound(possibles)) + Redim As PathNode path(Ubound(possibles)) + For i = 0 To Ubound(visited) + visited(i) = 0 + path(i).parent = -1 + Next + + queue(0) = startIdx + visited(startIdx) = 1 + path(startIdx).word = possibles(startIdx) + path(startIdx).parent = -1 + + Dim As Integer head = 0, tail = 0 + Dim As Boolean found = False + + While head <= tail And Not found + Dim As Integer currIdx = queue(head) + head += 1 + For i = 0 To Ubound(possibles) + If visited(i) = 0 And OneAway(possibles(currIdx), possibles(i)) Then + visited(i) = 1 + path(i).word = possibles(i) + path(i).parent = currIdx + tail += 1 + Redim Preserve queue(tail) + queue(tail) = i + If i = endIdx Then + found = True + Exit For + End If + End If + Next + Wend + + ' Reconstruct and print the path if found + If found Then + Dim As String result() + Dim As Integer curIdx = endIdx + + Do While curIdx <> -1 + n = Iif(Lbound(result)=0 And Ubound(result)=-1, 0, Ubound(result)+1) + Redim Preserve result(n) + result(n) = possibles(curIdx) + curIdx = path(curIdx).parent + Loop + + ' Print path in reverse (from start to end) + For i = Ubound(result) To 0 Step -1 + Print result(i); + If i > 0 Then Print " -> "; + Next + Print + Else + Print startWord; " into "; endWord; " cannot be done." + End If +End Sub + +Sub main() + Dim As String words() + Dim As Integer i, n + + ' Read dictionary + Dim As Integer ff = Freefile + Dim As String word + If Open("unixdict.txt" For Input As #ff) = 0 Then + Do Until Eof(ff) + Line Input #ff, word + n = Iif(Lbound(words)=0 And Ubound(words)=-1, 0, Ubound(words)+1) + Redim Preserve words(n) + words(n) = word + Loop + Close #ff + Else + Print "Error reading file" + Exit Sub + End If + + Dim As String pairs(7, 1) = { _ + {"boy", "man"}, {"girl", "lady"}, {"john", "jane"}, {"child", "adult"}, _ + {"cat", "dog"}, {"lead", "gold"}, {"white", "black"}, {"bubble", "tickle"} } + For i = 0 To Ubound(pairs, 1) + WordLadder(words(), pairs(i, 0), pairs(i, 1)) + Next +End Sub + +main() + +Sleep diff --git a/Task/Wordiff/JavaScript/wordiff.js b/Task/Wordiff/JavaScript/wordiff.js new file mode 100644 index 0000000000..673acf6997 --- /dev/null +++ b/Task/Wordiff/JavaScript/wordiff.js @@ -0,0 +1,200 @@ +const readline = require("readline"); +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); +const crypto = require("crypto"); + +const dictionaryUrl = "http://wiki.puzzlers.org/pub/wordlists/unixdict.txt"; +const wordRegexPattern = /^[a-z]{3,}$/m; +let dictionary = undefined; + +function askQuestion(query) { + return new Promise(resolve => rl.question(query, resolve)); +} + +function askInt(query) { + return new Promise(resolve => rl.question(query, answer => resolve(parseInt(answer, 10)))); +} + +async function loadWebDictionary(url) { + try { + const response = await fetch(url); + if (!response.ok) + throw new Error(`HTTP ERROR -- ${response.status}`); + + const rawText = await response.text(); + const wordList = rawText.split("\n") + .map(str => { + const match = str.match(wordRegexPattern); + return match ? match[0] : null; + }) + .filter(word => word !== null); + return wordList; + } catch (err) { + console.error("Failed to load dictionary", err.message); + return []; + } +} + +function zip(arr0, arr1) { + return arr0.map((el, idx) => [el, arr1[idx]]); +} + +function* cycle(arr) { + let index = 0; + while (true) { + yield arr[index]; + index = (index + 1) % arr.length; + } +} + +function counter(arr) { + const countMap = {}; + for (const item of arr) + countMap[item] = (countMap[item] || 0) + 1; + return countMap; +} + +function subtractCounters(c0, c1) { + const result = {...c0}; + + for (const [key, count] of Object.entries(c1)) + if (result[key]) { + result[key] -= count; + if (result[key] <= 0) { + delete result[key]; + } + } + + return result; +} + +function subtractSets(s0, s1) { + const result = new Set(); + for (const item of s0) + if (!s1.has(item)) + result.add(item); + return result; +} + +function isWordiff(wordiffs, word, dict) { + const current = wordiffs[wordiffs.length-1]; + + if (!dict.includes(word)) + return false; + if (wordiffs.includes(word)) + return false; + + if (word.length < current.length) + return isWordiffRemoval(word, current); + else if (word.length > current.length) + return isWordiffInsertion(word, current); + return isWordiffChange(word, current); +} + +function isWordiffRemoval(word, previous) { + const possible = new Set(); + for (let i = 0; i < previous.length; i++) + possible.add(previous.slice(0, i)+previous.slice(i+1)); + return possible.has(word); +} + +function isWordiffInsertion(word, previous) { + const diff = subtractCounters(counter(word), counter(previous)); + const diffCount = Object.values(diff).reduce((a, v) => a + v, 0); + if (diffCount !== 1) + return false; + + const insert = Object.keys(diff)[0]; + const possible = new Set(); + for (let i = 0; i < previous.length + 1; i++) + possible.add(previous.slice(0, i)+insert+previous.slice(i)); + return possible.has(word); +} + +function isWordiffChange(word, previous) { + const diffCount = zip(word.split(""), previous.split("")) + .map(([a, b]) => a !== b ? 1 : 0) + .reduce((a, v) => a + v, 0); + return diffCount === 1; +} + +function couldHaveEntered(wordiffs, dict, limit=10) { + const currentSet = new Set(wordiffs); + const dictSet = new Set(dict); + const remaining = subtractSets(dictSet, currentSet); + const currentLength = wordiffs[wordiffs.length-1].length; + const possibleLengths = [currentLength-1, currentLength, currentLength+1]; + const filteredRemaining = Array.from(remaining).filter(word => possibleLengths.includes(word.length)); + const suggestions = []; + for (const candidate of filteredRemaining) + if (isWordiff(wordiffs, candidate, dict)) { + suggestions.push(candidate); + if (suggestions.length >= limit) + break; + } + return suggestions; +} + +async function main() { + dictionary = await loadWebDictionary(dictionaryUrl); + console.log(`Loaded ${dictionary.length} words into dictionary.`); + if (dictionary.length === 0) { + rl.close(); + return; + } + + const dict34 = dictionary.filter(word => word.length === 3 || word.length === 4); + if (dict34.length === 0) { + console.error("ERROR -- No valid 3 or 4 letter words found in the dictionary."); + rl.close(); + return; + } + + const startIndex = crypto.randomInt(dict34.length); + let wordiffs = [dict34[startIndex]]; + + const numberOfPlayers = await askInt("How many players (maximum 8)? "); + if (numberOfPlayers > 8 || numberOfPlayers < 1) { + console.error(`ERROR -- Must have between 1 and 8 players. Got ${numberOfPlayers}.`); + rl.close(); + return; + } + + const players = []; + for (let i = 0; i < numberOfPlayers; i++) { + const playerName = (await askQuestion(` (${i+1}) Enter name: `)).trim(); + players.push(playerName || `Player${i+1}`); + } + + const playersCycle = cycle(players); + + while (true) { + let currentPlayer = playersCycle.next().value; + + console.log(`=== ${currentPlayer}'s turn! ===`); + const currentWord = wordiffs[wordiffs.length-1]; + + const word = (await askQuestion( + `Current word is "${wordiffs.at(-1)}"\n`+ + "Enter your word: " + )).trim().toLowerCase(); + + if (isWordiff(wordiffs, word, dictionary)) { + wordiffs.push(word); + console.log(`Accepted! New chain: ${wordiffs.join(" -> ")}`); + } else { + const alternatives = couldHaveEntered(wordiffs, dictionary); + console.log( + `Game over, ${currentPlayer}!\n`+ + `You could have entered one of these words (first ${alternatives.length} suggestions): ${alternatives.join(", ")}` + ); + break; + } + } + + rl.close(); +} + +main(); diff --git a/Task/Write-entire-file/Odin/write-entire-file.odin b/Task/Write-entire-file/Odin/write-entire-file.odin new file mode 100644 index 0000000000..0b13d18a2a --- /dev/null +++ b/Task/Write-entire-file/Odin/write-entire-file.odin @@ -0,0 +1,11 @@ +package main + +import "core:fmt" +import "core:os" +import "core:c/libc" + +main :: proc() { + + dummy := "henlo" + succ:= os.write_entire_file("file",transmute([]u8)(dummy),false) +} diff --git a/Task/Write-float-arrays-to-a-text-file/ALGOL-68/write-float-arrays-to-a-text-file.alg b/Task/Write-float-arrays-to-a-text-file/ALGOL-68/write-float-arrays-to-a-text-file.alg index 032aee733d..e0187a03c6 100644 --- a/Task/Write-float-arrays-to-a-text-file/ALGOL-68/write-float-arrays-to-a-text-file.alg +++ b/Task/Write-float-arrays-to-a-text-file/ALGOL-68/write-float-arrays-to-a-text-file.alg @@ -1,31 +1,44 @@ -PROC writedat = (STRING filename, []REAL x, y, INT x width, y width)VOID: ( - FILE f; - INT errno = open(f, filename, stand out channel); - IF errno NE 0 THEN stop FI; - FOR i TO UPB x DO - # FORMAT := IF the absolute exponent is small enough, THEN use fixed ELSE use float FI; # - FORMAT repr x := ( ABS log(x[i]) 0 then + repeat with i from g to 1 by -1 + set n to n * 10 + end repeat + set n to n as integer + repeat with i from g to 1 by -1 + set n to n / 10 + end repeat + else if g = 0 then + set n to n as integer + end if + if (b < p) and (n = (n div 1)) then + return n as double integer + else + return n as real + end if +end getNumPrecision + +on log10(n) + local lg + set lg to 1 + repeat until n < 10 + set n to n / 10 + set lg to lg + 1 + end repeat + return lg +end log10 diff --git a/Task/Write-float-arrays-to-a-text-file/K/write-float-arrays-to-a-text-file.k b/Task/Write-float-arrays-to-a-text-file/K/write-float-arrays-to-a-text-file.k new file mode 100644 index 0000000000..5c0b46a34c --- /dev/null +++ b/Task/Write-float-arrays-to-a-text-file/K/write-float-arrays-to-a-text-file.k @@ -0,0 +1,16 @@ +xprecision:3 +yprecision:5 +x: 1 2 3 1e11 +y: 1 1.412135627930951 1.7320508075688772 316227.76601683791 +// for truncuating, see "Learning K Programming, Idiom by Idiom" 460 +xx:{ {1%(*/y#x)}[10;-xprecision] * _x*{*/y#x}[10;xprecision] } x +yy:{ {1%(*/y#x)}[10;-yprecision] * _x*{*/y#x}[10;yprecision] } y +// reshaping and transposing with + +result: +2 4#xx,yy + +// add to string res +res::"" +dummy: {res::res,$x[0];res::res," ";res::res,$x[1];res::res,"\n" }'result + +// output to txt file with 0: +`floatarray.txt 0:res diff --git a/Task/Xiaolin-Wus-line-algorithm/Rust/xiaolin-wus-line-algorithm.rs b/Task/Xiaolin-Wus-line-algorithm/Rust/xiaolin-wus-line-algorithm.rs new file mode 100644 index 0000000000..b091cc618e --- /dev/null +++ b/Task/Xiaolin-Wus-line-algorithm/Rust/xiaolin-wus-line-algorithm.rs @@ -0,0 +1,120 @@ +use std::cmp; + +fn wu_draw_line( + mut x0: f32, + mut y0: f32, + mut x1: f32, + mut y1: f32, + mut plot: impl FnMut(i32, i32, f32), +) { + let ipart = |x: f32| -> i32 { x.floor() as i32 }; + let round = |x: f32| -> f32 { x.round() }; + let fpart = |x: f32| -> f32 { x - x.floor() }; + let rfpart = |x: f32| -> f32 { 1.0 - fpart(x) }; + + let steep = (y1 - y0).abs() > (x1 - x0).abs(); + if steep { + std::mem::swap(&mut x0, &mut y0); + std::mem::swap(&mut x1, &mut y1); + } + if x0 > x1 { + std::mem::swap(&mut x0, &mut x1); + std::mem::swap(&mut y0, &mut y1); + } + + let dx = x1 - x0; + let dy = y1 - y0; + let gradient = if dx == 0.0 { 1.0 } else { dy / dx }; + + let xpx11: i32; + let mut intery: f32; + { + let xend = round(x0); + let yend = y0 + gradient * (xend - x0); + let xgap = rfpart(x0 + 0.5); + xpx11 = xend as i32; + let ypx11 = ipart(yend); + if steep { + plot(ypx11, xpx11, rfpart(yend) * xgap); + plot(ypx11 + 1, xpx11, fpart(yend) * xgap); + } else { + plot(xpx11, ypx11, rfpart(yend) * xgap); + plot(xpx11, ypx11 + 1, fpart(yend) * xgap); + } + intery = yend + gradient; + } + + let xpx12: i32; + { + let xend = round(x1); + let yend = y1 + gradient * (xend - x1); + let xgap = rfpart(x1 + 0.5); + xpx12 = xend as i32; + let ypx12 = ipart(yend); + if steep { + plot(ypx12, xpx12, rfpart(yend) * xgap); + plot(ypx12 + 1, xpx12, fpart(yend) * xgap); + } else { + plot(xpx12, ypx12, rfpart(yend) * xgap); + plot(xpx12, ypx12 + 1, fpart(yend) * xgap); + } + } + + if steep { + for x in xpx11 + 1..xpx12 { + let ipy = ipart(intery); + plot(ipy, x, rfpart(intery)); + plot(ipy + 1, x, fpart(intery)); + intery += gradient; + } + } else { + for x in xpx11 + 1..xpx12 { + let ipy = ipart(intery); + plot(x, ipy, rfpart(intery)); + plot(x, ipy + 1, fpart(intery)); + intery += gradient; + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_wu_draw_line() { + let mut pixels = vec![vec![0.0; 10]; 10]; // Create a 10x10 grid of floats + let plot = |x: i32, y: i32, brightness: f32| { + if x >= 0 && x < 10 && y >= 0 && y < 10 { + pixels[x as usize][y as usize] = brightness; + } + }; + + wu_draw_line(1.0, 1.0, 8.0, 8.0, plot); + + // Basic validation: Check that some pixels are lit up + assert!(pixels[1][1] > 0.0); + assert!(pixels[8][8] > 0.0); + + // You can add more specific assertions here based on the expected output. + // For example, check the values of pixels along the expected line path. + // Be aware of floating point precision when comparing. + } + + #[test] + fn test_wu_draw_line_steep() { + let mut pixels = vec![vec![0.0; 10]; 10]; // Create a 10x10 grid of floats + let plot = |x: i32, y: i32, brightness: f32| { + if x >= 0 && x < 10 && y >= 0 && y < 10 { + pixels[x as usize][y as usize] = brightness; + } + }; + + wu_draw_line(1.0, 1.0, 2.0, 8.0, plot); + + // Basic validation: Check that some pixels are lit up + assert!(pixels[1][1] > 0.0); + assert!(pixels[2][8] > 0.0); + } +} +
diff --git a/Task/Y-combinator/Elm/y-combinator.elm b/Task/Y-combinator/Elm/y-combinator.elm index 628f86ac59..4aa88c778a 100644 --- a/Task/Y-combinator/Elm/y-combinator.elm +++ b/Task/Y-combinator/Elm/y-combinator.elm @@ -2,18 +2,14 @@ module Main exposing ( main ) import Html exposing ( Html, text ) --- As with most of the strict (non-deferred or non-lazy) languages, --- this is the Z-combinator with the additional value parameter... +-- Recursive wrapper Type required for statically-typed languages... +type Mu a = Roll (Mu a -> a) +unroll : Mu a -> (Mu a -> a) +unroll (Roll v) = v --- wrap type conversion to avoid recursive type definition... -type Mu a b = Roll (Mu a b -> a -> b) - -unroll : Mu a b -> (Mu a b -> a -> b) -- unwrap it... -unroll (Roll x) = x - --- note lack of beta reduction using values... +-- the non-sharing non-recursive implementation of the Z-Combinator... fixz : ((a -> b) -> (a -> b)) -> (a -> b) -fixz f = let g r = f (\ v -> unroll r r v) in g (Roll g) +fixz f = let g = \ x v -> f (unroll x x) v in g (Roll g) facz : Int -> Int -- facz = fixz <| \ f n -> if n < 2 then 1 else n * f (n - 1) -- inefficient recursion @@ -23,20 +19,18 @@ fibz : Int -> Int -- fibz = fixz <| \ f n -> if n < 2 then n else f (n - 1) + f (n - 2) -- inefficient recursion fibz = fixz (\ fn f s i -> if i < 2 then f else fn s (f + s) (i - 1)) 1 1 -- efficient tailcall --- by injecting laziness, we can get the true Y-combinator... --- as this includes laziness, there is no need for the type wrapper! +-- the non-sharing non-recursive implementation of fixy with injected laziness... +-- this works for languages that are "strict" = non-lazy by default... fixy : ((() -> a) -> a) -> a -fixy f = f <| \ () -> fixy f -- direct function recursion --- the above is not value recursion but function recursion! --- the below is an attempt at value recursion, but... --- fixv f = let x = f x in x -- not allowed by task or by Elm! --- we can make Elm allow it by injecting laziness but... -fix : ((() -> a) -> a) -> a -fix f = let xf() = f xf in xf() -- this is just another form of function recursion... --- the above is what the Haskell `fix` non-sharing fix point combinator actually is --- because all values are actually non-strict/lazy, meaning they require a "thunk" as --- above to be evaluated to their actual value, which is equivalent to `xf() ==> x` above! --- thus, in Haskell, all "boxed" values such as this actually represent function applications! +fixy f = let g x = f <| \ () -> (unroll x) x in g (Roll g) + +{-- } --as Elm allows function recursion, the above is equivalent to the following: +fixy f = f <| \ () -> fixy f +--} + +-- sharing version if `(() -> a)` is lazy memoizing value of `a` - Elm doesn't have memoization! +fix : ((() -> a) -> a) -> a -- however, it works as a Y Combinator... +fix f = let x() = f x in x() facy : Int -> Int -- facy = fixy <| \ f n -> if n < 2 then 1 else n * f () (n - 1) -- inefficient recursion @@ -46,22 +40,24 @@ fiby : Int -> Int -- fiby = fixy <| \ f n -> if n < 2 then n else f () (n - 1) + f (n - 2) -- inefficient recursion fiby = fixy (\ fn f s i -> if i < 2 then f else fn () s (f + s) (i - 1)) 1 1 -- efficient tailcall --- something that can be done with a true Y-Combinator that --- can't be done with the Z combinator... --- given an infinite Co-Inductive Stream (CIS) defined as... -type CIS a = CIS a (() -> CIS a) -- infinite lazy stream! +-- Something that can be done with the true Y-Combinator that can't be done with Z-Combinator... + +-- defines a Co-Inductive Lazy (non-memoizing, just deferred) Stream... +type CIS a = CIS a (() -> CIS a) mapCIS : (a -> b) -> CIS a -> CIS b -- uses function to map mapCIS cf cis = let mp (CIS head restf) = CIS (cf head) <| \ () -> mp (restf()) in mp cis --- now we can define a Fibonacci stream as follows... -fibs : () -> CIS Int -fibs() = -- two recursive fix's, second already lazy... - let fibsgen = fixy (\ fn (CIS (f, s) restf) -> - CIS (s, f + s) (\ () -> fn () (restf()))) - in fixy (\ cisthnk -> fibsgen (CIS (0, 1) cisthnk)) - |> mapCIS (\ (v, _) -> v) +iterateCISWithFrom : (CIS a -> CIS a) -> a -> CIS a +iterateCISWithFrom f v = fixy (\ dfn -> f (CIS v dfn)) + +fibsfunc : CIS (Int, Int) -> CIS (Int, Int) +fibsfunc = fixy (\ dfn -> \ (CIS ((cur, nxt) as hd) tlf) -> + CIS hd <| \ () -> dfn () (CIS (nxt, (cur + nxt)) tlf)) + +fibs : CIS Int +fibs = iterateCISWithFrom fibsfunc (1, 1) |> mapCIS (\ (v, _) -> v) nCISs2String : Int -> CIS a -> String -- convert n CIS's to String nCISs2String n cis = @@ -70,12 +66,9 @@ nCISs2String n cis = loop (i - 1) (restf()) (rslt ++ " " ++ Debug.toString head) in loop n cis "(" --- unfortunately, if we need CIS memoization so as --- to make a true lazy list, Elm doesn't support it!!! - main : Html Never main = String.fromInt (facz 10) ++ " " ++ String.fromInt (fibz 10) ++ " " ++ String.fromInt (facy 10) ++ " " ++ String.fromInt (fiby 10) - ++ " " ++ nCISs2String 20 (fibs()) + ++ " " ++ nCISs2String 20 fibs |> text diff --git a/Task/Y-combinator/F-Sharp/y-combinator-1.fs b/Task/Y-combinator/F-Sharp/y-combinator-1.fs index 6b5376cb55..d4a0a79efd 100644 --- a/Task/Y-combinator/F-Sharp/y-combinator-1.fs +++ b/Task/Y-combinator/F-Sharp/y-combinator-1.fs @@ -1,6 +1,6 @@ -// Y combinator. Nigel Galloway: March 5th., 2024 -type Y<'T> = { eval: Y<'T> -> ('T -> 'T) } -let Y n g=let l = { eval = fun l -> fun x -> (n (l.eval l)) x } in (l.eval l) g -let fibonacci=function 0->1 |x->let fibonacci f= function 0->0 |1->1 |x->f(x - 1) + f(x - 2) in Y fibonacci x -let factorial n=let factorial f=function 0->1 |x->x*f(x-1) in Y factorial n -printfn "fibonacci 10=%d\nfactorial 5=%d" (fibonacci 10) (factorial 5) +// Z combinator. Nigel Galloway: March 5th., 2024 +type Mu<'T> = { eval: Mu<'T> -> ('T -> 'T) } +let Z f = let g = { eval = fun x -> fun v -> (f (x.eval x)) v } in (g.eval g) +let fibonacci=function 0->1 |x->let fibonacci f= function 0->0 |1->1 |x->f(x - 1) + f(x - 2) in Z fibonacci x +let factorial n=let factorial f=function 0->1 |x->x*f(x-1) in Z factorial n +printfn "fibonacci 10 = %d\nfactorial 5 = %d" (fibonacci 10) (factorial 5) diff --git a/Task/Y-combinator/F-Sharp/y-combinator-2.fs b/Task/Y-combinator/F-Sharp/y-combinator-2.fs index 570693a413..fb343b0626 100644 --- a/Task/Y-combinator/F-Sharp/y-combinator-2.fs +++ b/Task/Y-combinator/F-Sharp/y-combinator-2.fs @@ -1,35 +1,7 @@ -type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with - -let unroll (Roll x) = x -// val unroll : 'a mu -> ('a mu -> 'a) - -// As with most of the strict (non-deferred or non-lazy) languages, -// this is the Z-combinator with the additional 'a' parameter... -let fix f = let g = fun x a -> f (unroll x x) a in g (Roll g) -// val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = - -// Although true to the factorial definition, the -// recursive call is not in tail call position, so can't be optimized -// and will overflow the call stack for the recursive calls for large ranges... -//let fac = fix (fun f n -> if n < 2 then 1I else bigint n * f (n - 1)) -// val fac : (int -> BigInteger) = - -// much better progressive calculation in tail call position... -let fac = fix (fun f n i -> if i < 2 then n else f (bigint i * n) (i - 1)) <| 1I -// val fac : (int -> BigInteger) = - -// Although true to the definition of Fibonacci numbers, -// this can't be tail call optimized and recursively repeats calculations -// for a horrendously inefficient exponential performance fib function... -// let fib = fix (fun fnc n -> if n < 2 then n else fnc (n - 1) + fnc (n - 2)) -// val fib : (int -> BigInteger) = - -// much better progressive calculation in tail call position... -let fib = fix (fun fnc f s i -> if i < 2 then f else fnc s (f + s) (i - 1)) 1I 1I -// val fib : (int -> BigInteger) = - -[] -let main argv = - fac 10 |> printfn "%A" // prints 3628800 - fib 10 |> printfn "%A" // prints 55 - 0 // return an integer exit code +// Y combinator with injected laziness. GordonBGood : April 18, 2025 +type 'T Mu = { eval: 'T Mu -> 'T } +let Y f = let g = fun x -> f <| fun() -> (x.eval x) in g { eval = g } +let fibonacci n = Y (fun fn f s i -> if i >= n then f else fn () s (f + s) (i + 1)) 1I 1I 1 +let factorial n = Y (fun f p x -> if x > n then p else f () (x * p) (x + 1I)) 1I 1I +printfn "fibonacci 10 = %A\r\nfactorial 5 = %A" (fibonacci 10) (factorial 5I) +printfn "fibonacci 1000 = %A" (fibonacci 1000) diff --git a/Task/Y-combinator/F-Sharp/y-combinator-3.fs b/Task/Y-combinator/F-Sharp/y-combinator-3.fs index c9fbe39fbc..570693a413 100644 --- a/Task/Y-combinator/F-Sharp/y-combinator-3.fs +++ b/Task/Y-combinator/F-Sharp/y-combinator-3.fs @@ -1,40 +1,35 @@ -// same as previous... type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with -// same as previous... let unroll (Roll x) = x // val unroll : 'a mu -> ('a mu -> 'a) -// break race condition with some deferred execution - laziness... -let fix f = let g = fun x -> f <| fun() -> (unroll x x) in g (Roll g) -// val fix : ((unit -> 'a) -> 'a -> 'a) = +// As with most of the strict (non-deferred or non-lazy) languages, +// this is the Z-combinator with the additional 'a' parameter... +let fix f = let g = fun x a -> f (unroll x x) a in g (Roll g) +// val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = -// same efficient version of factorial functionb with added deferred execution... -let fac = fix (fun f n i -> if i < 2 then n else f () (bigint i * n) (i - 1)) <| 1I +// Although true to the factorial definition, the +// recursive call is not in tail call position, so can't be optimized +// and will overflow the call stack for the recursive calls for large ranges... +//let fac = fix (fun f n -> if n < 2 then 1I else bigint n * f (n - 1)) // val fac : (int -> BigInteger) = -// same efficient version of Fibonacci function with added deferred execution... -let fib = fix (fun fnc f s i -> if i < 2 then f else fnc () s (f + s) (i - 1)) 1I 1I +// much better progressive calculation in tail call position... +let fac = fix (fun f n i -> if i < 2 then n else f (bigint i * n) (i - 1)) <| 1I +// val fac : (int -> BigInteger) = + +// Although true to the definition of Fibonacci numbers, +// this can't be tail call optimized and recursively repeats calculations +// for a horrendously inefficient exponential performance fib function... +// let fib = fix (fun fnc n -> if n < 2 then n else fnc (n - 1) + fnc (n - 2)) // val fib : (int -> BigInteger) = -// given the following definition for an infinite Co-Inductive Stream (CIS)... -type CIS<'a> = CIS of 'a * (unit -> CIS<'a>) // ' fix formatting - -// Using a double Y-Combinator recursion... -// defines a continuous stream of Fibonacci numbers; there are other simpler ways, -// this way implements recursion by using the Y-combinator, although it is -// much slower than other ways due to the many additional function calls, -// it demonstrates something that can't be done with the Z-combinator... -let fibs() = - let fbsgen = fix (fun fnc (CIS((f, s), rest)) -> - CIS((s, f + s), fun() -> fnc () <| rest())) - Seq.unfold (fun (CIS((v, _), rest)) -> Some(v, rest())) - <| fix (fun cis -> fbsgen (CIS((1I, 0I), cis))) // cis is a lazy thunk! +// much better progressive calculation in tail call position... +let fib = fix (fun fnc f s i -> if i < 2 then f else fnc s (f + s) (i - 1)) 1I 1I +// val fib : (int -> BigInteger) = [] let main argv = fac 10 |> printfn "%A" // prints 3628800 fib 10 |> printfn "%A" // prints 55 - fibs() |> Seq.take 20 |> Seq.iter (printf "%A ") - printfn "" 0 // return an integer exit code diff --git a/Task/Y-combinator/F-Sharp/y-combinator-4.fs b/Task/Y-combinator/F-Sharp/y-combinator-4.fs index 67c1a271c4..c9fbe39fbc 100644 --- a/Task/Y-combinator/F-Sharp/y-combinator-4.fs +++ b/Task/Y-combinator/F-Sharp/y-combinator-4.fs @@ -1,4 +1,40 @@ -let rec fix f = f <| fun() -> fix f -// val fix : f:((unit -> 'a) -> 'a) -> 'a +// same as previous... +type 'a mu = Roll of ('a mu -> 'a) // ' fixes ease syntax colouring confusion with -// the application of this true Y-combinator is the same as for the above non function recursive version. +// same as previous... +let unroll (Roll x) = x +// val unroll : 'a mu -> ('a mu -> 'a) + +// break race condition with some deferred execution - laziness... +let fix f = let g = fun x -> f <| fun() -> (unroll x x) in g (Roll g) +// val fix : ((unit -> 'a) -> 'a -> 'a) = + +// same efficient version of factorial functionb with added deferred execution... +let fac = fix (fun f n i -> if i < 2 then n else f () (bigint i * n) (i - 1)) <| 1I +// val fac : (int -> BigInteger) = + +// same efficient version of Fibonacci function with added deferred execution... +let fib = fix (fun fnc f s i -> if i < 2 then f else fnc () s (f + s) (i - 1)) 1I 1I +// val fib : (int -> BigInteger) = + +// given the following definition for an infinite Co-Inductive Stream (CIS)... +type CIS<'a> = CIS of 'a * (unit -> CIS<'a>) // ' fix formatting + +// Using a double Y-Combinator recursion... +// defines a continuous stream of Fibonacci numbers; there are other simpler ways, +// this way implements recursion by using the Y-combinator, although it is +// much slower than other ways due to the many additional function calls, +// it demonstrates something that can't be done with the Z-combinator... +let fibs() = + let fbsgen = fix (fun fnc (CIS((f, s), rest)) -> + CIS((s, f + s), fun() -> fnc () <| rest())) + Seq.unfold (fun (CIS((v, _), rest)) -> Some(v, rest())) + <| fix (fun cis -> fbsgen (CIS((1I, 0I), cis))) // cis is a lazy thunk! + +[] +let main argv = + fac 10 |> printfn "%A" // prints 3628800 + fib 10 |> printfn "%A" // prints 55 + fibs() |> Seq.take 20 |> Seq.iter (printf "%A ") + printfn "" + 0 // return an integer exit code diff --git a/Task/Y-combinator/F-Sharp/y-combinator-5.fs b/Task/Y-combinator/F-Sharp/y-combinator-5.fs new file mode 100644 index 0000000000..67c1a271c4 --- /dev/null +++ b/Task/Y-combinator/F-Sharp/y-combinator-5.fs @@ -0,0 +1,4 @@ +let rec fix f = f <| fun() -> fix f +// val fix : f:((unit -> 'a) -> 'a) -> 'a + +// the application of this true Y-combinator is the same as for the above non function recursive version. diff --git a/Task/Y-combinator/J/y-combinator-1.j b/Task/Y-combinator/J/y-combinator-1.j index e6cd6b8f33..75bc19b2e8 100644 --- a/Task/Y-combinator/J/y-combinator-1.j +++ b/Task/Y-combinator/J/y-combinator-1.j @@ -1,3 +1,3 @@ - Y=. {{x&(x`:6)`'' u y}} {{u`''&u}} + Y =. {{x&(x`:6)`'' u y}} {{u`''&u}} fac=. 1:`{{(* x`:6@<:)y}}@.(0 < ]) fib=. {{(-&1 +&(x`:6) -&2)y}}^:(1 < ]) diff --git a/Task/Y-combinator/J/y-combinator-3.j b/Task/Y-combinator/J/y-combinator-3.j index 43c4ff31b2..5a2752f4e4 100644 --- a/Task/Y-combinator/J/y-combinator-3.j +++ b/Task/Y-combinator/J/y-combinator-3.j @@ -1,4 +1,4 @@ - Y=. ]:&>/]:^:_1 b.]:`(<'0';_1)`:6&([ 128!:2 ,&<) - sr=. [ apply f. ,&< NB. Self referring + Y =. ]:&>/]:^:_1 b.]:`(<'0';_1)`:6&([ 128!:2 ,&<) + sr =. [ apply f. ,&< NB. Self referring fac=. 1:`(] * [ sr ] - 1:)@.(0 < ]) fib=. (([ sr ] - 2:) + [ sr ] - 1:)^:(1 < ]) diff --git a/Task/Y-combinator/J/y-combinator-6.j b/Task/Y-combinator/J/y-combinator-6.j index bcbaa5edea..760d8d8a98 100644 --- a/Task/Y-combinator/J/y-combinator-6.j +++ b/Task/Y-combinator/J/y-combinator-6.j @@ -1,6 +1,6 @@ sr=. [ apply f. ,&< NB. Self referring lv=. ]:^:_1 b.]:`(<'0';_1)`:6 NB. Linear representation of a verb operand - Y=. ]:&>/lv&sr NB. Y with embedded states - Y=. 'Y' f. NB. Fixing it... + Y =. ]:&>/lv&sr NB. Y with embedded states + Y =. 'Y' f. NB. Fixing it... Y NB. ... To make it stateless (i.e., a combinator) ((]: & >) / ((((]: ^: (_1)) b. ]:) ` (<'0';_1)) `: 6)) & ([ 128!:2 ,&<) diff --git a/Task/Y-combinator/Zig/y-combinator.zig b/Task/Y-combinator/Zig/y-combinator.zig new file mode 100644 index 0000000000..3a6cf9927b --- /dev/null +++ b/Task/Y-combinator/Zig/y-combinator.zig @@ -0,0 +1,71 @@ +//! A simple implementation of the Y Combinator: +//! λf.(λx.xx)(λx.f(xx)) +//! <=> λf.(λx.f(xx))(λx.f(xx)) + +const std = @import("std"); +const debug = std.debug; +const mem = std.mem; +const Allocator = mem.Allocator; + +// In Zig we can use function pointers and closures +// to implement the Y combinator without needing traits + +// Generic Y combinator implementation +fn Y(comptime T: type, comptime R: type, f: fn (fn (T) R, T) R) fn (T) R { + const Closure = struct { + fn call(t: T) R { + const applySelf = struct { + fn apply(x: fn (fn (T) R, T) R, y: T) R { + const innerApply = struct { + fn inner(z: T) R { + return apply(x, z); + } + }.inner; + return x(innerApply, y); + } + }.apply; + return applySelf(f, t); + } + }; + return Closure.call; +} + +// Factorial function using Y combinator +fn fac(n: usize) usize { + const almostFac = struct { + fn call(f: fn (usize) usize, x: usize) usize { + if (x == 0) return 1 else return x * f(x - 1); + } + }.call; + + return Y(usize, usize, almostFac)(n); +} + +// Fibonacci function using Y combinator +fn fib(n: usize) usize { + const FibTuple = struct { a0: usize, a1: usize, x: usize }; + + const almostFib = struct { + fn call(f: fn (FibTuple) usize, tuple: FibTuple) usize { + const a0 = tuple.a0; + const a1 = tuple.a1; + const x = tuple.x; + + return switch (x) { + 0 => a0, + 1 => a1, + else => f(.{ .a0 = a1, .a1 = a0 + a1, .x = x - 1 }), + }; + } + }.call; + + return Y(FibTuple, usize, almostFib)(.{ .a0 = 1, .a1 = 1, .x = n }); +} + +// Driver function +pub fn main() !void { + const n: usize = 10; + const stdout = std.io.getStdOut().writer(); + try stdout.print("fac({}) = {}\n", .{ n, fac(n) }); + try stdout.print("fib({}) = {}\n", .{ n, fib(n) }); +} diff --git a/Task/Yellowstone-sequence/EasyLang/yellowstone-sequence.easy b/Task/Yellowstone-sequence/EasyLang/yellowstone-sequence.easy index e980cb39de..cc912716ce 100644 --- a/Task/Yellowstone-sequence/EasyLang/yellowstone-sequence.easy +++ b/Task/Yellowstone-sequence/EasyLang/yellowstone-sequence.easy @@ -1,16 +1,12 @@ func gcd a b . - if b = 0 - return a - . + if b = 0 : return a return gcd b (a mod b) . -proc remove_at i . a[] . - for j = i + 1 to len a[] - a[j - 1] = a[j] - . +proc remove_at i &a[] . + for j = i + 1 to len a[] : a[j - 1] = a[j] len a[] -1 . -proc yellowstone count . yellow[] . +proc yellowstone count &yellow[] . yellow[] = [ 1 2 3 ] num = 4 while len yellow[] < count @@ -18,9 +14,7 @@ proc yellowstone count . yellow[] . yell2 = yellow[len yellow[]] for i to len notyellow[] test = notyellow[i] - if gcd yell1 test > 1 and gcd yell2 test = 1 - break 1 - . + if gcd yell1 test > 1 and gcd yell2 test = 1 : break 1 . if i <= len notyellow[] yellow[] &= notyellow[i] diff --git a/Task/Yellowstone-sequence/REXX/yellowstone-sequence-1.rexx b/Task/Yellowstone-sequence/REXX/yellowstone-sequence-1.rexx deleted file mode 100644 index be0c9c0fce..0000000000 --- a/Task/Yellowstone-sequence/REXX/yellowstone-sequence-1.rexx +++ /dev/null @@ -1,20 +0,0 @@ -/*REXX program calculates any number of terms in the Yellowstone (permutation) sequence.*/ -parse arg m . /*obtain optional argument from the CL.*/ -if m=='' | m=="," then m= 30 /*Not specified? Then use the default.*/ -!.= 0 /*initialize an array of numbers(used).*/ -# = 0 /*count of Yellowstone numbers in seq. */ -$= /*list " " " " " */ - do j=1 until #==m; prev= # - 1 - if j<5 then do; #= #+1; @.#= j; !.#= j; !.j= 1; $= strip($ j); iterate; end - - do k=1; if !.k then iterate /*Already used? Then skip this number.*/ - if gcd(k, @.prev)<2 then iterate /*Not meet requirement? Then skip it. */ - if gcd(k, @.#) \==1 then iterate /* " " " " " " */ - #= #+1; @.#= k; !.k= 1; $= $ k /*bump ctr; assign; mark used; add list*/ - leave /*find the next Yellowstone seq. number*/ - end /*k*/ - end /*j*/ -say $ /*display a list of a Yellowstone seq. */ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -gcd: parse arg x,y; do until y==0; parse value x//y y with y x; end; return x diff --git a/Task/Yellowstone-sequence/REXX/yellowstone-sequence-2.rexx b/Task/Yellowstone-sequence/REXX/yellowstone-sequence-2.rexx deleted file mode 100644 index 549ae130a1..0000000000 --- a/Task/Yellowstone-sequence/REXX/yellowstone-sequence-2.rexx +++ /dev/null @@ -1,21 +0,0 @@ -/*REXX program calculates any number of terms in the Yellowstone (permutation) sequence.*/ -parse arg m . /*obtain optional argument from the CL.*/ -if m=='' | m=="," then m= 30 /*Not specified? Then use the default.*/ -!.= 0 /*initialize an array of numbers(used).*/ -# = 0 /*count of Yellowstone numbers in seq. */ -$ = /*list " " " " " */ - do j=1 until #==m; prev= # - 1 - if j<5 then do; #= #+1; @.#= j; !.#= j; !.j= 1; $= strip($ j); iterate; end - - do k=1; if !.k then iterate /*Already used? Then skip this number.*/ - if gcd(k, @.prev)<2 then iterate /*Not meet requirement? Then skip it. */ - if gcd(k, @.#) \==1 then iterate /* " " " " " " */ - #= # + 1; @.#= k; !.k= 1; $= $ k /*bump ctr; assign; mark used; add list*/ - leave /*find the next Yellowstone seq. number*/ - end /*k*/ - end /*j*/ - -call $histo $ '(vertical)' /*invoke a REXX vertical histogram plot*/ -exit /*stick a fork in it, we're all done. */ -/*──────────────────────────────────────────────────────────────────────────────────────*/ -gcd: parse arg x,y; do until y==0; parse value x//y y with y x; end; return x diff --git a/Task/Yellowstone-sequence/REXX/yellowstone-sequence.rexx b/Task/Yellowstone-sequence/REXX/yellowstone-sequence.rexx new file mode 100644 index 0000000000..de391c503f --- /dev/null +++ b/Task/Yellowstone-sequence/REXX/yellowstone-sequence.rexx @@ -0,0 +1,56 @@ +-- 25 Apr 2025 +include Settings +numeric digits 100 +arg xx +if xx = '' then + xx = 30 + +say 'YELLOWSTONE SEQUENCE' +say version +say +call GetYellow xx +call DisplayList xx +call Timer +exit + +GetYellow: +procedure expose yell. work. +arg xx +say 'Get yellowstones...' +yell. = 0; work. = 0; n = 0 +do i = 1 until n = xx + p = n-1 + if i < 5 then do + n = n+1; yell.n = i; work.n = i; work.i = 1 + iterate i + end + do j = 1 + if work.j then + iterate j + if Gcd(j,yell.p) = 1 then + iterate j + if Gcd(j,yell.n) <> 1 then + iterate j + n = n+1; yell.n = j; work.j = 1 + leave j + end +end +say +return xx + +DisplayList: +procedure expose yell. +arg xx +say 'Yellowstone sequence...' +do i = 1 to xx + call Charout ,Right(yell.i,5) + if i//10 = 0 then + say +end +say +return + +include Sequences +include Functions +include Helper +include Abend diff --git a/Task/Yin-and-yang/EasyLang/yin-and-yang.easy b/Task/Yin-and-yang/EasyLang/yin-and-yang.easy index 38961146b9..653cd6fb44 100644 --- a/Task/Yin-and-yang/EasyLang/yin-and-yang.easy +++ b/Task/Yin-and-yang/EasyLang/yin-and-yang.easy @@ -1,20 +1,17 @@ -proc circ r c . . - color c - circle r +proc circ x y r c . + gcolor c + gcircle x y r . -proc yinyang x y r . . - move x y - circ 2 * r 000 - color 999 - circseg 2 * r 90 -90 - move x y - r - circ r 000 - circ r / 3 999 - move x y + r - circ r 999 - circ r / 3 000 +proc yinyang x y r . + circ x y 2 * r 000 + gcolor 999 + gcircseg x y 2 * r 90 -90 + circ x y - r r 000 + circ x y - r r / 3 999 + circ x y + r r 999 + circ x y + r r / 3 000 . -background 555 -clear +gbackground 555 +gclear yinyang 20 20 6 yinyang 50 60 14 diff --git a/Task/Zebra-puzzle/J/zebra-puzzle-1.j b/Task/Zebra-puzzle/J/zebra-puzzle-1.j index cfff37de00..b34c7f5f07 100644 --- a/Task/Zebra-puzzle/J/zebra-puzzle-1.j +++ b/Task/Zebra-puzzle/J/zebra-puzzle-1.j @@ -2,13 +2,23 @@ in=: {{n&{ i. m"_}} NB. index of m in row n of matrix F =: {{u"_1 # ]}} NB. filter by function of items 'Col Nat Pet Drink Cig'=: i.5 NB. refer to rows by name 'col nat pet drink cig'=: (A.~i.@!@#)&>;:'BGRWY DEGNS BCDHZ BCMTW BbDpP' NB. perm matrices -P=: ('W' in Col (= >:) 'G' in Col)F ,/col,:"1/nat NB. join first two mats and add 1st constraint -P=: ,/pet,"2 1/~ (('E' in Nat = 'R' in Col)*.(0 = 'N' in Nat))F P NB. and so on... -P=: ,/drink,"2 1/~ (('D' in Pet = 'S' in Nat)*.('N' in Nat (1=|@:-) 'B' in Col))F P -P=: (('C' in Drink = 'G' in Col)*.(2 = 'M' in Drink))F P -P=: (('T' in Drink = 'D' in Nat)*.('p' in Cig = 'B' in Pet))F ,/P,"2 1/cig -P=: (('D' in Cig = 'Y' in Col)*.('b' in Cig = 'B' in Drink))F P -P=: (('P' in Cig = 'G' in Nat)*.('B' in Cig (1=|@:-) 'C' in Pet))F P -P=: (('D' in Cig (1=|@:-) 'H' in Pet)*.('B' in Cig (1=|@:-) 'W' in Drink))F P -echo 'Solutions found: ',(":#P),LF,LF,~' owns the Z',~('Z' in Pet { Nat&{){.P -echo 'Col Nat Pet Drink Cig', ([,(6#' '),])/"1|:{.P +P=: ,/col,:"1/nat NB. join color and nationality matrices +P=: ('W' in Col = 1+ 'G' in Col)F P NB. white right of green +P=: (0 = 'N' in Nat)F P NB. Norwegian in first house +P=: ,/pet,"2 1/~ ('E' in Nat = 'R' in Col)F P NB. red = English; add pets +P=: ('N' in Nat (1=|@-) 'B' in Col)F P NB. blue next to Norwegian +P=: ,/drink,"2 1/~ ('D' in Pet = 'S' in Nat)F P NB. Swede owns dog; add drinks +P=: (2 = 'M' in Drink)F P NB. middle house drinks milk +P=: ('T' in Drink = 'D' in Nat)F P NB. Dane drinks tea +P=: ('C' in Drink = 'G' in Col)F P NB. green = coffee +P=: ('p' in Cig = 'B' in Pet)F ,/P,"2 1/cig NB. add cigs; PallMall = birds +P=: ('D' in Cig = 'Y' in Col)F P NB. Dunhill = yellow +P=: ('b' in Cig = 'B' in Drink)F P NB. BlueM = beer +P=: ('P' in Cig = 'G' in Nat)F P NB. Prince = German +P=: ('B' in Cig (1=|@-) 'C' in Pet)F P NB. cat next to Blend +P=: ('D' in Cig (1=|@-) 'H' in Pet)F P NB. horse next to Dunhill +P=: ('B' in Cig (1=|@-) 'W' in Drink)F P NB. water next to Blend +echo 'Solutions found: ',":#P +echo (('Z' in Pet { Nat&{){.P),' owns the Z' +echo 'Col Nat Pet Drink Cig' +echo ([,(6#' '),])/"1|:{.P diff --git a/Task/Zebra-puzzle/JavaScript/zebra-puzzle.js b/Task/Zebra-puzzle/JavaScript/zebra-puzzle.js new file mode 100644 index 0000000000..ccb11f817e --- /dev/null +++ b/Task/Zebra-puzzle/JavaScript/zebra-puzzle.js @@ -0,0 +1,163 @@ +// Define enums and their string representations +const Attrib = { Color: 0, Man: 1, Drink: 2, Animal: 3, Smoke: 4 }; +const Attrib_str = ["Color", "Man", "Drink", "Animal", "Smoke"]; + +const Colors = { Red: 0, Green: 1, White: 2, Yellow: 3, Blue: 4 }; +const Colors_str = ["Red", "Green", "White", "Yellow", "Blue"]; + +const Mans = { English: 0, Swede: 1, Dane: 2, German: 3, Norwegian: 4 }; +const Mans_str = ["English", "Swede", "Dane", "German", "Norwegian"]; + +const Drinks = { Tea: 0, Coffee: 1, Milk: 2, Beer: 3, Water: 4 }; +const Drinks_str = ["Tea", "Coffee", "Milk", "Beer", "Water"]; + +const Animals = { Dog: 0, Birds: 1, Cats: 2, Horse: 3, Zebra: 4 }; +const Animals_str = ["Dog", "Birds", "Cats", "Horse", "Zebra"]; + +const Smokes = { PallMall: 0, Dunhill: 1, Blend: 2, BlueMaster: 3, Prince: 4 }; +const Smokes_str = ["PallMall", "Dunhill", "Blend", "BlueMaster", "Prince"]; + +function printHouses(ha) { + const attr_names = [Colors_str, Mans_str, Drinks_str, Animals_str, Smokes_str]; + + let output = "House".padEnd(10); + for (const name of Attrib_str) { + output += name.padEnd(10); + } + console.log(output); + + for (let i = 0; i < 5; i++) { + output = String(i).padEnd(10); + for (let j = 0; j < 5; j++) { + output += attr_names[j][ha[i][j]].padEnd(10); + } + console.log(output); + } +} + +// House number specific rules +const housenos = [ + { houseno: 2, a: Attrib.Drink, v: Drinks.Milk }, // Cond 9: In the middle house they drink milk. + { houseno: 0, a: Attrib.Man, v: Mans.Norwegian } // Cond 10: The Norwegian lives in the first house. +]; + +// Attribute pair rules +const pairs = [ + { a1: Attrib.Man, v1: Mans.English, a2: Attrib.Color, v2: Colors.Red }, // Cond 2: The English man lives in the red house. + { a1: Attrib.Man, v1: Mans.Swede, a2: Attrib.Animal, v2: Animals.Dog }, // Cond 3: The Swede has a dog. + { a1: Attrib.Man, v1: Mans.Dane, a2: Attrib.Drink, v2: Drinks.Tea }, // Cond 4: The Dane drinks tea. + { a1: Attrib.Color, v1: Colors.Green, a2: Attrib.Drink, v2: Drinks.Coffee }, // Cond 6: drink coffee in the green house. + { a1: Attrib.Smoke, v1: Smokes.PallMall, a2: Attrib.Animal, v2: Animals.Birds }, // Cond 7: The man who smokes Pall Mall has birds. + { a1: Attrib.Smoke, v1: Smokes.Dunhill, a2: Attrib.Color, v2: Colors.Yellow }, // Cond 8: In the yellow house they smoke Dunhill. + { a1: Attrib.Smoke, v1: Smokes.BlueMaster, a2: Attrib.Drink, v2: Drinks.Beer }, // Cond 13: The man who smokes Blue Master drinks beer. + { a1: Attrib.Man, v1: Mans.German, a2: Attrib.Smoke, v2: Smokes.Prince } // Cond 14: The German smokes Prince +]; + +// Next to rules +const nexttos = [ + { a1: Attrib.Smoke, v1: Smokes.Blend, a2: Attrib.Animal, v2: Animals.Cats }, // Cond 11: The man who smokes Blend lives in the house next to the house with cats. + { a1: Attrib.Smoke, v1: Smokes.Dunhill, a2: Attrib.Animal, v2: Animals.Horse }, // Cond 12: In a house next to the house where they have a horse, they smoke Dunhill. + { a1: Attrib.Man, v1: Mans.Norwegian, a2: Attrib.Color, v2: Colors.Blue }, // Cond 15: The Norwegian lives next to the blue house. + { a1: Attrib.Smoke, v1: Smokes.Blend, a2: Attrib.Drink, v2: Drinks.Water } // Cond 16: They drink water in a house next to the house where they smoke Blend. +]; + +// Left of rules +const leftofs = [ + { a1: Attrib.Color, v1: Colors.Green, a2: Attrib.Color, v2: Colors.White } // Cond 5: The green house is immediately to the left of the white house. +]; + +function invalid(ha) { + // Check leftofs global rules + for (const rule of leftofs) { + if (ha[0][rule.a2] === rule.v2 || ha[4][rule.a1] === rule.v1) { + return true; + } + } + + // Check rules for each house + for (let i = 0; i < 5; i++) { + // Check pair rules + for (const rule of pairs) { + if (ha[i][rule.a1] >= 0 && ha[i][rule.a2] >= 0 && + ((ha[i][rule.a1] === rule.v1 && ha[i][rule.a2] !== rule.v2) || + (ha[i][rule.a1] !== rule.v1 && ha[i][rule.a2] === rule.v2))) { + return true; + } + } + + // Check next to rules + for (const rule of nexttos) { + if (ha[i][rule.a1] === rule.v1) { + if (i === 0 && ha[i + 1][rule.a2] >= 0 && ha[i + 1][rule.a2] !== rule.v2) { + return true; + } else if (i === 4 && ha[i - 1][rule.a2] !== rule.v2) { + return true; + } else if (i > 0 && i < 4 && + ha[i + 1][rule.a2] >= 0 && ha[i + 1][rule.a2] !== rule.v2 && + ha[i - 1][rule.a2] !== rule.v2) { + return true; + } + } + } + + // Check left of rules for this house + for (const rule of leftofs) { + if (i > 0 && ha[i][rule.a1] >= 0 && + ((ha[i - 1][rule.a1] === rule.v1 && ha[i][rule.a2] !== rule.v2) || + (ha[i - 1][rule.a1] !== rule.v1 && ha[i][rule.a2] === rule.v2))) { + return true; + } + } + } + return false; +} + +function search(used, ha, hno, attr) { + let nexthno, nextattr; + if (attr < 4) { + nextattr = attr + 1; + nexthno = hno; + } else { + nextattr = 0; + nexthno = hno + 1; + } + + if (ha[hno][attr] !== -1) { + search(used, ha, nexthno, nextattr); + } else { + for (let i = 0; i < 5; i++) { + if (used[attr][i]) continue; + used[attr][i] = true; + ha[hno][attr] = i; + + if (!invalid(ha)) { + if (hno === 4 && attr === 4) { + printHouses(ha); + } else { + search(used, ha, nexthno, nextattr); + } + } + + used[attr][i] = false; + ha[hno][attr] = -1; + } + } +} + +function main() { + // Initialize arrays + const used = Array(5).fill().map(() => Array(5).fill(false)); + const ha = Array(5).fill().map(() => Array(5).fill(-1)); + + // Apply house number specific rules + for (const rule of housenos) { + ha[rule.houseno][rule.a] = rule.v; + used[rule.a][rule.v] = true; + } + + // Start the search + search(used, ha, 0, 0); +} + +// Run the program +main(); diff --git a/Task/Zeckendorf-number-representation/EasyLang/zeckendorf-number-representation.easy b/Task/Zeckendorf-number-representation/EasyLang/zeckendorf-number-representation.easy index ed432b91e5..9d72b24831 100644 --- a/Task/Zeckendorf-number-representation/EasyLang/zeckendorf-number-representation.easy +++ b/Task/Zeckendorf-number-representation/EasyLang/zeckendorf-number-representation.easy @@ -1,4 +1,4 @@ -proc mkfibs n . fib[] . +proc mkfibs n &fib[] . fib[] = [ ] last = 1 current = 1 @@ -19,9 +19,7 @@ func$ zeckendorf n . zeck$ &= "0" . . - if zeck$ = "" - return "0" - . + if zeck$ = "" : return "0" return zeck$ . for n = 0 to 20 diff --git a/Task/Zig-zag-matrix/EasyLang/zig-zag-matrix.easy b/Task/Zig-zag-matrix/EasyLang/zig-zag-matrix.easy index 4eb3a10029..0db56b35a7 100644 --- a/Task/Zig-zag-matrix/EasyLang/zig-zag-matrix.easy +++ b/Task/Zig-zag-matrix/EasyLang/zig-zag-matrix.easy @@ -22,7 +22,7 @@ func coord2num row col n . return start + offs . n = 6 -numfmt 0 3 +numfmt 3 0 for row = 0 to n - 1 for col = 0 to n - 1 write coord2num row col n diff --git a/Task/Zig-zag-matrix/Uiua/zig-zag-matrix.uiua b/Task/Zig-zag-matrix/Uiua/zig-zag-matrix.uiua new file mode 100644 index 0000000000..979e08e630 --- /dev/null +++ b/Task/Zig-zag-matrix/Uiua/zig-zag-matrix.uiua @@ -0,0 +1,7 @@ +ZigZag ← ( + ↘₁⇡⊸×₂ + ⊃(⋅⟜⇡|↧₀-|◿₂|+⊃⍚⇡(\+⊂₀↘₋₁)↧⇌.) + ≡↙⊙(≡↻|⍉≡↻|⬚∞≡◇∘⍥⇌) +) + +ZigZag 5 diff --git a/Task/Zumkeller-numbers/EasyLang/zumkeller-numbers.easy b/Task/Zumkeller-numbers/EasyLang/zumkeller-numbers.easy index 350228b3f3..3e1093d7d1 100644 --- a/Task/Zumkeller-numbers/EasyLang/zumkeller-numbers.easy +++ b/Task/Zumkeller-numbers/EasyLang/zumkeller-numbers.easy @@ -1,40 +1,26 @@ -proc divisors n . divs[] . +proc divisors n &divs[] . divs[] = [ 1 n ] for i = 2 to sqrt n if n mod i = 0 j = n / i divs[] &= i - if i <> j - divs[] &= j - . + if i <> j : divs[] &= j . . . func ispartsum divs[] sum . - if sum = 0 - return 1 - . - if len divs[] = 0 - return 0 - . + if sum = 0 : return 1 + if len divs[] = 0 : return 0 last = divs[len divs[]] len divs[] -1 - if last > sum - return ispartsum divs[] sum - . - if ispartsum divs[] sum = 1 - return 1 - . + if last > sum : return ispartsum divs[] sum + if ispartsum divs[] sum = 1 : return 1 return ispartsum divs[] (sum - last) . func iszumkeller n . divisors n divs[] - for v in divs[] - sum += v - . - if sum mod 2 = 1 - return 0 - . + for v in divs[] : sum += v + if sum mod 2 = 1 : return 0 if n mod 2 = 1 abund = sum - 2 * n return if abund > 0 and abund mod 2 = 0