REN-C code show off

Think about the Fizz Buzz code Brian created and showed at the 2019 Conference:

count-up n 100 [
    print [ unspaced [
        if n mod 3 = 0 ["Fizz"]
        if n mod 5 = 0 ["Büzz"]
    ] else [n]]
]

Any more pieces of code where REN-C excels?

There are more programming ideas at

Rosettacode

Code Forces

1 Like

Displaying the Prime factors of an integer.
On rebol.org this oneliner script by Sunanda can be found.
I needs slight mod ification to work on REN-C. And with a bit of realigning and getting rid of the abbreviation for 'append we arrive at this function.

prime-factors: function [n [integer!]][
    m: 2 
    s: 1 
    a: copy[]
    until[
        either n mod m = 0 [
            n: n / m 
            append a m
        ][
            m: m + s 
            s: 2
        ]
        if 1. * m * m > n [
            append a n 
            n: 1
        ]
         n = 1
    ]
    a
] 

Where it is to be noted that n should be >= 2 and the maximum size will also be limited

Code for the "8 Queens problem"

; REN-C solution to the N Queens problem
;
; Place all N queens on the NxN chessboard where every queen is to be placed 
; on a field that is not taken nor covered by any of the other queens.
;
; We know the solutions are not symmetrical themselves but the solutions can be
; mirror images of other solutions or turned solutions.

; This solution works as follows
; By symmetry we only need to test the first half of the row or column with
; the first queen. On an odd sized board we only cannot double the number of
; results for the middle position.

; We do not know or even care if we work horizontally or vertically and even if we are
; starting at the first or last row or column is irrelevant.

; We start with adding our first queen to the board. This is a number in a
; solution block. The we go to the next level and determine the free choices
; for our next queen. This is a collection of all fields minus the ones other
; queens cover. This propagates through all rows / columns. At the end we
; reach an empty set so no solution or a set of solutions.

; This global variable is a quick and dirty fix.
number-of-solutions: 0

reset-number-of-solutions: does [
    number-of-solutions: 0
]

add-one-to-number-of-solutions: does [
    number-of-solutions: number-of-solutions + 1
]

get-number-of-solutions: does [
    number-of-solutions
]

; This variable is to signal that results should not be duplicated for
; this value.
odd-symmetry-limit: 0

reset-symmetry-limit: does [
    odd-symmetry-limit: 0
]

add-to-symmetry-limit: does [
    odd-symmetry-limit: odd-symmetry-limit + 1
]

;
logic-countonly: 0

set-countonly-true: does [
    logic-countonly: 1
]

set-countonly-false: does [
    logic-countonly: 0
]

; Function to print the board for a solution

print-board: function [n [integer!]
                       board-values [block!]
][
    a: copy ""
    for-each b board-values [
        repeat t b - 1 [ append a ". "]
        append a "Q "
        repeat t n - b [ append a ". "]
        append a newline
    ]
    print a
]

; Function for recursion
add-queen: function [n [integer!]
     solution [block!]
     free-places [block!]
][
     ; Determine the free choices for this queen
     forbidden-places: copy []
     can-see: 1
     rsolution: reverse copy solution
     for-each sol rsolution [
         append forbidden-places sol
         append forbidden-places sol + can-see
         append forbidden-places sol - can-see ; too lazy to check for out of bounds
         can-see: can-see + 1
     ]
     free-choices: exclude free-places forbidden-places
     if not empty? free-choices [
         either n = 1 [
             ; now check for a solution, no more recursion possible
             for-each place free-choices [
                 append solution place
                 if logic-countonly = 0 [print-board length-of solution solution]
                 add-one-to-number-of-solutions
                 if any [odd-symmetry-limit > first solution
                         odd-symmetry-limit = 0]
                  [
                     if logic-countonly = 0 [print-board length-of solution reverse copy solution]
                     add-one-to-number-of-solutions
                 ]
                 clear skip solution ((length-of solution) - 1)
             ]
         ][
             for-each place free-choices [
                 append solution place
                 add-queen n - 1 solution free-places
                 clear skip solution ((length-of solution) - 1)
             ]
         ]
     ]
]

; Function for main solution

solve-n-queens: function [
    n [integer!] "The number queens on to place the board of size nxn"
    /countonly "Only print the number of solutions found"
][
    ; We need to know this within our recursive function
    either "/countonly" = mold countonly [
        set-countonly-true
    ][
        set-countonly-false
    ]

    ; make a basic block of the row / column numbers
    places-block: copy []
    count-up i n [append places-block i]

    reset-number-of-solutions

    ; We need only do half of the first row / column for reasons of symmetry
    half: either odd? n [(n + 1) / 2][n / 2]
    reset-symmetry-limit
    if odd? n [
        loop half [add-to-symmetry-limit]
    ]

    either n > 1 [
        count-up first-queen half [
            solution: copy []
            append solution first-queen

            add-queen n - 1 solution places-block

            clear solution ; this is okay because we are in the outermost loop here
        ]
    ][
        add-one-to-number-of-solutions
        print-board n [1]
    ]

    ; print the number of solutions now
    print spaced ["Total number of solutions for n =" n "is" get-number-of-solutions]
]


; Examples

solve-n-queens 1
solve-n-queens 2
solve-n-queens 3
solve-n-queens 4
solve-n-queens 5
solve-n-queens/countonly 5

solve-n-queens/countonly 8
; 92

If we want to know how slow REN-C is on my machine

delta-time [solve-n-queens/countonly 5]
Total number of solutions for n = 5 is 10
== 0:00:00.00145

delta-time [solve-n-queens/countonly 8]
Total number of solutions for n = 8 is 92
== 0:00:00.041275

delta-time [solve-n-queens/countonly 12]
Total number of solutions for n = 12 is 14200
== 0:00:08.126828

delta-time [solve-n-queens/countonly 14]
Total number of solutions for n = 14 is 365596
== 0:06:21.679977

1 Like
; simple sudoku solver based on the Python example from computerphile:
; https://www.youtube.com/watch?v=G_UYXzGuqvM&list=WL&index=228

grid: [
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
]

print-grid: func [<local> output][
    output: copy ""
    count-up i 81 [
        append output grid/:i
        either i mod 9 = 0 [
            append output newline
            if all [ i mod 27 = 0
                     i < 81        ][
                append output "------+-------+------^/"
            ]
        ][
             append output either any [ i mod 9 = 3
                                        i mod 9 = 6 ][ " | " ][ " " ]
        ]
    ]
    print output
]

possible: func [
    y
    x
    n
    <local> x0 y0
][
    ; uses the global variable grid, hence used func not function that autocollects variables
    count-up i 9 [
        if n = grid/(9 * (y - 1) + i) [
            return false
        ]
    ]
    count-up i 9 [
        if n = grid/(9 * (i - 1) + x) [
            return false
        ]    
    ]
    x0: ((to integer! (x - 1) / 3)) * 3 + 1
    y0: ((to integer! (y - 1) / 3)) * 3 + 1
    count-up i 3 [
        count-up j 3 [
            if n = grid/(9 * (y0 + (i - 1) - 1) + (x0 + (j - 1))) [
                return false
            ]
        ]
    ]
    return true
]

solve: func [][
    count-up y 9 [
        count-up x 9 [
            if 0 = grid/(9 * (y - 1) + x) [
                count-up n 9 [
                    if possible y x n [
                        grid/(9 * (y - 1) + x): n
                        solve
                        grid/(9 * (y - 1) + x): 0 ; backtracking
                    ]
                ] return _
            ]
        ]
    ]
    print-grid
]

>> solve
5 3 4 | 6 7 8 | 9 1 2
6 7 2 | 1 9 5 | 3 4 8
1 9 8 | 3 4 2 | 5 6 7
------+-------+------
8 5 9 | 7 6 1 | 4 2 3
4 2 6 | 8 5 3 | 7 9 1
7 1 3 | 9 2 4 | 8 5 6
------+-------+------
9 6 1 | 5 3 7 | 2 8 4
2 8 7 | 4 1 9 | 6 3 5
3 4 5 | 2 8 6 | 1 7 9

== _

>>