• MPRCLOBTLB - Make Personal Rosetta Code Like Org Babel Texts Less Boring

    From yeti@yeti@tilde.institute to tilde.institute on Sun Mar 3 18:36:01 2024
    --=-=-=
    Content-Type: text/plain

    I think I found a solution to make repeatedly occurring code snippets'
    output less annoying by automagically checking them against the expected output.

    Sample UTF8 output of such a text with code snippets: ------------------------------------------------------------------------

    --=-=-=
    Content-Type: text/plain; charset=utf-8
    Content-Disposition: inline
    Content-Transfer-Encoding: 8bit

    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    COMPARING DEMO CODE SNIPPETS' RESULTS

    Not Really An Unnamed Elisp Toddler
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


    Table of Contents
    ─────────────────

    1. What and why?
    2. A Task Description With Expected Output
    3. An Implementation
    4. An Other Implementation
    5. Famous Last Words
    6. Happy(?) End.





    1 What and why?
    ═══════════════

    Imagine lots of my org notes as little Rosetta-Code alike collections
    of code snippets for one task in several languages.

    There is something to do and typically all of them should generate the
    same output, so I don't want that output below each snippet, but still
    have an automagic test for it being the expected result.


    2 A Task Description With Expected Output ═════════════════════════════════════════

    Task description and (fake) reference example output without published
    code.

    ┌────
    │ 2
    │ 6
    │ 30
    │ 210
    └────


    3 An Implementation
    ═══════════════════

    Fake "correct" example exporting code only:

    ┌────
    │ printf '%s\n' 2 6 30 210
    └────

    ┌────
    │ The results are identical to the expected output.
    └────


    4 An Other Implementation ═════════════════════════

    Fake "buggy" example exporting code only:

    ┌────
    │ printf '%s\n' 2 6 30 210 210210
    └────

    ┌────
    │ /!\ The results do not match the expected output.
    └────


    5 Famous Last Words
    ═══════════════════

    I think the check can be attached to the example code block as
    postprocessing function, but I'll play with more automagisms later.


    6 Happy(?) End.
    ═══════════════

    …for now.

    --=-=-=
    Content-Type: text/plain

    ------------------------------------------------------------------------

    The Org source of it: ------------------------------------------------------------------------

    --=-=-=
    Content-Type: text/x-org
    Content-Disposition: inline

    #+title: Comparing Demo Code Snippets' results
    #+author: Not Really An Unnamed Elisp Toddler

    * What and why?
    :PROPERTIES:
    :ID: c265fa90-cb89-46f9-b308-493aab52cccd
    :END:

    Imagine lots of my org notes as little Rosetta-Code alike collections of
    code snippets for one task in several languages.

    There is something to do and typically all of them should generate the
    same output, so I don't want that output below each snippet, but still
    have an automagic test for it being the expected result.


    * The Helper Function :noexport: :PROPERTIES:
    :ID: 1cac6b80-e6ac-4170-a965-9196e7d6029f
    :END:

    #+name: results-equal
    #+begin_src elisp :results output :exports none :var ok="" check="" :cache yes :eval never-export
    (if (string-equal ok check)
    (princ "The results are identical to the expected output.")
    (princ "/!\\ The results do not match the expected output."))
    #+end_src


    * A Task Description With Expected Output
    :PROPERTIES:
    :ID: c5ee4e87-9d8d-4a5b-ade8-067f5f0bb636
    :END:

    Task description and (fake) reference example output without published
    code.

    #+name: expected-result
    #+begin_src sh :results output :exports results :cache yes :eval never-export printf '%s\n' 2 6 30 210
    #+end_src

    #+RESULTS[10aa19a40b920cecfaae760a321d00fb673eaa87]: expected-result
    : 2
    : 6
    : 30
    : 210


    * An Implementation
    :PROPERTIES:
    :ID: 37ff69a3-6042-4303-b4fb-d35d93a71c55
    :END:

    Fake "correct" example exporting code only:

    #+name: candidate1
    #+begin_src sh :results output :exports code :cache yes :eval never-export printf '%s\n' 2 6 30 210
    #+end_src

    #+RESULTS[c7cb5e6b1e51294f0b6c816d462c099fecce4c25]: candidate1
    : 2
    : 6
    : 30
    : 210

    #+call: results-equal(ok=expected-result,check=candidate1)

    #+RESULTS[eecafe18fa130771ebc6c2f8442a66e0f13707da]:
    : The results are identical to the expected output.


    * An Other Implementation
    :PROPERTIES:
    :ID: ee1a8d84-2941-45ca-9699-2625aeb3a9e3
    :END:

    Fake "buggy" example exporting code only:

    #+name: candidate2
    #+begin_src sh :results output :exports code :cache yes :eval never-export printf '%s\n' 2 6 30 210 210210
    #+end_src

    #+RESULTS[d69e51c8aa25b238802dea59ba964e9be0714626]: candidate2
    : 2
    : 6
    : 30
    : 210
    : 210210

    #+call: results-equal(ok=expected-result,check=candidate2)

    #+RESULTS[ffe5d4054ba6ddfb56b3d463f78e939026df5abb]:
    : /!\ The results do not match the expected output.

    * Famous Last Words
    :PROPERTIES:
    :ID: db9fcac2-6a4b-4890-a3cc-5f4cc5d77990
    :END:

    I think the check can be attached to the example code block as
    postprocessing function, but I'll play with more automagisms later.

    * Happy(?) End.
    :PROPERTIES:
    :ID: bf3e3940-91fc-4113-8eb6-ba29f80866d6
    :END:

    ...for now.

    --=-=-=
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit

    ------------------------------------------------------------------------
    -- ⢀⣶⡀⠀⠀⢀⣶⡀⠀⠀⢀⣶⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⣤⣤⣤⣤⣤⣤⣤⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣶⡀⠀⠀⢀⣶⡀⠀⠀⢀⣶⡀
    ⢸⣿⡇⠀⠀⢸⣿⡇⠀⠀⢸⣿⡇⠀⠀⠶⠶⠶⠶⠶⣶⠶⠶⣿⠀⠀⠀⠀⠀⠀⠀⣿⠶⠶⣶⠶⠶⠶⠶⠶⠀⠀⠀⢸⣿⡇⠀⠀⢸⣿⡇⠀⠀⢸⣿⡇
    ⠈⠿⠁⠀⠀⠈⠿⠁⠀⠀⠈⠿⠁⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠛⠛⠛⠛⠛⠛⠛⠛⠛⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠈⠿⠁⠀⠀⠈⠿⠁⠀⠀⠈⠿⠁
    ⠀⠶⠀⠀⠀⠀⠶⠀⠀⠀⠀⠶⠀⠀⠀⠀⠀⠀⠀⠀⠿⠶⠶⠶⠶⠶⠶⠶⠶⠶⠶⠶⠶⠶⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠶⠀⠀⠀⠀⠶⠀⠀⠀⠀⠶

    --=-=-=--
    --- Synchronet 3.19a-Linux NewsLink 1.113
  • From yeti@yeti@tilde.institute to tilde.institute on Sun Mar 3 23:56:57 2024
    --=-=-=
    Content-Type: text/plain

    Reboot...

    ------------------------------------------------------------------------


    --=-=-=
    Content-Type: text/plain; charset=utf-8
    Content-Disposition: inline
    Content-Transfer-Encoding: 8bit

    ━━━━━━━━━━━━━━━━━━━━
    KNOTS IN DA BRAINZ

    Wasn't Me, Mom!!!
    ━━━━━━━━━━━━━━━━━━━━


    Table of Contents
    ─────────────────

    1. Reference Result
    2. One Example
    3. Other Example
    4. Last Cry





    1 Reference Result
    ══════════════════

    ┌────
    │ 2
    │ 6
    │ 30
    │ 210
    └────


    2 One Example
    ═════════════

    ┌────
    │ printf '%s\n' 2 6 30 210
    └────

    ┌────
    │ The results are identical to the expected output.
    └────


    3 Other Example
    ═══════════════

    ┌────
    │ printf '%s\n' 2 6 30 210 210210
    └────

    ┌────
    │ /!\ The results do not match the expected output.
    └────


    4 Last Cry
    ══════════

    Now my brains hurt. Too many knobs and options and whatsoevers…

    --=-=-=
    Content-Type: text/plain


    ------------------------------------------------------------------------


    --=-=-=
    Content-Type: text/x-org
    Content-Disposition: inline

    #+title: Knots In Da Brainz
    #+author: Wasn't Me, Mom!!!


    * Helper :noexport: :PROPERTIES:
    :ID: d5371c7f-bc51-478d-b008-c1ca89178990
    :END:

    #+name: result-equal
    #+begin_src elisp :results output :exports none :var a="" b="" :eval always
    (if (string-equal a b)
    (princ "The results are identical to the expected output.")
    (princ "/!\\ The results do not match the expected output."))
    #+end_src


    * Reference Result
    :PROPERTIES:
    :ID: bd76d324-cbd7-4020-842b-d6b96605109c
    :END:

    #+name: ref
    #+begin_src sh :results output :exports results :eval never-export
    printf '%s\n' 2 6 30 210
    #+end_src

    #+RESULTS: ref
    : 2
    : 6
    : 30
    : 210


    * One Example
    :PROPERTIES:
    :ID: 4fd618ad-e6d6-47d8-b9e9-5a04f5ac66f4
    :END:

    #+name: example
    #+begin_src sh :results output :post result-equal(a=ref, b=*this*) :exports both :eval no-export
    printf '%s\n' 2 6 30 210
    #+end_src

    #+RESULTS[25cbddbb12cb606415b4bfde232a19c0c7e43c3d]: example
    : The results are identical to the expected output.


    * Other Example
    :PROPERTIES:
    :ID: 01855a80-d038-4c70-96e7-b5b8bcd7b2d8
    :END:

    #+name: other
    #+begin_src sh :results output :post result-equal(a=ref, b=*this*) :exports both :eval no-export
    printf '%s\n' 2 6 30 210 210210
    #+end_src

    #+RESULTS: other
    : /!\ The results do not match the expected output.


    * Last Cry
    :PROPERTIES:
    :ID: bbabb4de-7522-4038-9c90-67ca7e71bfd0
    :END:

    Now my brains hurt.
    Too many knobs and options and whatsoevers...

    --=-=-=
    Content-Type: text/plain; charset=utf-8
    Content-Transfer-Encoding: 8bit
    --
    ⠀⠀⠀⠀⠀⠀⠀( Play pew-pew? )
    ⠀⠀⠀⠀⠀⠀⠀/
    ⠀⠀⢀⡧⣤⢼⡀
    ⠀⠀⠏⢟⠛⡻⠹

    --=-=-=--
    --- Synchronet 3.19a-Linux NewsLink 1.113
  • From yeti@yeti@tilde.institute to tilde.institute on Mon Mar 4 14:44:48 2024
    --=-=-=
    Content-Type: text/plain

    Now the important things first: The Org source...

    ------------------------------------------------------------------------

    --=-=-=
    Content-Type: text/x-org
    Content-Disposition: inline

    #+title: Knots In Da Brainz
    #+subtitle: Now With More Ecamples
    #+author: Wasn't Me, Mom!!!

    #+options: tags:nil

    * Helper :noexport: :PROPERTIES:
    :ID: 4f1aaf59-84c3-4285-8f28-96db3f7e3b4c
    :END:

    #+name: result-equal
    #+begin_src elisp :results output :exports none :var a="" b="" :eval always
    (if (string-equal a b)
    (princ "The results are identical to the expected output.")
    (princ "/!\\ The results do not match the expected output."))
    #+end_src

    * Task :resourceless: :PROPERTIES:
    :ID: a2843421-4100-42f9-905f-62ea63c0c240
    :END:

    Calculate the n-th Primorial in a Way using the known ones as jump bar.

    The Primorial is product of numbers like a Factorial, but only
    using primes.

    Hint: ~GCD(Primorial,Prime) == 1~ for primes not yet multiplied into the
    used ~Primorial~.

    ** Reference Result :resourceless: :PROPERTIES:
    :ID: 925e6e6f-83ae-4770-bf0d-2e45a06ef4b4
    :END:

    #+name: ref
    #+begin_src sh :results output :exports results :eval never-export
    cat<<-dog
    2 2
    3 6
    5 30
    7 210
    11 2310
    13 30030
    17 510510
    19 9699690
    23 223092870
    29 6469693230
    31 200560490130
    37 7420738134810
    41 304250263527210
    dog
    #+end_src

    #+RESULTS: ref
    #+begin_example
    2 2
    3 6
    5 30
    7 210
    11 2310
    13 30030
    17 510510
    19 9699690
    23 223092870
    29 6469693230
    31 200560490130
    37 7420738134810
    41 304250263527210
    #+end_example

    * Implementations :resourceless: :PROPERTIES:
    :ID: 96eb2cf0-cbb2-4a6c-a6d4-a95050882b70
    :END:

    ** C :resourceless: :PROPERTIES:
    :ID: 6d031aa9-8f6f-4f47-9725-0474c3733a05
    :END:

    This was verified to compile with GCC an TinyCC.

    #+name: Primes via Primorial (C)
    #+header: :shebang #!/opt/tcc/bin/tcc -run -lgmp
    #+header: :results output :exports both :eval no-export
    #+header: :post result-equal(a=ref, b=*this*)
    #+begin_src sh
    #include <stdio.h>
    #include <gmp.h>

    int main(int argc, char *argv[]) {
    mpz_t P,p,g;
    mpz_init_set_ui(P,1);
    mpz_init_set_ui(p,1);
    mpz_init(g);

    while(mpz_cmp_ui(p,42)!=0) {
    mpz_add_ui(p,p,1);
    mpz_gcd(g,P,p);
    if(mpz_cmp_ui(g,1)==0) {
    mpz_mul(P,P,p);
    gmp_printf("%Zd %Zd\n",p,P);
    }
    }

    mpz_clears(g,p,P,NULL);
    return 0;
    }
    #+end_src

    #+RESULTS: Primes via Primorial (C)
    : The results are identical to the expected output.

    ** DC :resourceless: :PROPERTIES:
    :ID: c76ef9fe-62b2-4156-ae0c-f133a314dfed
    :END:

    Tested with GNU-DC.

    #+name: Primes via Primorial (DC)
    #+header: :shebang #!/usr/bin/env -S stdbuf -oL -eL dc
    #+header: :results output :exports both :eval no-export
    #+header: :post result-equal(a=ref, b=*this*)
    #+begin_src sh
    [ d S! % L! r d 0<G ] sG # a b -- gcd 0

    [
    lp lP * sP # "remember" found prime by multiplying it into P
    lp n 32 P # print: p <space>
    lP n 10 P # print: P <linefeed>
    ] sT

    [ 2q ] sQ

    [
    lp 1 + sp # p += 1

    lp 42<Q # break if end reached

    lp lP lG x + 1=T # gcd(P,p) > 1 ? call T
    lL x # tail-recurse
    ]
    sL # store as L

    1 sp # p = 1
    1 sP # P = 1
    lL x # call L
    #+end_src

    #+RESULTS: Primes via Primorial (DC)
    : The results are identical to the expected output.

    [[https://tio.run/##dZFPT4NAEMXv@yleS0zUSlKqJ0Px2AuHbeTW9MCfoW5c6LoLif30OLRJUSnvNNn85u28mSLvuh0KvM9wh3gGy/Uy3GAPtwE8pMjg@zjk/CzETgDaQEs8wkn8kYe5pYqqjOwc5bGtCxirKkJ2QtXqRhl9UvUBqoGqmyPkxavG8wr/rNiLW@vmFQahM2lOUQ9LhoPlNDxIItSqppKoiARHSXh0rL76VNtrigALODM2w2KNQFyYl1W4BUZMZin9hCpBnJLr/IMKcd2N3uCbvYN1MnTwAu/lk3lAxP@@IU@1RtJ3xMzekIcmVdq3lLfWkdgLF2NCHlxztITUIRYiGGf6Fa1PFoxONxDyTEwN1RPnyeOu@wE][...the above in tio.run...]]

    ** Emacs-Lisp :resourceless: :PROPERTIES:
    :ID: 890ff0ed-9317-4c7f-a3c5-9b82034fd27e
    :END:

    /!\ Please excuse my Lisp indentation style. I'm optimistic that
    Lispers will be able to read it in this non standard style, but users of
    other languages may find this less compact way a bit easier.

    *** ...using cl-lib
    :PROPERTIES:
    :ID: 10142f5f-3882-4ca8-817a-aac7c432a53a
    :END:

    #+name: Primes via Primorial (elisp 1)
    #+header: :shebang #!/usr/bin/env -S emacs -Q --script
    #+header: :results output :exports both :eval no-export
    #+header: :post result-equal(a=ref, b=*this*)
    #+begin_src sh
    (require 'cl-lib)

    (let ((P 1) (p 1))
    (while (< p 42)
    (setq p (1+ p))
    (when (= 1 (cl-gcd P p))
    (setq P (* P p))
    (princ (format "%d %d\n" p P))
    )
    )
    )
    #+end_src

    #+RESULTS: Primes via Primorial (elisp 1)
    : The results are identical to the expected output.

    *** ...without cl-lib
    :PROPERTIES:
    :ID: 93771662-0994-4c16-a896-3a74d495a709
    :END:

    #+name: Primes via Primorial (elisp 2)
    #+header: :shebang #!/usr/bin/env -S emacs -Q --script
    #+header: :results output :exports both :eval no-export
    #+header: :post result-equal(a=ref, b=*this*)
    #+begin_src sh
    (defun gcd (x y)
    (if (= y 0)
    x
    (gcd y (mod x y)
    )
    )
    )

    (let ((P 1) (p 1))
    (while (< p 42)
    (setq p (1+ p))
    (when (= 1 (gcd P p))
    (setq P (* P p))
    (princ (format "%d %d\n" p P))
    )
    )
    )
    #+end_src

    #+RESULTS: Primes via Primorial (elisp 2)
    : The results are identical to the expected output.

    ** GAWK :resourceless: :PROPERTIES:
    :ID: d084c6c3-6e16-4e64-a773-aa96c39d49ff
    :END:

    /!\ This is deliberately failing to test the results watchdog.

    The code is correct but just spits out one line less, see ~while(p<40)~.

    #+name: Primes via Primorial (gawk)
    #+header: :shebang #!/usr/bin/env -S gawk --bignum -f
    #+header: :results output :exports both :eval no-export
    #+header: :post result-equal(a=ref, b=*this*)
    #+begin_src sh
    # use: gawk --bignum

    function gcd(a,b) {
    return b?gcd(b,(a%b)):a
    }

    BEGIN {
    P=p=1
    while(p<40)
    if(gcd(P,++p)==1)
    print p,P*=p
    }
    #+end_src

    #+RESULTS: Primes via Primorial (gawk)
    : /!\ The results do not match the expected output.

    [[https://tio.run/##NY5BCsIwFET3/xQDIiQ2XVRcFYMgiLiRXCGpaQ2tMdSGLqRnj63iapjHGxg9timtEF@2RKPHFnluXOPjg6iOvhrc06OpbkwLw/EmoLdD7D3MYaFGML02nJeaJqLj6Xy5fiUlgyzmHO@usyzsd1s@N8DVbJkpkWWBS1n8KBB65wcEoTYy0JRS@r/4AA][...the above in tio.run...]]

    * Last Cry :resourceless: :PROPERTIES:
    :ID: bbabb4de-7522-4038-9c90-67ca7e71bfd0
    :END:

    #+begin_example
    ( Are we there yet? )
    \ ( Be patient! )
    \ \
    _______________________ _@o ____________ _@o _@o _______________________ #+end_example

    --=-=-=
    Content-Type: text/plain

    ------------------------------------------------------------------------

    ASCII export looks acceptable. I'm not yet happy with links, but I do
    not think I'll do much about that.

    ------------------------------------------------------------------------

    --=-=-=
    Content-Type: text/plain
    Content-Disposition: inline

    ________________________

    KNOTS IN DA BRAINZ
    Now With More Examples

    Wasn't Me, Mom!!!
    ________________________


    Table of Contents
    _________________

    1. Task
    .. 1. Reference Result
    2. Implementations
    .. 1. C
    .. 2. DC
    .. 3. Emacs-Lisp
    ..... 1. ...using cl-lib
    ..... 2. ...without cl-lib
    .. 4. GAWK
    3. Last Cry





    1 Task
    ======

    Calculate the n-th Primorial in a Way using the known ones as jump
    bar.

    The Primorial is product of numbers like a Factorial, but only using
    primes.

    Hint: `GCD(Primorial,Prime) == 1' for primes not yet multiplied into
    the used `Primorial'.


    1.1 Reference Result
    ~~~~~~~~~~~~~~~~~~~~

    ,----
    | 2 2
    | 3 6
    | 5 30
    | 7 210
    | 11 2310
    | 13 30030
    | 17 510510
    | 19 9699690
    | 23 223092870
    | 29 6469693230
    | 31 200560490130
    | 37 7420738134810
    | 41 304250263527210
    `----


    2 Implementations
    =================

    2.1 C
    ~~~~~

    This was verified to compile with GCC an TinyCC.

    ,----
    | #include <stdio.h>
    | #include <gmp.h>
    |
    | int main(int argc, char *argv[]) {
    | mpz_t P,p,g;
    | mpz_init_set_ui(P,1);
    | mpz_init_set_ui(p,1);
    | mpz_init(g);
    |
    | while(mpz_cmp_ui(p,42)!=0) {
    | mpz_add_ui(p,p,1);
    | mpz_gcd(g,P,p);
    | if(mpz_cmp_ui(g,1)==0) {
    | mpz_mul(P,P,p);
    | gmp_printf("%Zd %Zd\n",p,P);
    | }
    | }
    |
    | mpz_clears(g,p,P,NULL);
    | return 0;
    | }
    `----

    ,----
    | The results are identical to the expected output.
    `----


    2.2 DC
    ~~~~~~

    Tested with GNU-DC.

    ,----
    | [ d S! % L! r d 0<G ] sG # a b -- gcd 0
    |
    | [
    | lp lP * sP # "remember" found prime by multiplying it into P
    | lp n 32 P # print: p <space>
    | lP n 10 P # print: P <linefeed>
    | ] sT
    |
    | [ 2q ] sQ
    |
    | [
    | lp 1 + sp # p += 1
    |
    | lp 42<Q # break if end reached
    |
    | lp lP lG x + 1=T # gcd(P,p) > 1 ? call T
    | lL x # tail-recurse
    | ]
    | sL # store as L
    |
    | 1 sp # p = 1
    | 1 sP # P = 1
    | lL x # call L
    `----

    ,----
    | The results are identical to the expected output.
    `----


    [...the above in tio.run...]


    [...the above in tio.run...] <https://tio.run/##dZFPT4NAEMXv@yleS0zUSlKqJ0Px2AuHbeTW9MCfoW5c6LoLif30OLRJUSnvNNn85u28mSLvuh0KvM9wh3gGy/Uy3GAPtwE8pMjg@zjk/CzETgDaQEs8wkn8kYe5pYqqjOwc5bGtCxirKkJ2QtXqRhl9UvUBqoGqmyPkxavG8wr/rNiLW@vmFQahM2lOUQ9LhoPlNDxIItSqppKoiARHSXh0rL76VNtrigALODM2w2KNQFyYl1W4BUZMZin9hCpBnJLr/IMKcd2N3uCbvYN1MnTwAu/lk3lAxP@@IU@1RtJ3xMzekIcmVdq3lLfWkdgLF2NCHlxztITUIRYiGGf6Fa1PFoxONxDyTEwN1RPnyeOu@wE>


    2.3 Emacs-Lisp
    ~~~~~~~~~~~~~~

    /!\ Please excuse my Lisp indentation style. I'm optimistic that
    Lispers will be able to read it in this non standard style, but users
    of other languages may find this less compact way a bit easier.


    2.3.1 ...using cl-lib
    ---------------------

    ,----
    | (require 'cl-lib)
    |
    | (let ((P 1) (p 1))
    | (while (< p 42)
    | (setq p (1+ p))
    | (when (= 1 (cl-gcd P p))
    | (setq P (* P p))
    | (princ (format "%d %d\n" p P))
    | )
    | )
    | )
    `----

    ,----
    | The results are identical to the expected output.
    `----


    2.3.2 ...without cl-lib
    -----------------------

    ,----
    | (defun gcd (x y)
    | (if (= y 0)
    | x
    | (gcd y (mod x y)
    | )
    | )
    | )
    |
    | (let ((P 1) (p 1))
    | (while (< p 42)
    | (setq p (1+ p))
    | (when (= 1 (gcd P p))
    | (setq P (* P p))
    | (princ (format "%d %d\n" p P))
    | )
    | )
    | )
    `----

    ,----
    | The results are identical to the expected output.
    `----


    2.4 GAWK
    ~~~~~~~~

    /!\ This is deliberately failing to test the results watchdog.

    The code is correct but just spits out one line less, see
    `while(p<40)'.

    ,----
    | # use: gawk --bignum
    |
    | function gcd(a,b) {
    | return b?gcd(b,(a%b)):a
    | }
    |
    | BEGIN {
    | P=p=1
    | while(p<40)
    | if(gcd(P,++p)==1)
    | print p,P*=p
    | }
    `----

    ,----
    | /!\ The results do not match the expected output.
    `----


    [...the above in tio.run...]


    [...the above in tio.run...] <https://tio.run/##NY5BCsIwFET3/xQDIiQ2XVRcFYMgiLiRXCGpaQ2tMdSGLqRnj63iapjHGxg9timtEF@2RKPHFnluXOPjg6iOvhrc06OpbkwLw/EmoLdD7D3MYaFGML02nJeaJqLj6Xy5fiUlgyzmHO@usyzsd1s@N8DVbJkpkWWBS1n8KBB65wcEoTYy0JRS@r/4AA>


    3 Last Cry
    ==========

    ,----
    | ( Are we there yet? )
    | \ ( Be patient! )
    | \ \
    | _______________________ _@o ____________ _@o _@o _______________________
    `----

    --=-=-=
    Content-Type: text/plain

    ------------------------------------------------------------------------

    I'm not so happy with the default look of Org's HTML export and my other
    stuff has more tweaks co compensate for that. So here it is, a not
    really fine tuned HTML example:

    ------------------------------------------------------------------------

    --=-=-=
    Content-Type: text/html
    Content-Disposition: inline

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
    <!-- 2024-03-04 Mon 13:46 -->
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Knots In Da Brainz</title>
    <meta name="generator" content="Org mode" />
    <meta name="author" content="Wasn't Me, Mom!!!" />
    <style type="text/css">
    <!--/*--><![CDATA[/*><!--*/
    .title { text-align: center;
    margin-bottom: .2em; }
    .subtitle { text-align: center;
    font-size: medium;
    font-weight: bold;
    margin-top:0; }
    .todo { font-family: monospace; color: red; }
    .done { font-family: monospace; color: green; }
    .priority { font-family: monospace; color: orange; }
    .tag { background-color: #eee; font-family: monospace;
    padding: 2px; font-size: 80%; font-weight: normal; }
    .timestamp { color: #bebebe; }
    .timestamp-kwd { color: #5f9ea0; }
    .org-right { margin-left: auto; margin-right: 0px; text-align: right; }
    .org-left { margin-left: 0px; margin-right: auto; text-align: left; }
    .org-center { margin-left: auto; margin-right: auto; text-align: center; }
    .underline { text-decoration: underline; }
    #postamble p, #preamble p { font-size: 90%; margin: .2em; }
    p.verse { margin-left: 3%; }
    pre {
    border: 1px solid #ccc;
    box-shadow: 3px 3px 3px #eee;
    padding: 8pt;
    font-family: monospace;
    overflow: auto;
    margin: 1.2em;
    }
    pre.src {
    position: relative;
    overflow: visible;
    padding-top: 1.2em;
    }
    pre.src:before {
    display: none;
    position: absolute;
    background-color: white;
    top: -10px;
    right: 10px;
    padding: 3px;
    border: 1px solid black;
    }
    pre.src:hover:before { display: inline;}
    /* Languages per Org manual */
    pre.src-asymptote:before { content: 'Asymptote'; }
    pre.src-awk:before { content: 'Awk'; }
    pre.src-C:before { content: 'C'; }
    /* pre.src-C++ doesn't work in CSS */
    pre.src-clojure:before { content: 'Clojure'; }
    pre.src-css:before { content: 'CSS'; }
    pre.src-D:before { content: 'D'; }
    pre.src-ditaa:before { content: 'ditaa'; }
    pre.src-dot:before { content: 'Graphviz'; }
    pre.src-calc:before { content: 'Emacs Calc'; }
    pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
    pre.src-fortran:before { content: 'Fortran'; }
    pre.src-gnuplot:before { content: 'gnuplot'; }
    pre.src-haskell:before { content: 'Haskell'; }
    pre.src-hledger:before { content: 'hledger'; }
    pre.src-java:before { content: 'Java'; }
    pre.src-js:before { content: 'Javascript'; }
    pre.src-latex:before { content: 'LaTeX'; }
    pre.src-ledger:before { content: 'Ledger'; }
    pre.src-lisp:before { content: 'Lisp'; }
    pre.src-lilypond:before { content: 'Lilypond'; }
    pre.src-lua:before { content: 'Lua'; }
    pre.src-matlab:before { content: 'MATLAB'; }
    pre.src-mscgen:before { content: 'Mscgen'; }
    pre.src-ocaml:before { content: 'Objective Caml'; }
    pre.src-octave:before { content: 'Octave'; }
    pre.src-org:before { content: 'Org mode'; }
    pre.src-oz:before { content: 'OZ'; }
    pre.src-plantuml:before { content: 'Plantuml'; }
    pre.src-processing:before { content: 'Processing.js'; }
    pre.src-python:before { content: 'Python'; }
    pre.src-R:before { content: 'R'; }
    pre.src-ruby:before { content: 'Ruby'; }
    pre.src-sass:before { content: 'Sass'; }
    pre.src-scheme:before { content: 'Scheme'; }
    pre.src-screen:before { content: 'Gnu Screen'; }
    pre.src-sed:before { content: 'Sed'; }
    pre.src-sh:before { content: 'shell'; }
    pre.src-sql:before { content: 'SQL'; }
    pre.src-sqlite:before { content: 'SQLite'; }
    /* additional languages in org.el's org-babel-load-languages alist */
    pre.src-forth:before { content: 'Forth'; }
    pre.src-io:before { content: 'IO'; }
    pre.src-J:before { content: 'J'; }
    pre.src-makefile:before { content: 'Makefile'; }
    pre.src-maxima:before { content: 'Maxima'; }
    pre.src-perl:before { content: 'Perl'; }
    pre.src-picolisp:before { content: 'Pico Lisp'; }
    pre.src-scala:before { content: 'Scala'; }
    pre.src-shell:before { content: 'Shell Script'; }
    pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
    /* additional language identifiers per "defun org-babel-execute"
    in ob-*.el */
    pre.src-cpp:before { content: 'C++'; }
    pre.src-abc:before { content: 'ABC'; }
    pre.src-coq:before { content: 'Coq'; }
    pre.src-groovy:before { content: 'Groovy'; }
    /* additional language identifiers from org-babel-shell-names in
    ob-shell.el: ob-shell is the only babel language using a lambda to put
    the execution function name together. */
    pre.src-bash:before { content: 'bash'; }
    pre.src-csh:before { content: 'csh'; }
    pre.src-ash:before { content: 'ash'; }
    pre.src-dash:before { content: 'dash'; }
    pre.src-ksh:before { content: 'ksh'; }
    pre.src-mksh:before { content: 'mksh'; }
    pre.src-posh:before { content: 'posh'; }
    /* Additional Emacs modes also supported by the LaTeX listings package */
    pre.src-ada:before { content: 'Ada'; }
    pre.src-asm:before { content: 'Assembler'; }
    pre.src-caml:before { content: 'Caml'; }
    pre.src-delphi:before { content: 'Delphi'; }
    pre.src-html:before { content: 'HTML'; }
    pre.src-idl:before { content: 'IDL'; }
    pre.src-mercury:before { content: 'Mercury'; }
    pre.src-metapost:before { content: 'MetaPost'; }
    pre.src-modula-2:before { content: 'Modula-2'; }
    pre.src-pascal:before { content: 'Pascal'; }
    pre.src-ps:before { content: 'PostScript'; }
    pre.src-prolog:before { content: 'Prolog'; }
    pre.src-simula:before { content: 'Simula'; }
    pre.src-tcl:before { content: 'tcl'; }
    pre.src-tex:before { content: 'TeX'; }
    pre.src-plain-tex:before { content: 'Plain TeX'; }
    pre.src-verilog:before { content: 'Verilog'; }
    pre.src-vhdl:before { content: 'VHDL'; }
    pre.src-xml:before { content: 'XML'; }
    pre.src-nxml:before { content: 'XML'; }
    /* add a generic configuration mode; LaTeX export needs an additional
    (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
    pre.src-conf:before { content: 'Configuration File'; }

    table { border-collapse:collapse; }
    caption.t-above { caption-side: top; }
    caption.t-bottom { caption-side: bottom; }
    td, th { vertical-align:top; }
    th.org-right { text-align: center; }
    th.org-left { text-align: center; }
    th.org-center { text-align: center; }
    td.org-right { text-align: right; }
    td.org-left { text-align: left; }
    td.org-center { text-align: center; }
    dt { font-weight: bold; }
    .footpara { display: inline; }
    .footdef { margin-bottom: 1em; }
    .figure { padding: 1em; }
    .figure p { text-align: center; }
    .equation-container {
    display: table;
    text-align: center;
    width: 100%;
    }
    .equation {
    vertical-align: middle;
    }
    .equation-label {
    display: table-cell;
    text-align: right;
    vertical-align: middle;
    }
    .inlinetask {
    padding: 10px;
    border: 2px solid gray;
    margin: 10px;
    background: #ffffcc;
    }
    #org-div-home-and-up
    { text-align: right; font-size: 70%; white-space: nowrap; }
    textarea { overflow-x: auto; }
    .linenr { font-size: smaller }
    .code-highlighted { background-color: #ffff00; }
    .org-info-js_info-navigation { border-style: none; }
    #org-info-js_console-label
    { font-size: 10px; font-weight: bold; white-space: nowrap; }
    .org-info-js_search-highlight
    { background-color: #ffff00; color: #000000; font-weight: bold; }
    .org-svg { width: 90%; }
    /*]]>*/-->
    </style>
    <script type="text/javascript">
    /*
    @licstart The following is the entire license notice for the
    JavaScript code in this tag.

    Copyright (C) 2012-2020 Free Software Foundation, Inc.

    The JavaScript code in this tag is free software: you can
    redistribute it and/or modify it under the terms of the GNU
    General Public License (GNU GPL) as published by the Free Software
    Foundation, either version 3 of the License, or (at your option)
    any later version. The code is distributed WITHOUT ANY WARRANTY;
    without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.

    As additional permission under GNU GPL version 3 section 7, you
    may distribute non-source (e.g., minimized or compacted) forms of
    that code without the copy of the GNU GPL normally required by
    section 4, provided you include this license notice and a URL
    through which recipients can access the Corresponding Source.


    @licend The above is the entire license notice
    for the JavaScript code in this tag.
    */
    <!--/*--><![CDATA[/*><!--*/
    function CodeHighlightOn(elem, id)
    {
    var target = document.getElementById(id);
    if(null != target) {
    elem.cacheClassElem = elem.className;
    elem.cacheClassTarget = target.className;
    target.className = "code-highlighted";
    elem.className = "code-highlighted";
    }
    }
    function CodeHighlightOff(elem, id)
    {
    var target = document.getElementById(id);
    if(elem.cacheClassElem)
    elem.className = elem.cacheClassElem;
    if(elem.cacheClassTarget)
    target.className = elem.cacheClassTarget;
    }
    /*]]>*///-->
    </script>
    </head>
    <body>
    <div id="content">
    <h1 class="title">Knots In Da Brainz
    <br />
    <span class="subtitle">Now With More Examples</span>
    </h1>
    <div id="table-of-contents">
    <h2>Table of Contents</h2>
    <div id="text-table-of-contents">

    <li><a href="#orged5f1b8">1. Task</a>

    <li><a href="#org3f8a3bf">1.1. Reference Result</a></li>
    </ul>
    </li>
    <li><a href="#org25a4dab">2. Implementations</a>

    <li><a href="#orga021e93">2.1. C</a></li>
    <li><a href="#org72561fd">2.2. DC</a></li>
    <li><a href="#orgcc0c7f8">2.3. Emacs-Lisp</a>

    <li><a href="#org99cfecd">2.3.1. &#x2026;using cl-lib</a></li>
    <li><a href="#org470c338">2.3.2. &#x2026;without cl-lib</a></li>
    </ul>
    </li>
    <li><a href="#orgff0035a">2.4. GAWK</a></li>
    </ul>
    </li>
    <li><a href="#org5583be6">3. Last Cry</a></li>
    </ul>
    </div>
    </div>

    <div id="outline-container-orged5f1b8" class="outline-2">
    <h2 id="orged5f1b8"><span class="section-number-2">1</span> <a href="#orged5f1b8">Task</a></h2>
    <div class="outline-text-2" id="text-1">

    Calculate the n-th Primorial in a Way using the known ones as jump bar.



    The Primorial is product of numbers like a Factorial, but only
    using primes.



    Hint: <code>GCD(Primorial,Prime) == 1</code> for primes not yet multiplied into the
    used <code>Primorial</code>.

    </div>

    <div id="outline-container-org3f8a3bf" class="outline-3">
    <h3 id="org3f8a3bf"><span class="section-number-3">1.1</span> <a href="#org3f8a3bf">Reference Result</a></h3>
    <div class="outline-text-3" id="text-1-1">
    <pre class="example">
    2 2
    3 6
    5 30
    7 210
    11 2310
    13 30030
    17 510510
    19 9699690
    23 223092870
    29 6469693230
    31 200560490130
    37 7420738134810
    41 304250263527210
    </pre>
    </div>
    </div>
    </div>

    <div id="outline-container-org25a4dab" class="outline-2">
    <h2 id="org25a4dab"><span class="section-number-2">2</span> <a href="#org25a4dab">Implementations</a></h2>
    <div class="outline-text-2" id="text-2">
    </div>

    <div id="outline-container-orga021e93" class="outline-3">
    <h3 id="orga021e93"><span class="section-number-3">2.1</span> <a href="#orga021e93">C</a></h3>
    <div class="outline-text-3" id="text-2-1">

    This was verified to compile with GCC an TinyCC.


    <div class="org-src-container">
    <pre class="src src-sh" id="org2ac031d">#include &lt;stdio.h&gt;
    #include &lt;gmp.h&gt;

    int main(int argc, char *argv[]) {
    mpz_t P,p,g;
    mpz_init_set_ui(P,1);
    mpz_init_set_ui(p,1);
    mpz_init(g);

    while(mpz_cmp_ui(p,42)!=0) {
    mpz_add_ui(p,p,1);
    mpz_gcd(g,P,p);
    if(mpz_cmp_ui(g,1)==0) {
    mpz_mul(P,P,p);
    gmp_printf("%Zd %Zd\n",p,P);
    }
    }

    mpz_clears(g,p,P,NULL);
    return 0;
    }
    </pre>
    </div>

    <pre class="example">
    The results are identical to the expected output.
    </pre>
    </div>
    </div>

    <div id="outline-container-org72561fd" class="outline-3">
    <h3 id="org72561fd"><span class="section-number-3">2.2</span> <a href="#org72561fd">DC</a></h3>
    <div class="outline-text-3" id="text-2-2">

    Tested with GNU-DC.


    <div class="org-src-container">
    <pre class="src src-sh" id="org07c5b7c">[ d S! % L! r d 0&lt;G ] sG # a b -- gcd 0

    [
    lp lP * sP # "remember" found prime by multiplying it into P
    lp n 32 P # print: p &lt;space&gt;
    lP n 10 P # print: P &lt;linefeed&gt;
    ] sT

    [ 2q ] sQ

    [
    lp 1 + sp # p += 1

    lp 42&lt;Q # break if end reached

    lp lP lG x + 1=T # gcd(P,p) &gt; 1 ? call T
    lL x # tail-recurse
    ]
    sL # store as L

    1 sp # p = 1
    1 sP # P = 1
    lL x # call L
    </pre>
    </div>

    <pre class="example">
    The results are identical to the expected output.
    </pre>



    <a href="https://tio.run/#%23dZFPT4NAEMXv@yleS0zUSlKqJ0Px2AuHbeTW9MCfoW5c6LoLif30OLRJUSnvNNn85u28mSLvuh0KvM9wh3gGy/Uy3GAPtwE8pMjg@zjk/CzETgDaQEs8wkn8kYe5pYqqjOwc5bGtCxirKkJ2QtXqRhl9UvUBqoGqmyPkxavG8wr/rNiLW@vmFQahM2lOUQ9LhoPlNDxIItSqppKoiARHSXh0rL76VNtrigALODM2w2KNQFyYl1W4BUZMZin9hCpBnJLr/IMKcd2N3uCbvYN1MnTwAu/lk3lAxP@@IU@1RtJ3xMzekIcmVdq3lLfWkdgLF2NCHlxztITUIRYiGGf6Fa1PFoxONxDyTEwN1RPnyeOu@wE">&#x2026;the above in tio.run&#x2026;</a>

    </div>
    </div>

    <div id="outline-container-orgcc0c7f8" class="outline-3">
    <h3 id="orgcc0c7f8"><span class="section-number-3">2.3</span> <a href="#orgcc0c7f8">Emacs-Lisp</a></h3>
    <div class="outline-text-3" id="text-2-3">

    /!\ Please excuse my Lisp indentation style. I'm optimistic that
    Lispers will be able to read it in this non standard style, but users of
    other languages may find this less compact way a bit easier.

    </div>

    <div id="outline-container-org99cfecd" class="outline-4">
    <h4 id="org99cfecd"><span class="section-number-4">2.3.1</span> <a href="#org99cfecd">&#x2026;using cl-lib</a></h4>
    <div class="outline-text-4" id="text-2-3-1">
    <div class="org-src-container">
    <pre class="src src-sh" id="org8bc3f5d">(require 'cl-lib)

    (let ((P 1) (p 1))
    (while (&lt; p 42)
    (setq p (1+ p))
    (when (= 1 (cl-gcd P p))
    (setq P (* P p))
    (princ (format "%d %d\n" p P))
    )
    )
    )
    </pre>
    </div>

    <pre class="example">
    The results are identical to the expected output.
    </pre>
    </div>
    </div>

    <div id="outline-container-org470c338" class="outline-4">
    <h4 id="org470c338"><span class="section-number-4">2.3.2</span> <a href="#org470c338">&#x2026;without cl-lib</a></h4>
    <div class="outline-text-4" id="text-2-3-2">
    <div class="org-src-container">
    <pre class="src src-sh" id="org85c9151">(defun gcd (x y)
    (if (= y 0)
    x
    (gcd y (mod x y)
    )
    )
    )

    (let ((P 1) (p 1))
    (while (&lt; p 42)
    (setq p (1+ p))
    (when (= 1 (gcd P p))
    (setq P (* P p))
    (princ (format "%d %d\n" p P))
    )
    )
    )
    </pre>
    </div>

    <pre class="example">
    The results are identical to the expected output.
    </pre>
    </div>
    </div>
    </div>

    <div id="outline-container-orgff0035a" class="outline-3">
    <h3 id="orgff0035a"><span class="section-number-3">2.4</span> <a href="#orgff0035a">GAWK</a></h3>
    <div class="outline-text-3" id="text-2-4">

    /!\ This is deliberately failing to test the results watchdog.



    The code is correct but just spits out one line less, see <code>while(p&lt;40)</code>.


    <div class="org-src-container">
    <pre class="src src-sh" id="org0f17f8a"># use: gawk --bignum

    function gcd(a,b) {
    return b?gcd(b,(a%b)):a
    }

    BEGIN {
    P=p=1
    while(p&lt;40)
    if(gcd(P,++p)==1)
    print p,P*=p
    }
    </pre>
    </div>

    <pre class="example">
    /!\ The results do not match the expected output.
    </pre>



    <a href="https://tio.run/#%23NY5BCsIwFET3/xQDIiQ2XVRcFYMgiLiRXCGpaQ2tMdSGLqRnj63iapjHGxg9timtEF@2RKPHFnluXOPjg6iOvhrc06OpbkwLw/EmoLdD7D3MYaFGML02nJeaJqLj6Xy5fiUlgyzmHO@usyzsd1s@N8DVbJkpkWWBS1n8KBB65wcEoTYy0JRS@r/4AA">&#x2026;the above in tio.run&#x2026;</a>

    </div>
    </div>
    </div>

    <div id="outline-container-org5583be6" class="outline-2">
    <h2 id="org5583be6"><span class="section-number-2">3</span> <a href="#org5583be6">Last Cry</a></h2>
    <div class="outline-text-2" id="text-3">
    <pre class="example">
    ( Are we there yet? )
    \ ( Be patient! )
    \ \
    _______________________ _@o ____________ _@o _@o _______________________
    </pre>
    </div>
    </div>
    </div>
    <div id="postamble" class="status">
    <p class="author">Author: Wasn't Me, Mom!!!</p>
    <p class="date">Created: 2024-03-04 Mon 13:46</p>
    <p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
    </div>
    </body>
    </html>
    --=-=-=
    Content-Type: text/plain

    ------------------------------------------------------------------------

    Conclusion...

    You have survived all this and still are reading? WOW!!!

    I'll take a break from this and later will try to find a way to
    automagically show out the results if they do not match the reference
    results. Apart from that I'm kind of happy with the current state of
    this experiment.
    --
    C-x C-c

    Oops!
    Wrong window!

    --=-=-=--
    --- Synchronet 3.19a-Linux NewsLink 1.113
  • From yeti@yeti@tilde.institute to tilde.institute on Mon Mar 4 20:53:25 2024
    It's late, too late for a solution with more blingbling than this:

    ------------------------------------------------------------------------ #+name: result-equal
    #+begin_src elisp :results output :exports none :var a="" b="" :eval always
    (if (string-equal a b)
    (princ "The results are identical to the expected output.")
    (progn
    (princ b)
    (princ "\n")
    (princ "/!\\ The results do not match the expected output.")))
    #+end_src ------------------------------------------------------------------------
    --
    3. Hitchhiker 1: (6) He stood up straight and looked the world squarely
    in the fields and hills. To add weight to his words he stuck the rabbit
    bone in his hair. He spread his arms out wide. (7) "I will go mad!" he announced.
    --- Synchronet 3.19a-Linux NewsLink 1.113