Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

View file

@ -0,0 +1,2 @@
---
from: http://rosettacode.org/wiki/Cantor_set

View file

@ -0,0 +1,6 @@
;Task:
Draw a Cantor set.
See details at this Wikipedia webpage:   [https://en.wikipedia.org/wiki/Cantor_set Cantor set]
<br><br>

View file

@ -0,0 +1,22 @@
V WIDTH = 81
V HEIGHT = 5
F cantor(start, len, index)
V seg = len I/ 3
I seg == 0
R
L(it) 0 .< :HEIGHT - index
V i = index + it
L(jt) 0 .< seg
V j = start + seg + jt
V pos = i * :WIDTH + j
:lines[pos] =
cantor(start, seg, index + 1)
cantor(start + seg * 2, seg, index + 1)
V lines = [*] * (WIDTH * HEIGHT)
cantor(0, WIDTH, 1)
L(i) 0 .< HEIGHT
V beg = WIDTH * i
print((lines[beg .< beg + WIDTH]).join())

View file

@ -0,0 +1,27 @@
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

View file

@ -0,0 +1,34 @@
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.

View file

@ -0,0 +1,30 @@
# 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)
}

View file

@ -0,0 +1,52 @@
PROC FillRect(INT x,y,w,h)
INT i
FOR i=y TO y+h-1
DO
Plot(x,i)
DrawTo(x+w-1,i)
OD
RETURN
PROC DrawCantor(INT x0,y0,h,level)
INT x,y,i,j,w,w2,h2
w=1
FOR i=0 TO level-1
DO w==*3 OD
Color=1
y=y0
FOR i=0 TO level
DO
FillRect(x0,y,w,h)
y==+h*2
OD
Color=0
w2=1 h2=h*2
FOR i=0 TO level-1
DO
x=w2 y=(level-i)*(h*2)
WHILE x<w
DO
FillRect(x0+x,y0+y,w2,h2)
x==+w2*2
OD
w2==*3
h2==+h*2
OD
RETURN
PROC Main()
BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6
Graphics(8+16)
COLOR1=$0C
COLOR2=$02
DrawCantor(38,48,8,5)
DO UNTIL CH#$FF OD
CH=$FF
RETURN

View file

@ -0,0 +1,24 @@
with Ada.Text_IO;
procedure Cantor_Set is
subtype Level_Range is Integer range 1 .. 5;
Image : array (Level_Range) of String (1 .. 81) := (others => (others => ' '));
procedure Cantor (Level : Natural; Length : Natural; Start : Natural) is
begin
if Level in Level_Range then
Image (Level) (Start .. Start + Length - 1) := (others => '*');
Cantor (Level + 1, Length / 3, Start);
Cantor (Level + 1, Length / 3, Start + 2 * Length / 3);
end if;
end Cantor;
begin
Cantor (Level => Level_Range'First,
Length => 81,
Start => 1);
for L in Level_Range loop
Ada.Text_IO.Put_Line (Image (L));
end loop;
end Cantor_Set;

View file

@ -0,0 +1,163 @@
------------------------- CANTOR SET -----------------------
-- cantor :: [String] -> [String]
on cantor(xs)
script go
on |λ|(s)
set m to (length of s) div 3
set blocks to text 1 thru m of s
if "█" = text 1 of s then
{blocks, replicate(m, space), blocks}
else
{s}
end if
end |λ|
end script
concatMap(go, xs)
end cantor
---------------------------- TEST --------------------------
on run
showCantor(5)
end run
-- showCantor :: Int -> String
on showCantor(n)
unlines(map(my concat, ¬
take(n, iterate(cantor, ¬
{replicate(3 ^ (n - 1), "█")}))))
end showCantor
--------------------- GENERIC FUNCTIONS --------------------
-- concat :: [[a]] -> [a]
-- concat :: [String] -> String
on concat(xs)
set lng to length of xs
if 0 < lng and string is class of (item 1 of xs) then
set acc to ""
else
set acc to {}
end if
repeat with i from 1 to lng
set acc to acc & item i of xs
end repeat
acc
end concat
-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
set lng to length of xs
set acc to {}
tell mReturn(f)
repeat with i from 1 to lng
set acc to acc & |λ|(item i of xs, i, xs)
end repeat
end tell
return acc
end concatMap
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- iterate :: (a -> a) -> a -> Gen [a]
on iterate(f, x)
script
property v : missing value
property g : mReturn(f)'s |λ|
on |λ|()
if missing value is v then
set v to x
else
set v to g(v)
end if
return v
end |λ|
end script
end iterate
-- replicate :: Int -> String -> String
on replicate(n, s)
set out to ""
if n < 1 then return out
set dbl to s
repeat while (n > 1)
if (n mod 2) > 0 then set out to out & dbl
set n to (n div 2)
set dbl to (dbl & dbl)
end repeat
return out & dbl
end replicate
-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
set c to class of xs
if list is c then
if 0 < n then
items 1 thru min(n, length of xs) of xs
else
{}
end if
else if string is c then
if 0 < n then
text 1 thru min(n, length of xs) of xs
else
""
end if
else if script is c then
set ys to {}
repeat with i from 1 to n
set v to xs's |λ|()
if missing value is v then
return ys
else
set end of ys to v
end if
end repeat
return ys
else
missing value
end if
end take
-- unlines :: [String] -> String
on unlines(xs)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set str to xs as text
set my text item delimiters to dlm
str
end unlines

View file

@ -0,0 +1,21 @@
width: 81
height: 5
lines: array.of: height repeat `*` width
cantor: function [start length idx].export:[lines][
seg: length / 3
if seg = 0 -> return null
loop idx..dec height 'i [
loop (start + seg).. dec start + 2 * seg 'j
-> set lines\[i] j ` `
]
cantor start seg idx+1
cantor start + 2 * seg seg idx+1
]
cantor 0 width 1
loop lines 'line
-> print join line

View file

@ -0,0 +1,14 @@
10 DEFINT A-Z
20 N = 4
30 W = 3^(N-1)
40 S = W
50 L$ = STRING$(W, "#")
60 PRINT L$
70 IF S = 1 THEN END
80 S = S\3
90 P = 1
100 IF P >= W-S GOTO 60
110 P = P+S
120 MID$(L$,P,S) = SPACE$(S)
130 P = P+S
140 GOTO 100

View file

@ -0,0 +1,33 @@
global ancho, alto, intervalo
ancho = 81 : alto = 5
dim intervalo(alto, ancho)
subroutine Cantor()
for i = 0 to alto - 1
for j = 0 to ancho - 1
intervalo[i, j] = "■"
next j
next i
end subroutine
subroutine ConjCantor(inicio, longitud, indice)
segmento = longitud / 3
if segmento = 0 then return
for i = indice to alto - 1
for j = inicio + segmento to inicio + segmento * 2 - 1
intervalo[i, j] = " "
next j
next i
call ConjCantor(inicio, segmento, indice + 1)
call ConjCantor(inicio + segmento * 2, segmento, indice + 1)
end subroutine
call Cantor()
call ConjCantor(0, ancho, 1)
for i = 0 to alto - 1
for j = 0 to ancho - 1
print intervalo[i, j];
next j
print
next i
End

View file

@ -0,0 +1 @@
Cantor {" •" ˜ >¨(¯1¨¨)101(𝕩)1}

View file

@ -0,0 +1,36 @@
#include <iostream>
const int WIDTH = 81;
const int HEIGHT = 5;
char lines[WIDTH*HEIGHT];
void cantor(int start, int len, int index) {
int seg = len / 3;
if (seg == 0) return;
for (int i = index; i < HEIGHT; i++) {
for (int j = start + seg; j < start + seg * 2; j++) {
int pos = i * WIDTH + j;
lines[pos] = ' ';
}
}
cantor(start, seg, index + 1);
cantor(start + 2 * seg, seg, index + 1);
}
int main() {
// init
for (int i = 0; i < WIDTH*HEIGHT; i++) {
lines[i] = '*';
}
// calculate
cantor(0, WIDTH, 1);
// print
for (int i = 0; i < HEIGHT*WIDTH; i += WIDTH) {
printf("%.*s\n", WIDTH, lines + i);
}
return 0;
}

View file

@ -0,0 +1,39 @@
using System;
namespace CantorSet {
class Program {
const int WIDTH = 81;
const int HEIGHT = 5;
private static char[,] lines = new char[HEIGHT, WIDTH];
static Program() {
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
lines[i, j] = '*';
}
}
}
private static void Cantor(int start, int len, int index) {
int seg = len / 3;
if (seg == 0) return;
for (int i = index; i < HEIGHT; i++) {
for (int j = start + seg; j < start + seg * 2; j++) {
lines[i, j] = ' ';
}
}
Cantor(start, seg, index + 1);
Cantor(start + seg * 2, seg, index + 1);
}
static void Main(string[] args) {
Cantor(0, WIDTH, 1);
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
Console.Write(lines[i,j]);
}
Console.WriteLine();
}
}
}
}

View file

@ -0,0 +1,38 @@
#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;
}

View file

@ -0,0 +1,33 @@
cantor = cluster is make
rep = null
ac = array[char]
aac = array[array[char]]
make = proc (width, height: int, ch: char) returns (string)
lines: aac := aac$fill_copy(0, height, ac$fill(0, width, ch))
cantor_step(lines, 0, width, 1)
s: stream := stream$create_output()
for line: ac in aac$elements(lines) do
stream$putl(s, string$ac2s(line))
end
return(stream$get_contents(s))
end make
cantor_step = proc (lines: aac, start, len, index: int)
seg: int := len / 3
if seg = 0 then return end
for i: int in int$from_to(index, aac$high(lines)) do
for j: int in int$from_to(start+seg, start+seg*2-1) do
lines[i][j] := ' '
end
end
cantor_step(lines, start, seg, index+1)
cantor_step(lines, start+seg*2, seg, index+1)
end cantor_step
end cantor
start_up = proc ()
po: stream := stream$primary_output()
cs: string := cantor$make(81, 5, '*')
stream$puts(po, cs)
end start_up

View file

@ -0,0 +1,48 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. CANTOR.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 SETTINGS.
03 NUM-LINES PIC 9 VALUE 5.
03 FILL-CHAR PIC X VALUE '#'.
01 VARIABLES.
03 CUR-LINE.
05 CHAR PIC X OCCURS 81 TIMES.
03 WIDTH PIC 99.
03 CUR-SIZE PIC 99.
03 POS PIC 99.
03 MAXPOS PIC 99.
03 NEXTPOS PIC 99.
03 I PIC 99.
PROCEDURE DIVISION.
BEGIN.
COMPUTE WIDTH = 3 ** (NUM-LINES - 1).
PERFORM INIT.
MOVE WIDTH TO CUR-SIZE.
DISPLAY CUR-LINE.
PERFORM DO-LINE UNTIL CUR-SIZE IS EQUAL TO 1.
STOP RUN.
INIT.
PERFORM INIT-CHAR VARYING I FROM 1 BY 1
UNTIL I IS GREATER THAN WIDTH.
INIT-CHAR.
MOVE FILL-CHAR TO CHAR(I).
DO-LINE.
DIVIDE 3 INTO CUR-SIZE.
MOVE 1 TO POS.
SUBTRACT CUR-SIZE FROM WIDTH GIVING MAXPOS.
PERFORM BLANK-REGIONS UNTIL POS IS GREATER THAN MAXPOS.
DISPLAY CUR-LINE.
BLANK-REGIONS.
ADD CUR-SIZE TO POS.
PERFORM BLANK-CHAR CUR-SIZE TIMES.
BLANK-CHAR.
MOVE SPACE TO CHAR(POS).
ADD 1 TO POS.

View file

@ -0,0 +1,33 @@
import std.stdio;
enum WIDTH = 81;
enum HEIGHT = 5;
char[WIDTH*HEIGHT] lines;
void cantor(int start, int len, int index) {
int seg = len / 3;
if (seg == 0) return;
for (int i=index; i<HEIGHT; i++) {
for (int j=start+seg; j<start+seg*2; j++) {
int pos = i*WIDTH + j;
lines[pos] = ' ';
}
}
cantor(start, seg, index+1);
cantor(start+seg*2, seg, index+1);
}
void main() {
// init
lines[] = '*';
// calculate
cantor(0, WIDTH, 1);
// print
for (int i=0; i<HEIGHT; i++) {
int beg = WIDTH * i;
writeln(lines[beg..beg+WIDTH]);
}
}

View file

@ -0,0 +1,49 @@
program Cantor_set;
{$APPTYPE CONSOLE}
const
WIDTH: Integer = 81;
HEIGHT: Integer = 5;
var
Lines: TArray<TArray<Char>>;
procedure Init;
var
i, j: Integer;
begin
SetLength(lines, HEIGHT, WIDTH);
for i := 0 to HEIGHT - 1 do
for j := 0 to WIDTH - 1 do
lines[i, j] := '*';
end;
procedure Cantor(start, len, index: Integer);
var
seg, i, j: Integer;
begin
seg := len div 3;
if seg = 0 then
Exit;
for i := index to HEIGHT - 1 do
for j := start + seg to start + seg * 2 - 1 do
lines[i, j] := ' ';
Cantor(start, seg, index + 1);
Cantor(start + seg * 2, seg, index + 1);
end;
var
i, j: Integer;
begin
Init;
Cantor(0, WIDTH, 1);
for i := 0 to HEIGHT - 1 do
begin
for j := 0 to WIDTH - 1 do
Write(lines[i, j]);
Writeln;
end;
Readln;
end.

View file

@ -0,0 +1,17 @@
int WIDTH = 81
int HEIGHT = 5
List lines = text[].with(HEIGHT) # a list with HEIGHT empty texts
for each int i in range(0, HEIGHT) do lines[i] = text("█", WIDTH) end
fun cantor = void by int start, int len, int index
int seg = len / 3
if seg == 0 do return end
for int i = index; i < HEIGHT; i++
for int j = start + seg; j < start + seg * 2; j++
lines[i][j] = " "
end
end
cantor(start, seg, index + 1)
cantor(start + seg * 2, seg, index + 1)
end
cantor(0, WIDTH, 1)
for each text line in lines do writeLine(line) end

View file

@ -0,0 +1,30 @@
defmodule Cantor do
@pos "█"
@neg " "
def run(lines) do
Enum.map(0..lines, fn line ->
segment_size = 3 ** (lines - line - 1)
chars = (3 ** line)
Enum.map(0..chars, fn char ->
char
|> Integer.digits(3)
|> Enum.any?(fn x -> x === 1 end)
|> case do
true -> @neg
false -> @pos
end
end)
|> Enum.reduce([], fn el, acc -> duplicate_char(acc, el, segment_size) end)
|> Enum.join()
|> String.trim_trailing()
end)
|> Enum.filter(fn line -> line !== "" end)
end
def duplicate_char(acc, el, segment_size) when segment_size >= 1, do: acc ++ [String.duplicate(el, segment_size)]
def duplicate_char(acc, _el, segment_size) when segment_size < 1, do: acc
end
Cantor.run(5) |> IO.inspect()

View file

@ -0,0 +1,90 @@
CANTOR
=LAMBDA(n,
APPLYN(n)(
LAMBDA(grid,
APPENDROWS(grid)(
CANTOROW(
LASTROW(grid)
)
)
)
)({0,1})
)
CANTOROW
=LAMBDA(xys,
LET(
nCols, COLUMNS(xys),
IF(2 > nCols,
xys,
IF(3 < nCols,
APPENDCOLS(
CANTORSLICES(TAKECOLS(2)(xys))
)(
CANTOROW(DROPCOLS(2)(xys))
),
CANTORSLICES(TAKECOLS(2)(xys))
)
)
)
)
CANTORSLICES
=LAMBDA(ab,
LET(
a, INDEX(ab, 1),
b, INDEX(ab, 2),
third, (b - a) / 3,
CHOOSE({1,2,3,4}, a, a + third, b - third, b)
)
)
SHOWCANTOR
=LAMBDA(grid,
LET(
leaves, LASTROW(grid),
leafWidth, INDEX(leaves, 1, 2) - INDEX(leaves, 1, 1),
leafCount, 1 / leafWidth,
SHOWCANTROWS(leafCount)(grid)
)
)
SHOWCANTROWS
=LAMBDA(leafCount,
LAMBDA(grid,
LET(
xs, FILTERP(
LAMBDA(x, NOT(ISNA(x)))
)(
HEADCOL(grid)
),
runLengths, LAMBDA(x,
CEILING.MATH(leafCount * x))(
SUBTRACT(TAILROW(xs))(INITROW(xs)
)
),
iCols, SEQUENCE(1, COLUMNS(runLengths)),
CONCAT(
REPT(
IF(ISEVEN(iCols), " ", "█"),
runLengths
)
) & IF(1 < ROWS(grid),
CHAR(10) & SHOWCANTROWS(leafCount)(
TAILCOL(grid)
),
""
)
)
)
)

View file

@ -0,0 +1,157 @@
APPENDCOLS
=LAMBDA(xs,
LAMBDA(ys,
LET(
nx, COLUMNS(xs),
ny, COLUMNS(ys),
colIndexes, SEQUENCE(1, nx + ny),
rowIndexes, SEQUENCE(MAX(ROWS(xs), ROWS(ys))),
IFERROR(
IF(nx < colIndexes,
INDEX(ys, rowIndexes, colIndexes - nx),
INDEX(xs, rowIndexes, colIndexes)
),
NA()
)
)
)
)
APPENDROWS
=LAMBDA(xs,
LAMBDA(ys,
LET(
nx, ROWS(xs),
rowIndexes, SEQUENCE(nx + ROWS(ys)),
colIndexes, SEQUENCE(
1,
MAX(COLUMNS(xs), COLUMNS(ys))
),
IFERROR(
IF(rowIndexes <= nx,
INDEX(xs, rowIndexes, colIndexes),
INDEX(ys, rowIndexes - nx, colIndexes)
),
NA()
)
)
)
)
APPLYN
=LAMBDA(n,
LAMBDA(f,
LAMBDA(x,
IF(0 < n,
APPLYN(n - 1)(f)(
f(x)
),
x
)
)
)
)
DROPCOLS
=LAMBDA(n,
LAMBDA(xs,
INDEX(
xs,
SEQUENCE(ROWS(xs), 1),
SEQUENCE(1, (COLUMNS(xs) - n), 1 + n, 1)
)
)
)
FILTERP
=LAMBDA(p,
LAMBDA(xs,
FILTER(xs, p(xs))
)
)
HEADCOL
=LAMBDA(xs,
LET(REM, "The first item of each column in xs",
INDEX(xs, 1, SEQUENCE(1, COLUMNS(xs)))
)
)
INITROW
=LAMBDA(xs,
INDEX(
xs,
SEQUENCE(
1,
COLUMNS(xs) - 1,
1, 1
)
)
)
LASTROW
=LAMBDA(xs,
INDEX(
xs,
ROWS(xs),
SEQUENCE(1, COLUMNS(xs), 1, 1)
)
)
SUBTRACT
=LAMBDA(a,
LAMBDA(b, a - b)
)
TAILCOL
=LAMBDA(cols,
LET(REM, "The tail of each column in the grid.",
INDEX(
cols,
SEQUENCE(ROWS(cols) - 1, 1, 2, 1),
SEQUENCE(1, COLUMNS(cols))
)
)
)
TAILROW
=LAMBDA(xs,
LET(REM,"The tail of each row in the grid",
n, COLUMNS(xs) - 1,
IF(0 < n,
INDEX(
xs,
SEQUENCE(ROWS(xs), 1, 1, 1),
SEQUENCE(1, n, 2, 1)
),
NA()
)
)
)
TAKECOLS
=LAMBDA(n,
LAMBDA(xs,
INDEX(
xs,
SEQUENCE(ROWS(xs)),
SEQUENCE(1, n)
)
)
)

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,2 @@
███
█ █

View file

@ -0,0 +1,3 @@
█████████
███ ███
█ █ █ █

View file

@ -0,0 +1,4 @@
███████████████████████████
█████████ █████████
███ ███ ███ ███
█ █ █ █ █ █ █ █

View file

@ -0,0 +1,23 @@
USING: grouping.extras io kernel math sequences
sequences.repeating ;
IN: rosetta-code.cantor-set
CONSTANT: width 81
CONSTANT: depth 5
: cantor ( n -- seq )
dup 0 = [ drop { 0 1 } ]
[ 1 - cantor [ 3 / ] map dup [ 2/3 + ] map append ] if ;
! Produces a sequence of lengths from a Cantor set, depending on
! width. Even indices are solid; odd indices are blank.
! e.g. 2 cantor gaps -> { 9 9 9 27 9 9 9 }
!
: gaps ( seq -- seq )
[ width * ] map [ - abs ] 2clump-map ;
: print-cantor ( n -- )
cantor gaps [ even? "#" " " ? swap repeat ] map-index
concat print ;
depth <iota> [ print-cantor ] each

View file

@ -0,0 +1,26 @@
warnings off
4 \ iterations
: ** 1 swap 0 ?DO over * LOOP nip ;
3 swap ** constant width \ Make smallest step 1
create string here width char # fill width allot
: print string width type cr ;
\ Overwrite string with new holes of size 'length'.
\ Pointer into string at TOS.
create length width ,
: reduce length dup @ 3 / swap ! ;
: done? dup string - width >= ;
: hole? dup c@ bl = ;
: skip length @ + ;
: whipe dup length @ bl fill skip ;
: step hole? IF skip skip skip ELSE skip whipe skip THEN ;
: split reduce string BEGIN step done? UNTIL drop ;
\ Main
: done? length @ 1 <= ;
: step split print ;
: go print BEGIN step done? UNTIL ;
go bye

View file

@ -0,0 +1,36 @@
Const ancho = 81
Const alto = 5
Dim Shared intervalo(alto, ancho) As String
Dim As Integer i, j
Sub Cantor()
Dim As Integer i, j
For i = 0 To alto - 1
For j = 0 To ancho - 1
intervalo(i, j) = Chr(254)
Next j
Next i
End Sub
Sub ConjCantor(inicio As Integer, longitud As Integer, indice As Integer)
Dim As Integer i, j
Dim segmento As Integer = longitud / 3
If segmento = 0 Then Return
For i = indice To alto - 1
For j = inicio + segmento To inicio + segmento * 2 - 1
intervalo(i, j) = Chr(32)
Next j
Next i
ConjCantor(inicio, segmento, indice + 1)
ConjCantor(inicio + segmento * 2, segmento, indice + 1)
End Sub
Cantor()
ConjCantor(0, ancho, 1)
For i = 0 To alto - 1
For j = 0 To ancho - 1
Print intervalo(i, j);
Next j
Print
Next i
End

View file

@ -0,0 +1,48 @@
_window = 1
_width = 81
_height = 5
window _window, @"FutureBasic Cantor Set", ( 0, 0, 695, 100 )
WindowSetBackgroundColor( _window, fn ColorWhite )
text @"Menlo", 14.0, fn ColorRed
begin globals
CFStringRef gInterval( _height, _width )
end globals
local fn Init
NSInteger i, j
for i = 0 to _height - 1
for j = 0 to _width - 1
gInterval( i, j ) = @"◼︎"
next
next
end fn
local fn CantorSet( start as NSInteger, length as NSInteger, index as NSInteger )
NSInteger i, j, segment = length / 3
if segment == 0 then exit fn
for i = index to _height - 1
for j = start + segment to start + segment * 2 - 1
gInterval( i, j ) = @" "
next
next
fn CantorSet( start, segment, index + 1 )
fn CantorSet( start + segment * 2, segment, index + 1 )
end fn
NSInteger i, j
fn Init
fn CantorSet ( 0, _width, 1 )
for i = 0 to _height - 1
for j = 0 to _width - 1
print gInterval( i, j );
next
print
next
HandleEvents

View file

@ -0,0 +1,39 @@
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[:]))
}
}

View file

@ -0,0 +1,36 @@
class App {
private static final int WIDTH = 81
private static final int HEIGHT = 5
private static char[][] lines
static {
lines = new char[HEIGHT][WIDTH]
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
lines[i][j] = '*'
}
}
}
private static void cantor(int start, int len, int index) {
int seg = (int) (len / 3)
if (seg == 0) return
for (int i = index; i < HEIGHT; i++) {
for (int j = start + seg; j < start + seg * 2; j++) {
lines[i][j] = ' '
}
}
cantor(start, seg, index + 1)
cantor(start + seg * 2, seg, index + 1)
}
static void main(String[] args) {
cantor(0, WIDTH, 1)
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
System.out.print(lines[i][j])
}
System.out.println()
}
}
}

View file

@ -0,0 +1,27 @@
-------------------------- CANTOR ------------------------
cantor :: [(Bool, Int)] -> [(Bool, Int)]
cantor = concatMap go
where
go (bln, n)
| bln && 1 < n =
let m = quot n 3
in [(True, m), (False, m), (True, m)]
| otherwise = [(bln, n)]
--------------------------- TEST -------------------------
main :: IO ()
main = putStrLn $ cantorLines 5
------------------------- DISPLAY ------------------------
cantorLines :: Int -> String
cantorLines n =
unlines $
showCantor
<$> take n (iterate cantor [(True, 3 ^ pred n)])
showCantor :: [(Bool, Int)] -> String
showCantor = concatMap $ uncurry (flip replicate . c)
where
c True = '*'
c False = ' '

View file

@ -0,0 +1,30 @@
-------------------------- CANTOR ------------------------
cantor :: [String] -> [String]
cantor = (go =<<)
where
go x
| '█' == head x = [block, replicate m ' ', block]
| otherwise = [x]
where
m = quot (length x) 3
block = take m x
--------------------------- TEST -------------------------
main :: IO ()
main = putStrLn $ cantorLines 5
------------------------- DISPLAY ------------------------
cantorLines :: Int -> String
cantorLines =
unlines . (concat <$>)
. ( take
<*> ( iterate cantor
. return
. flip replicate '█'
. (3 ^)
. pred
)
)

View file

@ -0,0 +1,59 @@
import Control.Monad (join)
import Data.Bifunctor (bimap)
import Data.List (intercalate, mapAccumL, maximumBy)
import Data.Ratio (Ratio, denominator, numerator, (%))
-------------------------- CANTOR ------------------------
cantor :: (Rational, Rational) -> [[(Rational, Rational)]]
cantor = iterate (go =<<) . pure
where
go (x, y) = [(x, x + r), (y - r, y)]
where
r = (y - x) / 3
--------------------------- TEST -------------------------
main :: IO ()
main =
( ( (>>)
. putStrLn
. unlines
. fmap intervalRatios
)
<*> (putStrLn . intervalBars)
)
$ take 4 $ cantor (0, 1)
------------------------- DISPLAY ------------------------
intervalBars :: [[(Rational, Rational)]] -> String
intervalBars xs = unlines $ go (d % 1) <$> xs
where
d = maximum $ denominator . fst <$> last xs
go w xs =
concat . snd $
mapAccumL
( \a (rx, ry) ->
let (wy, wx) = (w * ry, w * rx)
in ( wy,
replicate (floor (wx - a)) ' '
<> replicate (floor (wy - wx)) '█'
)
)
0
xs
intervalRatios :: [(Rational, Rational)] -> String
intervalRatios =
('(' :) . (<> ")")
. intercalate ") ("
. fmap
(uncurry ((<>) . (<> ", ")) . join bimap showRatio)
showRatio :: Rational -> String
showRatio = ((<>) . show . numerator) <*> (go . denominator)
where
go x
| 1 /= x = '/' : show x
| otherwise = []

View file

@ -0,0 +1,11 @@
100 PROGRAM "Cantor.bas"
110 GRAPHICS HIRES 2
120 SET PALETTE BLACK,WHITE
130 CALL CANTOR(28,500,1216,32)
140 DEF CANTOR(X,Y,L,HEIGHT)
150 IF L>3 THEN
160 PLOT X,Y;X+L,Y,X,Y+4;X+L,Y+4
170 CALL CANTOR(X,Y-HEIGHT,L/3,HEIGHT)
180 CALL CANTOR(X+2*L/3,Y-HEIGHT,L/3,HEIGHT)
190 END IF
200 END DEF

View file

@ -0,0 +1,8 @@
odometer =: [: (4 $. $.) $&1
cantor_dust =: monad define
shape =. ,~ 3 ^ y
a =. shape $ ' '
i =. odometer shape
< (}:"1) 1j1 #"1 '#' (([: <"1 [: ;/"1 (#~ 1 e."1 [: (,/"2) 3 3&#:)) i)}a
)

View file

@ -0,0 +1,6 @@
cantor_dust =: 2&$: :(dyad define)
shape =. x # 3 ^ y
a =. shape $ ' '
i =. odometer shape
< (}:"1) 1j1 #"1 '#' (([: <"1 [: ;/"1 (#~ 1 e."1 [: (,/"2) 3 3&#:)) i)} a
)

View file

@ -0,0 +1,36 @@
public class App {
private static final int WIDTH = 81;
private static final int HEIGHT = 5;
private static char[][] lines;
static {
lines = new char[HEIGHT][WIDTH];
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
lines[i][j] = '*';
}
}
}
private static void cantor(int start, int len, int index) {
int seg = len / 3;
if (seg == 0) return;
for (int i = index; i < HEIGHT; i++) {
for (int j = start + seg; j < start + seg * 2; j++) {
lines[i][j] = ' ';
}
}
cantor(start, seg, index + 1);
cantor(start + seg * 2, seg, index + 1);
}
public static void main(String[] args) {
cantor(0, WIDTH, 1);
for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
System.out.print(lines[i][j]);
}
System.out.println();
}
}
}

View file

@ -0,0 +1,88 @@
(() => {
"use strict";
// -------------- CANTOR BOOL-INT PAIRS --------------
// cantor :: [(Bool, Int)] -> [(Bool, Int)]
const cantor = xs => {
const go = ([bln, n]) =>
bln && 1 < n ? (() => {
const x = Math.floor(n / 3);
return [
[true, x],
[false, x],
[true, x]
];
})() : [
[bln, n]
];
return xs.flatMap(go);
};
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () =>
cantorLines(5);
// --------------------- DISPLAY ---------------------
// cantorLines :: Int -> String
const cantorLines = n =>
take(n)(
iterate(cantor)([
[true, 3 ** (n - 1)]
])
)
.map(showCantor)
.join("\n");
// showCantor :: [(Bool, Int)] -> String
const showCantor = xs =>
xs.map(
([bln, n]) => (
bln ? (
"*"
) : " "
).repeat(n)
)
.join("");
// ---------------- GENERIC FUNCTIONS ----------------
// iterate :: (a -> a) -> a -> Gen [a]
const iterate = f =>
// An infinite list of repeated
// applications of f to x.
function* (x) {
let v = x;
while (true) {
yield v;
v = f(v);
}
};
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => "GeneratorFunction" !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat(...Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
// MAIN ---
return main();
})();

View file

@ -0,0 +1,72 @@
(() => {
"use strict";
// ----------------- CANTOR STRINGS ------------------
// cantor :: [String] -> [String]
const cantor = xs => {
const go = s => {
const
m = Math.floor(s.length / 3),
blocks = take(m)(s);
return "█" === s[0] ? (
[blocks, " ".repeat(m), blocks]
) : [s];
};
return xs.flatMap(go);
};
// ---------------------- TEST -----------------------
const main = () =>
showCantor(5);
// --------------------- DISPLAY ---------------------
// showCantor :: Int -> String
const showCantor = n =>
take(n)(
iterate(cantor)([
"█".repeat(3 ** (n - 1))
])
)
.map(x => x.join(""))
.join("\n");
// ---------------- GENERIC FUNCTIONS ----------------
// iterate :: (a -> a) -> a -> Gen [a]
const iterate = f =>
// An infinite list of repeated
// applications of f to x.
function* (x) {
let v = x;
while (true) {
yield v;
v = f(v);
}
};
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => "GeneratorFunction" !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat(...Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
// MAIN ---
return main();
})();

View file

@ -0,0 +1,387 @@
(() => {
"use strict";
// -------------- CANTOR RATIONAL PAIRS --------------
// cantor :: [(Rational, Rational)] ->
// [(Rational, Rational)]
const cantor = xs => {
const go = ab => {
const [r1, r2] = Array.from(ab).map(rational);
const third = ratioDiv(ratioMinus(r2)(r1))(3);
return [
Tuple(r1)(ratioPlus(r1)(third)),
Tuple(ratioMinus(r2)(third))(r2)
];
};
return xs.flatMap(go);
};
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () => {
const
xs = take(4)(
iterate(cantor)([Tuple(0)(1)])
);
return [
`${unlines(xs.map(intervalRatios))}\n`,
intervalBars(xs)
]
.join("\n\n");
};
// --------------------- DISPLAY ---------------------
// intervalRatios :: [(Rational, Rational)] -> String
const intervalRatios = xs => {
const go = ab =>
Array.from(ab).map(
compose(showRatio, rational)
)
.join(", ");
return `(${xs.map(go).join(") (")})`;
};
// intervalBars :: [[(Rational, Rational)]] -> String
const intervalBars = rs => {
const go = w => xs =>
snd(mapAccumL(
a => ab => {
const [wx, wy] = Array.from(ab).map(
r => ratioMult(w)(
rational(r)
)
);
return Tuple(wy)(
replicateString(
floor(ratioMinus(wx)(a))
)(" ") + replicateString(
floor(ratioMinus(wy)(wx))
)("█")
);
}
)(0)(xs)).join("");
const d = maximum(
last(rs).map(x => fst(x).d)
);
return unlines(rs.map(
go(Ratio(d)(1))
));
};
// ---------------- GENERIC FUNCTIONS ----------------
// Ratio :: Integral a => a -> a -> Ratio a
const Ratio = a => b => {
const go = (x, y) =>
0 !== y ? (() => {
const d = gcd(x)(y);
return {
type: "Ratio",
// numerator
"n": Math.trunc(x / d),
// denominator
"d": Math.trunc(y / d)
};
})() : undefined;
return go(a * signum(b), abs(b));
};
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: "Tuple",
"0": a,
"1": b,
length: 2
});
// abs :: Num -> Num
const abs =
// Absolute value of a given number
// without the sign.
x => 0 > x ? (
-x
) : x;
// approxRatio :: Float -> Float -> Ratio
const approxRatio = eps =>
n => {
const
gcde = (e, x, y) => {
const _gcd = (a, b) =>
b < e ? (
a
) : _gcd(b, a % b);
return _gcd(Math.abs(x), Math.abs(y));
},
c = gcde(Boolean(eps) ? (
eps
) : (1 / 10000), 1, n);
return Ratio(
Math.floor(n / c)
)(
Math.floor(1 / c)
);
};
// floor :: Num -> Int
const floor = x => {
const
nr = (
"Ratio" !== x.type ? (
properFraction
) : properFracRatio
)(x),
n = nr[0];
return 0 > nr[1] ? n - 1 : n;
};
// fst :: (a, b) -> a
const fst = ab =>
// First member of a pair.
ab[0];
// gcd :: Integral a => a -> a -> a
const gcd = x =>
y => {
const zero = x.constructor(0);
const go = (a, b) =>
zero === b ? (
a
) : go(b, a % b);
return go(abs(x), abs(y));
};
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
// iterate :: (a -> a) -> a -> Gen [a]
const iterate = f =>
// An infinite list of repeated
// applications of f to x.
function* (x) {
let v = x;
while (true) {
yield v;
v = f(v);
}
};
// last :: [a] -> a
const last = xs =>
// The last item of a list.
0 < xs.length ? (
xs.slice(-1)[0]
) : null;
// lcm :: Int -> Int -> Int
const lcm = x =>
// The smallest positive integer divisible
// without remainder by both x and y.
y => (x === 0 || y === 0) ? (
0
) : Math.abs(Math.floor(x / gcd(x)(y)) * y);
// mapAccumL :: (acc -> x -> (acc, y)) ->
// acc -> [x] -> (acc, [y])
const mapAccumL = f =>
// A tuple of an accumulation and a list
// obtained by a combined map and fold,
// with accumulation from left to right.
acc => xs => [...xs].reduce(
(a, x) => {
const ab = f(a[0])(x);
return [ab[0], a[1].concat(ab[1])];
},
[acc, []]
);
// maximum :: Ord a => [a] -> a
const maximum = xs => (
// The largest value in a non-empty list.
ys => 0 < ys.length ? (
ys.slice(1).reduce(
(a, y) => y > a ? (
y
) : a, ys[0]
)
) : undefined
)(xs);
// properFracRatio :: Ratio -> (Int, Ratio)
const properFracRatio = nd => {
const [q, r] = Array.from(quotRem(nd.n)(nd.d));
return Tuple(q)(Ratio(r)(nd.d));
};
// properFraction :: Real -> (Int, Real)
const properFraction = n => {
const i = Math.floor(n) + (n < 0 ? 1 : 0);
return Tuple(i)(n - i);
};
// quotRem :: Integral a => a -> a -> (a, a)
const quotRem = m =>
// The quotient, tupled with the remainder.
n => Tuple(
Math.trunc(m / n)
)(
m % n
);
// ratioDiv :: Rational -> Rational -> Rational
const ratioDiv = n1 => n2 => {
const [r1, r2] = [n1, n2].map(rational);
return Ratio(r1.n * r2.d)(
r1.d * r2.n
);
};
// ratioMinus :: Rational -> Rational -> Rational
const ratioMinus = n1 => n2 => {
const [r1, r2] = [n1, n2].map(rational);
const d = lcm(r1.d)(r2.d);
return Ratio(
(r1.n * (d / r1.d)) - (r2.n * (d / r2.d))
)(d);
};
// ratioMult :: Rational -> Rational -> Rational
const ratioMult = n1 => n2 => {
const [r1, r2] = [n1, n2].map(rational);
return Ratio(r1.n * r2.n)(
r1.d * r2.d
);
};
// ratioPlus :: Rational -> Rational -> Rational
const ratioPlus = n1 =>
n2 => {
const [r1, r2] = [n1, n2].map(rational);
const d = lcm(r1.d)(r2.d);
return Ratio(
(r1.n * (d / r1.d)) + (
r2.n * (d / r2.d)
)
)(d);
};
// rational :: Num a => a -> Rational
const rational = x =>
isNaN(x) ? x : Number.isInteger(x) ? (
Ratio(x)(1)
) : approxRatio(undefined)(x);
// replicateString :: Int -> String -> String
const replicateString = n =>
s => s.repeat(n);
// showRatio :: Ratio -> String
const showRatio = r =>
"Ratio" !== r.type ? (
r.toString()
) : r.n.toString() + (
1 !== r.d ? (
`/${r.d}`
) : ""
);
// signum :: Num -> Num
const signum = n =>
// | Sign of a number.
n.constructor(
0 > n ? (
-1
) : (
0 < n ? 1 : 0
)
);
// snd :: (a, b) -> b
const snd = ab =>
// Second member of a pair.
ab[1];
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => "GeneratorFunction" !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat(...Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
// unlines :: [String] -> String
const unlines = xs =>
// A single string formed by the intercalation
// of a list of strings with the newline character.
xs.join("\n");
// MAIN ---
return main();
})();

View file

@ -0,0 +1,18 @@
# cantor(width; height)
def cantor($w; $h):
def init: [range(0; $h) | [range(0; $w) | "*"]];
def cantor($start; $leng; $ix):
($leng/3|floor) as $seg
| if $seg == 0 then .
else reduce range($ix; $h) as $i (.;
reduce range($start+$seg; $start + 2*$seg) as $j (.; .[$i][$j] = " "))
| cantor($start; $seg; $ix+1)
| cantor($start + 2*$seg; $seg; $ix+1)
end ;
init | cantor(0; $w; 1);
def pp: .[] | join("");
cantor($width; $height)
| pp

View file

@ -0,0 +1,20 @@
const width = 81
const height = 5
function cantor!(lines, start, len, idx)
seg = div(len, 3)
if seg > 0
for i in idx+1:height, j in start + seg + 1: start + seg * 2
lines[i, j] = ' '
end
cantor!(lines, start, seg, idx + 1)
cantor!(lines, start + 2 * seg, seg, idx + 1)
end
end
lines = fill(UInt8('#'), height, width)
cantor!(lines, 0, width, 1)
for i in 1:height, j in 1:width
print(Char(lines[i, j]), j == width ? "\n" : "")
end

View file

@ -0,0 +1,21 @@
// 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) }
}

View file

@ -0,0 +1,46 @@
local WIDTH = 81
local HEIGHT = 5
local lines = {}
function cantor(start, length, index)
-- must be local, or only one side will get calculated
local seg = math.floor(length / 3)
if 0 == seg then
return nil
end
-- remove elements that are not in the set
for it=0, HEIGHT - index do
i = index + it
for jt=0, seg - 1 do
j = start + seg + jt
pos = WIDTH * i + j
lines[pos] = ' '
end
end
-- left side
cantor(start, seg, index + 1)
-- right side
cantor(start + seg * 2, seg, index + 1)
return nil
end
-- initialize the lines
for i=0, WIDTH * HEIGHT do
lines[i] = '*'
end
-- calculate
cantor(0, WIDTH, 1)
-- print the result sets
for i=0, HEIGHT-1 do
beg = WIDTH * i
for j=beg, beg+WIDTH-1 do
if j <= WIDTH * HEIGHT then
io.write(lines[j])
end
end
print()
end

View file

@ -0,0 +1 @@
Graphics[MeshPrimitives[CantorMesh[#],1]/.{x_}:>{x,-0.05#}&/@Range[5],ImageSize->600]

View file

@ -0,0 +1,52 @@
MODULE Cantor;
FROM Terminal IMPORT Write,WriteLn,ReadChar;
CONST
WIDTH = 81;
HEIGHT = 5;
VAR
lines : ARRAY[0..HEIGHT] OF ARRAY[0..WIDTH] OF CHAR;
PROCEDURE Init;
VAR i,j : CARDINAL;
BEGIN
FOR i:=0 TO HEIGHT DO
FOR j:=0 TO WIDTH DO
lines[i,j] := '*'
END
END
END Init;
PROCEDURE Cantor(start,len,index : CARDINAL);
VAR i,j,seg : CARDINAL;
BEGIN
seg := len DIV 3;
IF seg=0 THEN RETURN END;
FOR i:=index TO HEIGHT-1 DO
j := start+seg;
FOR j:=start+seg TO start+seg*2-1 DO
lines[i,j] := ' '
END
END;
Cantor(start, seg, index+1);
Cantor(start+seg*2, seg, index+1)
END Cantor;
PROCEDURE Print;
VAR i,j : CARDINAL;
BEGIN
FOR i:=0 TO HEIGHT-1 DO
FOR j:=0 TO WIDTH-1 DO
Write(lines[i,j])
END;
WriteLn
END
END Print;
BEGIN
Init;
Cantor(0,WIDTH,1);
Print;
ReadChar;
END Cantor.

View file

@ -0,0 +1,21 @@
import strutils
const
Width = 81
Height = 5
var lines: array[Height, string]
for line in lines.mitems: line = repeat('*', Width)
proc cantor(start, length, index: Natural) =
let seg = length div 3
if seg == 0: return
for i in index..<Height:
for j in (start + seg)..<(start + seg * 2):
lines[i][j] = ' '
cantor(start, seg, index + 1)
cantor(start + seg * 2, seg, index + 1)
cantor(0, Width, 1)
for line in lines:
echo line

View file

@ -0,0 +1,46 @@
class CantorSet {
WIDTH : static : Int;
HEIGHT : static : Int;
lines : static : Char[,];
function : Init() ~ Nil {
WIDTH := 81;
HEIGHT := 5;
lines := Char->New[HEIGHT, WIDTH];
each(i : HEIGHT) {
each(j : WIDTH) {
lines[i,j] := '*';
};
};
}
function : Cantor(start : Int, len : Int, index : Int) ~ Nil {
seg : Int := len / 3;
if(seg = 0) {
return;
};
for(i := index; i < HEIGHT; i += 1;) {
for(j := start + seg; j < start + seg * 2; j += 1;) {
lines[i,j] := ' ';
};
};
Cantor(start, seg, index + 1);
Cantor(start + seg * 2, seg, index + 1);
}
function : Main(args : String[]) ~ Nil {
Init();
Cantor(0, WIDTH, 1);
each(i : HEIGHT) {
each(j : WIDTH) {
lines[i,j]->Print();
};
""->PrintLine();
};
}
}

View file

@ -0,0 +1,37 @@
100H: /* DRAW A CANTOR SET USING ASCII */
/* BDOS SYSTEM CALL AND I/O ROUTINES */
BDOS: PROCEDURE( F, A ); DECLARE F BYTE, A ADDRESS; GOTO 5; END;
PR$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PR$NL: PROCEDURE; CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
/* DRAW A CANTOR SET */
DECLARE LINES LITERALLY '4';
DECLARE WIDTH LITERALLY '27'; /* MUST BE 3**(LINES-1) */
DECLARE LINE (WIDTH)BYTE;
DECLARE ( I, L, C, W, S, SEGMENTS ) BYTE;
DO I = 0 TO LAST( LINE );
LINE( I ) = 023H;
CALL PR$CHAR( LINE( I ) );
END;
CALL PR$NL;
W = WIDTH;
SEGMENTS = 1;
DO L = 2 TO LINES;
W = W / 3;
SEGMENTS = SEGMENTS * 3;
C = 0;
DO S = 1 TO SEGMENTS;
DO I = 1 TO W;
IF NOT S THEN LINE( C ) = ' '; /* EVEN SEGMENT - BLANK IT */
CALL PR$CHAR( LINE( C ) );
C = C + 1;
END;
END;
CALL PR$NL;
END;
EOF

View file

@ -0,0 +1,28 @@
use strict;
use feature 'say';
sub cantor {
our($height) = @_;
my $width = 3 ** ($height - 1);
our @lines = ('#' x $width) x $height;
sub trim_middle_third {
my($len, $start, $index) = @_;
my $seg = int $len / 3
or return;
for my $i ( $index .. $height - 1 ) {
for my $j ( 0 .. $seg - 1 ) {
substr $lines[$i], $start + $seg + $j, 1, ' ';
}
}
trim_middle_third( $seg, $start + $_, $index + 1 ) for 0, $seg * 2;
}
trim_middle_third( $width, 0, 1 );
@lines;
}
say for cantor(5);

View file

@ -0,0 +1,8 @@
#!/usr/bin/perl -l
use strict; # https://rosettacode.org/wiki/Cantor_set
use warnings;
$_ = '#' x 81;
1 while print, s/(#+)\1\1/ $1 . $1 =~ tr!#! !r . $1 /ge;

View file

@ -0,0 +1,18 @@
(phixonline)-->
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">w</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'#'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"\n"</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">3</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;"><(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">-</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">len</span>
<span style="color: #000000;">line</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">..</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">+</span><span style="color: #000000;">len</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">' '</span>
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">len</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<!--

View file

@ -0,0 +1,21 @@
include ..\Utilitys.pmt
5 >ps
3 tps 1 - power var w
"#" 1 get nip w repeat var line
ps> for
3 swap 1 - power
w over / int var step
true >ps
for var j
tps not if
step for var k
line 32 j 1 - step * k + set var line
endfor
endif
ps> not >ps
endfor
cps
line ?
endfor

View file

@ -0,0 +1,17 @@
include ..\Utilitys.pmt
5 >ps
3 tps 1 - power var w
"#" 1 get nip w repeat var line
( 2 ps> ) for
line ?
3 swap 1 - power
w over / int var step
2 swap 2 3 tolist for var j
step for var k
line 32 j 1 - step * k + set var line
endfor
endfor
endfor
line ?

View file

@ -0,0 +1,15 @@
//Aamrun, 1st July 2022
void cantorSet(int x1,int y1,int x2,int y2,int strWt,int gap,int n){
strokeWeight(strWt);
line(x1,y1,x2,y2);
if(n>0){
cantorSet(x1,gap + y1,(2*x1+x2)/3,gap + (2*y1+y2)/3,strWt,gap,n-1);
cantorSet((2*x2+x1)/3,gap + (2*y2+y1)/3,x2,gap + y2,strWt,gap,n-1);
}
}
void setup(){
size(1000,1000);
cantorSet(100,10,900,10,1,10,5);
}

View file

@ -0,0 +1,24 @@
WIDTH = 81
HEIGHT = 5
lines=[]
def cantor(start, len, index):
seg = len / 3
if seg == 0:
return None
for it in xrange(HEIGHT-index):
i = index + it
for jt in xrange(seg):
j = start + seg + jt
pos = i * WIDTH + j
lines[pos] = ' '
cantor(start, seg, index + 1)
cantor(start + seg * 2, seg, index + 1)
return None
lines = ['*'] * (WIDTH*HEIGHT)
cantor(0, WIDTH, 1)
for i in xrange(HEIGHT):
beg = WIDTH * i
print ''.join(lines[beg : beg+WIDTH])

View file

@ -0,0 +1,74 @@
'''Cantor set separating model from display'''
from functools import (reduce)
import itertools
# cantor :: [(Bool, Int)] -> [(Bool, Int)]
def cantor(xs):
'''A Cantor segmentation step.'''
def go(tpl):
(bln, n) = tpl
m = n // 3
return [
(True, m), (False, m), (True, m)
] if bln and (1 < n) else [tpl]
return concatMap(go)(xs)
# cantorLines :: Int -> String
def cantorLines(n):
'''A text block display of n
Cantor-segmented lines.
'''
m = n - 1
repeat = itertools.repeat
return '\n'.join(
[showCantor(x) for x in (
reduce(
lambda a, f: a + [f(a[-1])],
repeat(cantor, m),
[[(True, 3 ** m)]]
)
)]
)
# showCantor :: [(Bool, Int)] -> String
def showCantor(xs):
'''A text block display of a list of
Cantor line segments.
'''
return ''.join(
concatMap(lambda tpl: tpl[1] * ('' if tpl[0] else ' '))(
xs
)
)
# main :: IO ()
def main():
'''Testing to depth 5'''
print(
cantorLines(5)
)
# GENERIC -------------------------------------------------------------
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list over which a function has been mapped.
The list monad can be derived by using a function f which
wraps its output in a list,
(using an empty list to represent computational failure).'''
chain = itertools.chain
return lambda xs: list(
chain.from_iterable(map(f, xs))
)
# MAIN ---
if __name__ == '__main__':
main()

View file

@ -0,0 +1,71 @@
'''Cantor set strings as both model and display.'''
from itertools import (chain, islice)
# cantorLines :: Int -> String
def cantorLines(n):
'''N levels of cantor segmentation,
obtained and displayed in the
form of lines of block characters.
'''
return '\n'.join(
[''.join(x) for x in islice(
iterate(cantor)(
[3 ** (n - 1) * '']
), n
)]
)
# cantor :: [String] -> [String]
def cantor(xs):
'''A cantor line derived from its predecessor.'''
def go(s):
m = len(s) // 3
blocks = s[0:m]
return [
blocks, m * ' ', blocks
] if '' == s[0] else [s]
return concatMap(go)(xs)
# MAIN ----------------------------------------------------
# main :: IO ()
def main():
'''Testing cantor line generation to level 5'''
print(
cantorLines(5)
)
# GENERIC -------------------------------------------------
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list over which a function has been mapped.
The list monad can be derived by using a function f which
wraps its output in a list,
(using an empty list to represent computational failure).'''
return lambda xs: list(
chain.from_iterable(map(f, xs))
)
# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
'''An infinite list of repeated
applications of f to x.
'''
def go(x):
v = x
while True:
yield v
v = f(v)
return lambda x: go(x)
# MAIN ---
if __name__ == '__main__':
main()

View file

@ -0,0 +1,126 @@
'''A Cantor set generator, and two different
representations of its output.
'''
from itertools import (islice, chain)
from fractions import Fraction
from functools import (reduce)
# ----------------------- CANTOR SET -----------------------
# cantor :: Generator [[(Fraction, Fraction)]]
def cantor():
'''A non-finite stream of successive Cantor
partitions of the line, in the form of
lists of fraction pairs.
'''
def go(xy):
(x, y) = xy
third = Fraction(y - x, 3)
return [(x, x + third), (y - third, y)]
return iterate(
concatMap(go)
)(
[(0, 1)]
)
# fractionLists :: [(Fraction, Fraction)] -> String
def fractionLists(xs):
'''A fraction pair representation of a
Cantor-partitioned line.
'''
def go(xy):
return ', '.join(map(showRatio, xy))
return ' '.join('(' + go(x) + ')' for x in xs)
# intervalBars :: [(Fraction, Fraction)] -> String
def intervalBars(w):
'''A block diagram representation of a
Cantor-partitioned line.
'''
def go(xs):
def show(a, tpl):
[x, y] = [int(w * r) for r in tpl]
return (
y,
(' ' * (x - a)) + ('' * (y - x))
)
return mapAccumL(show)(0)(xs)
return lambda xs: ''.join(go(xs)[1])
# -------------------------- TEST --------------------------
# main :: IO ()
def main():
'''Testing the generation of successive
Cantor subdivisions of the line, and
displaying them both as lines of fraction
pairs and as graphic interval bars.
'''
xs = list(islice(cantor(), 4))
w = max(xy[1].denominator for xy in xs[-1])
print(
'\n'.join(map(fractionLists, xs)),
'\n'
)
print(
'\n'.join(map(intervalBars(w), xs))
)
# ------------------------ GENERIC -------------------------
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list over which a function has been mapped.
The list monad can be derived by using a function f which
wraps its output in a list,
(using an empty list to represent computational failure).'''
return lambda xs: list(
chain.from_iterable(map(f, xs))
)
# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
'''An infinite list of repeated
applications of f to x.
'''
def go(x):
v = x
while True:
yield v
v = f(v)
return go
# mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
def mapAccumL(f):
'''A tuple of an accumulation and a list derived by a
combined map and fold,
with accumulation from left to right.
'''
def go(a, x):
tpl = f(a[0], x)
return (tpl[0], a[1] + [tpl[1]])
return lambda acc: lambda xs: (
reduce(go, xs, (acc, []))
)
# showRatio :: Ratio -> String
def showRatio(r):
'''String representation of the ratio r.'''
d = r.denominator
return str(r.numerator) + (
'/' + str(d) if 1 != d else ''
)
# MAIN ---
if __name__ == '__main__':
main()

View file

@ -0,0 +1,38 @@
_Title "Cantor Set"
Dim Shared As Integer sw, sh, wide, high
sw = 800: sh = 200: wide = 729: high = 7
Dim Shared As Integer a(wide, high)
Screen _NewImage(sw, sh, 8)
Cls , 15: Color 0
Call calc(0, wide, 1)
Call CantorSet
Sleep
System
Sub calc (start As Integer, length As Integer, index As Integer)
Dim As Integer i, j, newLength
newLength = length \ 3
If newLength = 0 Then Exit Sub
For j = index To high - 1
For i = start + newLength To start + newLength * 2 - 1
a(i, j) = 1
Next
Next
Call calc(start, newLength, index + 1)
Call calc(start + newLength * 2, newLength, index + 1)
End Sub
Sub CantorSet
Dim As Integer i, j, x, y
For y = 0 To high - 1
j = y + 1
For x = 0 To wide - 1
i = x + 34
If a(x, y) = 0 Then Line (i, j * 24 - 5)-(i, j * 24 + 17)
Next
Next
End Sub

View file

@ -0,0 +1,20 @@
[ $ "" swap witheach
[ nested quackery join ] ] is expand ( $ --> $ )
[ $ "ABA" ] is A ( $ --> $ )
[ $ "BBB" ] is B ( $ --> $ )
[ char A = iff
[ char q ] else space
swap of echo$ ] is draw ( n c --> $ )
81 $ "A"
5 times
[ dup witheach
[ dip over draw ]
cr
i if
[ expand
dip [ 3 / ] ] ]
2drop

View file

@ -0,0 +1,51 @@
cantorSet <- function() {
depth <- 6L
cs <- vector('list', depth)
cs[[1L]] <- c(0, 1)
for(k in seq_len(depth)) {
cs[[k + 1L]] <- unlist(sapply(seq_len(length(cs[[k]]) / 2L), function(j) {
p <- cs[[k]][2L] / 3
h <- 2L * (j - 1L)
c(
cs[[k]][h + 1L] + c(0, p),
cs[[k]][h + 2L] - c(p, 0)
)
}, simplify = FALSE))
}
cs
}
cantorSetGraph <- function() {
cs <- cantorSet()
u <- unlist(cs)
df <- data.frame(
x_start = u[seq_along(u) %% 2L == 1L],
x_end = u[seq_along(u) %% 2L == 0L],
depth = unlist(lapply(cs, function(e) {
l <- length(e)
n <- 0
while(l > 1) {
n <- n + 1L
l <- l / 2
}
rep(n, length(e) / 2)
}))
)
require(ggplot2)
g <- ggplot(df, aes_string(x = 'x_start', y = 'depth')) +
geom_segment(aes_string(xend = 'x_end', yend = 'depth', size = 3)) +
scale_y_continuous(trans = "reverse") +
theme(
axis.title = element_blank(),
axis.line = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.position = 'none',
aspect.ratio = 1/5
)
list(graph = g, data = df, set = cs)
}

View file

@ -0,0 +1,16 @@
/*REXX program displays an ASCII diagram of a Canter Set as a set of (character) lines. */
w= linesize() /*obtain the width of the display term.*/
if w==0 then w= 81 /*Can't obtain width? Use the default.*/
do lines=0; _ = 3 ** lines /*calculate powers of three (# lines).*/
if _>w then leave /*Too large? We passed the max value. */
#=_ /*this value of a width─of─line is OK. */
end /*lines*/ /* [↑] calculate a useable line width.*/
w= # /*use the (last) useable line width. */
$= copies('', #) /*populate the display line with blocks*/
do j=0 until #==0 /*show Cantor set as a line of chars. */
if j>0 then do k=#+1 by #+# to w /*skip 1st line blanking*/
$= overlay( left('', #), $, k) /*blank parts of a line.*/
end /*j*/
say $ /*display a line of the Cantor Set. */
#= # % 3 /*the part (thirds) to be blanked out. */
end /*j*/ /*stick a fork in it, we're all done. */

View file

@ -0,0 +1,24 @@
#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)))

View file

@ -0,0 +1,21 @@
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);

View file

@ -0,0 +1,51 @@
# Project : Cantor set
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

View file

@ -0,0 +1,7 @@
lines = 5
(0..lines).each do |exp|
seg_size = 3**(lines-exp-1)
chars = (3**exp).times.map{ |n| n.digits(3).any?(1) ? " " : ""}
puts chars.map{ |c| c * seg_size }.join
end

View file

@ -0,0 +1,64 @@
use convert_base::Convert;
use std::fmt;
struct CantorSet {
cells: Vec<Vec<bool>>,
}
fn number_to_vec(n: usize) -> Vec<u32> {
// for the conversion we need the digits in reverse order
// i.e the least significant digit in the first element of the vector
n.to_string()
.chars()
.rev()
.map(|c| c.to_digit(10).unwrap())
.collect()
}
impl CantorSet {
fn new(lines: usize) -> CantorSet {
// Convert from base 10- to base 3
let mut base = Convert::new(10, 3);
let mut cells: Vec<Vec<bool>> = vec![];
for line in 0..lines {
// calculate how many repeating sequence will be in the given line
let segment_size = 3_usize.pow((lines - line - 1) as u32);
let segment: Vec<bool> = (0..3_usize.pow(line as u32))
.map(|n| {
let output = base.convert::<u32, u32>(&number_to_vec(n));
// return false in case the base 3 number contains at least one "1"
// otherwise return true
!output.contains(&1)
})
.collect();
// copy the segment "segment_size" time
let mut accum: Vec<bool> = Vec::with_capacity(segment.len() * segment_size);
for c in segment.iter() {
accum.extend(std::iter::repeat(*c).take(segment_size))
}
cells.push(accum);
}
CantorSet { cells }
}
}
impl fmt::Display for CantorSet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for line in self.cells.iter() {
for c in line {
write!(f, "{}", if *c { "█" } else { " " })?
}
writeln!(f)?;
}
Ok(())
}
}
fn main() {
let cs = CantorSet::new(5);
println!("Cantor set:");
println!("{}", cs);
}

View file

@ -0,0 +1,22 @@
object CantorSetQD extends App {
val (width, height) = (81, 5)
val lines = Seq.fill[Array[Char]](height)(Array.fill[Char](width)('*'))
def cantor(start: Int, len: Int, index: Int) {
val seg = len / 3
println(start, len, index)
if (seg != 0) {
for (i <- index until height;
j <- (start + seg) until (start + seg * 2)) lines(i)(j) = ' '
cantor(start, seg, index + 1)
cantor(start + seg * 2, seg, index + 1)
}
}
cantor(0, width, 1)
lines.foreach(l => println(l.mkString))
}

View file

@ -0,0 +1,32 @@
object CantorSetFP extends App {
val (width, height) = (81, 5)
def lines = (1 to height).map(_ => (0 until width).toSet)
def cantorSet(pre: Seq[Set[Int]], start: Int, len: Int, index: Int): Seq[Set[Int]] = {
val seg = len / 3
def cantorSet1(pre: Seq[Set[Int]], start: Int, index: Int): Seq[Set[Int]] = {
def elementsStuffing(pre: Set[Int], start: Int): Set[Int] =
pre -- ((start + seg) until (start + seg * 2))
for (n <- 0 until height)
yield if (index to height contains n) elementsStuffing(pre(n), start)
else pre(n)
}
if (seg == 0) pre
else {
def version0 = cantorSet1(pre, start, index)
def version1 = cantorSet(cantorSet1(pre, start, index), start, seg, index + 1)
cantorSet(version1, start + seg * 2, seg, index + 1)
}
}
def output: Seq[Set[Int]] = cantorSet(lines, 0, width, 1)
println(
output.map(l => (0 to width).map(pos => if (l contains pos) '*' else ' ').mkString)
.mkString("\n"))
}

View file

@ -0,0 +1,21 @@
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 }

View file

@ -0,0 +1,68 @@
Object subclass: CantorSet [
| intervals |
CantorSet class >> new
[^self basicNew
initialize;
yourself]
initialize
[intervals := Array with: (CantorInterval
from: 0
to: 1)]
split
[intervals := intervals gather: [:each | each split]]
displayOn: aStream atScale: aNumber
[| current |
current := 0.
intervals do:
[:each |
(each start - current) * aNumber timesRepeat: [aStream space].
each length * aNumber timesRepeat: [aStream nextPut: $#].
current := each stop].
aStream nl]
]
Interval subclass: CantorInterval [
split
[| oneThird left right |
oneThird := self length / 3.
left := self class
from: start
to: start + oneThird.
right := self class
from: stop - oneThird
to: stop.
^Array
with: left
with: right]
start [^start]
stop [^stop]
length [^stop - start]
printOn: aStream
[aStream << ('%1[%2,%3]' % {self class name. start. stop})]
]
Object subclass: TestCantor [
TestCantor class >> iterations: anInteger
[| cantorset scale count |
scale := 3 raisedTo: anInteger. "Make smallest interval 1"
count := 0.
cantorset := CantorSet new.
[cantorset
displayOn: Transcript
atScale: scale.
count < anInteger] whileTrue:
[cantorset split.
count := count + 1]]
]
TestCantor iterations: 4.

View file

@ -0,0 +1,26 @@
const (
width = 81
height = 5
)
fn cantor(mut lines [][]u8, start int, len int, index int) {
seg := len / 3
if seg == 0 {
return
}
for i in index.. height {
for j in start + seg..start + 2 * seg {
lines[i][j] = ' '[0]
}
}
cantor(mut lines, start, seg, index + 1)
cantor(mut lines, start + seg * 2, seg, index + 1)
}
fn main() {
mut lines := [][]u8{len:height, init: []u8{len:width, init:'*'[0]}}
cantor(mut lines, 0, width, 1)
for line in lines {
println(line.bytestr())
}
}

View file

@ -0,0 +1,30 @@
1010 L=4
1020 I=1
1030 X=1
1040 I=I+1
1050 X=X*3
1060 #=I<L*1040
2010 I=0
2020 :I)=35
2030 $=:I)
2040 I=I+1
2050 #=I<X*2020
2060 ?=""
2070 W=X
2080 G=1
2090 W=W/3
2100 G=G*3
2110 S=1
2120 C=0
2130 I=1
2140 #=S/2*0+%=1*2160
2150 :C)=32
2160 $=:C)
2170 C=C+1
2180 I=I+1
2190 #=W>I*2140
2200 S=S+1
2210 #=C<X*2130
2220 ?=""
2230 L=L-1
2240 #=1<L*2090

View file

@ -0,0 +1,40 @@
Module Module1
Const WIDTH = 81
Const HEIGHT = 5
Dim lines(HEIGHT, WIDTH) As Char
Sub Init()
For i = 0 To HEIGHT - 1
For j = 0 To WIDTH - 1
lines(i, j) = "*"
Next
Next
End Sub
Sub Cantor(start As Integer, len As Integer, index As Integer)
Dim seg As Integer = len / 3
If seg = 0 Then
Return
End If
For i = index To HEIGHT - 1
For j = start + seg To start + seg * 2 - 1
lines(i, j) = " "
Next
Next
Cantor(start, seg, index + 1)
Cantor(start + seg * 2, seg, index + 1)
End Sub
Sub Main()
Init()
Cantor(0, WIDTH, 1)
For i = 0 To HEIGHT - 1
For j = 0 To WIDTH - 1
Console.Write(lines(i, j))
Next
Console.WriteLine()
Next
End Sub
End Module

View file

@ -0,0 +1,19 @@
var width = 81
var height = 5
var lines = [[]] * height
for (i in 0...height) lines[i] = ["*"] * width
var cantor // recursive so need to declare variable first
cantor = Fn.new { |start, len, index|
var seg = (len/3).floor
if (seg == 0) return
for (i in index...height) {
for (j in (start+seg)...(start+seg*2)) lines[i][j] = " "
}
cantor.call(start, seg, index + 1)
cantor.call(start + seg*2, seg, index + 1)
}
cantor.call(0, width, 1)
for (i in 0...height) System.print(lines[i].join())

View file

@ -0,0 +1,19 @@
proc Cantor(N, LineSeg, Len); \Delete middle third of LineSeg
int N; char LineSeg; int Len, Third, I;
[if N>0 and Len>1 then
[Third:= Len/3;
for I:= Third, 2*Third-1 do LineSeg(I):= ^ ;
Cantor(N-1, LineSeg, Third);
Cantor(N-1, LineSeg+2*Third, Third);
];
];
char LineSeg, N;
[LineSeg:=
"#################################################################################
";
for N:= 0 to 4 do
[Cantor(N, LineSeg, 81);
Text(0, LineSeg);
];
]

View file

@ -0,0 +1,13 @@
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");