Cantor set

From Rosetta Code
Cantor set is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Draw Cantor set. See details: Cantor set


ALGOL 68[edit]

BEGIN
# draw a Cantor Set using ASCII #
INT lines = 5; # number of lines for the set #
# we must choose the line width so that the width of each segment is #
# divisible by 3 ( except for the final line where the segment width will #
# be 1 ) #
INT set width = 3 ^ ( lines - 1 );
[ set width ]CHAR set;
# start with a complete line #
FOR i TO set width DO set[ i ] := "#" OD;
print( ( set, newline ) );
# repeatedly modify the line, replacing the middle third of each segment #
# with blanks #
INT segment width := set width OVER 3;
WHILE segment width > 0 DO
INT set pos := 1;
WHILE set pos < ( set width - segment width ) DO
set pos +:= segment width;
FOR char pos FROM set pos TO ( set pos + segment width ) - 1 DO
set[ char pos ] := " "
OD;
set pos +:= segment width
OD;
print( ( set, newline ) );
segment width OVERAB 3
OD
END
Output:
#################################################################################
###########################                           ###########################
#########         #########                           #########         #########
###   ###         ###   ###                           ###   ###         ###   ###
# #   # #         # #   # #                           # #   # #         # #   # #

ALGOL W[edit]

Based on the Algol 68 sample.

begin
 % draw a Cantor Set using ASCII  %
integer LINES;  % number of lines for the set  %
integer setWidth;  % width of each line of the set  %
 % we must choose the line width so that the width of each segment is  %
 % divisible by 3 ( except for the final line where the segment width will  %
 % be 1 )  %
LINES  := 5;
setWidth := round( 3 ** ( LINES - 1 ) );
begin % start new block so the array can have computed bounds  %
logical array set ( 1 :: setWidth );
integer segmentWidth;
 % start with a complete line %
for i := 1 until setWidth do set( i ) := true;
segmentWidth := setWidth;
for l := 1 until LINES do begin
 % print the latest line, all lines start with a "#"  %
write( "#" );
for i := 2 until setWidth do writeon( if set( i ) then "#" else " " );
 % modify the line, replacing the middle third of each segment  %
 % with blanks, unless this was the last line  %
if l < LINES then begin
integer setPos;
segmentWidth := segmentWidth div 3;
setPos := 1;
while setPos < ( setWidth - segmentWidth ) do begin
setPos := setPos + segmentWidth;
for charPos := setPos until ( setPos + segmentWidth ) - 1 do set( charPos ) := false;
setPos := setPos + segmentWidth
end while_setPos_in_range ;
end if_l_lt_LINES
end for_l
end
end.
Output:
#################################################################################
###########################                           ###########################
#########         #########                           #########         #########
###   ###         ###   ###                           ###   ###         ###   ###
# #   # #         # #   # #                           # #   # #         # #   # #

AWK[edit]

 
# syntax: GAWK -f CANTOR_SET.AWK
# converted from C
BEGIN {
WIDTH = 81
HEIGHT = 5
for (i=0; i<HEIGHT; ++i) {
for (j=0; j<WIDTH; ++j) {
lines[i][j] = "*"
}
}
cantor(0,WIDTH,1)
for (i=0; i<HEIGHT; ++i) {
for (j=0; j<WIDTH; ++j) {
printf("%s",lines[i][j])
}
printf("\n")
}
exit(0)
}
function cantor(start,leng,indx, i,j,seg) {
seg = int(leng/3)
if (seg == 0) { return }
for (i=indx; i<HEIGHT; ++i) {
for (j=start+seg; j<start+seg*2; ++j) {
lines[i][j] = " "
}
}
cantor(start,seg,indx+1)
cantor(start+seg*2,seg,indx+1)
}
 
Output:
*********************************************************************************
***************************                           ***************************
*********         *********                           *********         *********
***   ***         ***   ***                           ***   ***         ***   ***
* *   * *         * *   * *                           * *   * *         * *   * *

C[edit]

Translation of: Kotlin
#include <stdio.h>
 
#define WIDTH 81
#define HEIGHT 5
 
char lines[HEIGHT][WIDTH];
 
void init() {
int i, j;
for (i = 0; i < HEIGHT; ++i) {
for (j = 0; j < WIDTH; ++j) lines[i][j] = '*';
}
}
 
void cantor(int start, int len, int index) {
int i, j, seg = len / 3;
if (seg == 0) return;
for (i = index; i < HEIGHT; ++i) {
for (j = start + seg; j < start + seg * 2; ++j) lines[i][j] = ' ';
}
cantor(start, seg, index + 1);
cantor(start + seg * 2, seg, index + 1);
}
 
void print() {
int i, j;
for (i = 0; i < HEIGHT; ++i) {
for (j = 0; j < WIDTH; ++j) printf("%c", lines[i][j]);
printf("\n");
}
}
 
int main() {
init();
cantor(0, WIDTH, 1);
print();
return 0;
}
Output:
*********************************************************************************
***************************                           ***************************
*********         *********                           *********         *********
***   ***         ***   ***                           ***   ***         ***   ***
* *   * *         * *   * *                           * *   * *         * *   * *

Kotlin[edit]

Simple terminal drawing.

// Version 1.2.31
 
const val WIDTH = 81
const val HEIGHT = 5
 
val lines = List(HEIGHT) { CharArray(WIDTH) { '*' } }
 
fun cantor(start: Int, len: Int, index: Int) {
val seg = len / 3
if (seg == 0) return
for (i in index until HEIGHT) {
for (j in start + seg until start + seg * 2) lines[i][j] = ' '
}
cantor(start, seg, index + 1)
cantor(start + seg * 2, seg, index + 1)
}
 
fun main(args: Array<String>) {
cantor(0, WIDTH, 1)
lines.forEach { println(it) }
}
Output:
*********************************************************************************
***************************                           ***************************
*********         *********                           *********         *********
***   ***         ***   ***                           ***   ***         ***   ***
* *   * *         * *   * *                           * *   * *         * *   * *

Perl 6[edit]

Translation of: Kotlin
sub cantor ( Int $height ) {
my $width = 3 ** ($height - 1);
 
my @lines = ( "\c[FULL BLOCK]" x $width ) xx $height;
 
my sub _trim_middle_third ( $len, $start, $index ) {
my $seg = $len div 3
or return;
 
for ( $index ..^ $height ) X ( 0 ..^ $seg ) -> ( $i, $j ) {
@lines[$i].substr-rw( $start + $seg + $j, 1 ) = ' ';
}
 
_trim_middle_third( $seg, $start + $_, $index + 1 ) for 0, $seg * 2;
}
 
_trim_middle_third( $width, 0, 1 );
return @lines;
}
 
.say for cantor(5);
Output:
█████████████████████████████████████████████████████████████████████████████████
███████████████████████████                           ███████████████████████████
█████████         █████████                           █████████         █████████
███   ███         ███   ███                           ███   ███         ███   ███
█ █   █ █         █ █   █ █                           █ █   █ █         █ █   █ █

Racket[edit]

Translation of: Kotlin
#lang racket/base
;; {trans|Kotlin}}
 
(define current-width (make-parameter 81))
 
(define current-height (make-parameter 5))
 
(define (Cantor_set (w (current-width)) (h (current-height)))
(define lines (build-list h (λ (_) (make-bytes w (char->integer #\#)))))
(define (cantor start len index)
(let* ((seg (quotient len 3))
(seg-start (+ start seg))
(seg-end (+ seg-start seg)))
(unless (zero? seg)
(for* ((i (in-range index h))
(j (in-range seg-start seg-end)))
(bytes-set! (list-ref lines i) j (char->integer #\space)))
(cantor start seg (add1 index))
(cantor seg-end seg (add1 index)))))
(cantor 0 w 1)
lines)
 
(module+ main
(for-each displayln (Cantor_set)))
 
Output:
*********************************************************************************
***************************                           ***************************
*********         *********                           *********         *********
***   ***         ***   ***                           ***   ***         ***   ***
* *   * *         * *   * *                           * *   * *         * *   * *

Ring[edit]

 
# Project : Cantor set
# Date  : 2018/04/20
# Author : Gal Zsolt [~ CalmoSoft ~]
# Email  : <[email protected]>
 
load "guilib.ring"
paint = null
 
new qapp
{
win1 = new qwidget() {
setwindowtitle("")
setgeometry(100,100,800,600)
label1 = new qlabel(win1) {
setgeometry(10,10,800,600)
settext("")
}
new qpushbutton(win1) {
setgeometry(150,500,100,30)
settext("draw")
setclickevent("draw()")
}
show()
}
exec()
}
 
func draw
p1 = new qpicture()
color = new qcolor() {
setrgb(0,0,255,255)
}
pen = new qpen() {
setcolor(color)
setwidth(10)
}
paint = new qpainter() {
begin(p1)
setpen(pen)
 
cantor(10,20,600)
 
endpaint()
}
label1 { setpicture(p1) show() }
return
 
func cantor(x,y,lens)
if lens >= 10
paint.drawline(x,y,x+lens,y)
y = y + 20
cantor(x,y,floor(lens/3))
cantor(x+floor(lens*2/3),y,floor(lens/3))
ok
 

Output image:

Cantor set

Sidef[edit]

Translation of: Perl 6
func cantor (height) {
var width = 3**(height - 1)
var lines = height.of { "\N{FULL BLOCK}" * width }
 
func trim_middle_third (len, start, index) {
var seg = (len // 3) || return()
 
for i, j in ((index ..^ height) ~X (0 ..^ seg)) {
lines[i].replace!(Regex("^.{#{start + seg + j}}\\K."), ' ')
}
 
[0, 2*seg].each { |k|
trim_middle_third(seg, start + k, index + 1)
}
}
 
trim_middle_third(width, 0, 1)
return lines
}
 
cantor(5).each { .say }
Output:
█████████████████████████████████████████████████████████████████████████████████
███████████████████████████                           ███████████████████████████
█████████         █████████                           █████████         █████████
███   ███         ███   ███                           ███   ███         ███   ███
█ █   █ █         █ █   █ █                           █ █   █ █         █ █   █ █

zkl[edit]

const WIDTH=81, HEIGHT=5;
var lines=HEIGHT.pump(List,List.createLong(WIDTH,"\U2588;").copy); // full block
 
fcn cantor(start,len,index){
(seg:=len/3) or return();
foreach i,j in ([index..HEIGHT-1], [start + seg .. start + seg*2 - 1]){
lines[i][j]=" ";
}
cantor(start, seg, index + 1);
cantor(start + seg*2, seg, index + 1);
}(0,WIDTH,1);
 
lines.pump(Console.println,"concat");
Output:
█████████████████████████████████████████████████████████████████████████████████
███████████████████████████                           ███████████████████████████
█████████         █████████                           █████████         █████████
███   ███         ███   ███                           ███   ███         ███   ███
█ █   █ █         █ █   █ █                           █ █   █ █         █ █   █ █