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
]

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
]

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
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]
if any [odd-symmetry-limit > first solution
odd-symmetry-limit = 0]
[
if logic-countonly = 0 [print-board length-of solution reverse copy solution]
]
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 [
]

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
]
][
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:

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

== _

>>``````