Cantor set
Draw Cantor set. See details: Cantor set
ALGOL 68
<lang algol68>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</lang>
- Output:
################################################################################# ########################### ########################### ######### ######### ######### ######### ### ### ### ### ### ### ### ### # # # # # # # # # # # # # # # #
ALGOL W
Based on the Algol 68 sample. <lang algolw>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.</lang>
- Output:
################################################################################# ########################### ########################### ######### ######### ######### ######### ### ### ### ### ### ### ### ### # # # # # # # # # # # # # # # #
AWK
<lang AWK>
- 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)
} </lang>
- Output:
********************************************************************************* *************************** *************************** ********* ********* ********* ********* *** *** *** *** *** *** *** *** * * * * * * * * * * * * * * * *
C
<lang c>#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;
}</lang>
- Output:
********************************************************************************* *************************** *************************** ********* ********* ********* ********* *** *** *** *** *** *** *** *** * * * * * * * * * * * * * * * *
Go
<lang go>package main
import "fmt"
const (
width = 81 height = 5
)
var lines [height][width]byte
func init() {
for i := 0; i < height; i++ { for j := 0; j < width; j++ { lines[i][j] = '*' } }
}
func cantor(start, len, index int) {
seg := len / 3 if seg == 0 { return } for i := index; i < height; i++ { for j := start + seg; j < start + 2 * seg; j++ { lines[i][j] = ' ' } } cantor(start, seg, index + 1) cantor(start + seg * 2, seg, index + 1)
}
func main() {
cantor(0, width, 1) for _, line := range lines { fmt.Println(string(line[:])) }
}</lang>
- Output:
********************************************************************************* *************************** *************************** ********* ********* ********* ********* *** *** *** *** *** *** *** *** * * * * * * * * * * * * * * * *
Kotlin
Simple terminal drawing. <lang scala>// 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) }
}</lang>
- Output:
********************************************************************************* *************************** *************************** ********* ********* ********* ********* *** *** *** *** *** *** *** *** * * * * * * * * * * * * * * * *
Perl 6
<lang perl6>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);</lang>
- Output:
█████████████████████████████████████████████████████████████████████████████████ ███████████████████████████ ███████████████████████████ █████████ █████████ █████████ █████████ ███ ███ ███ ███ ███ ███ ███ ███ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
Racket
<lang racket>#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)))
</lang>
- Output:
********************************************************************************* *************************** *************************** ********* ********* ********* ********* *** *** *** *** *** *** *** *** * * * * * * * * * * * * * * * *
Ring
<lang ring>
- Project : Cantor set
- Date : 2018/04/20
- Author : Gal Zsolt [~ CalmoSoft ~]
- Email : <calmosoft@gmail.com>
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
</lang> Output image:
Sidef
<lang ruby>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 }</lang>
- Output:
█████████████████████████████████████████████████████████████████████████████████ ███████████████████████████ ███████████████████████████ █████████ █████████ █████████ █████████ ███ ███ ███ ███ ███ ███ ███ ███ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
zkl
<lang zkl>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");</lang>
- Output:
█████████████████████████████████████████████████████████████████████████████████ ███████████████████████████ ███████████████████████████ █████████ █████████ █████████ █████████ ███ ███ ███ ███ ███ ███ ███ ███ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █