September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,103 @@
-- SIERPINKSI TRIANGLE -------------------------------------------------------
-- sierpinski :: Int -> [String]
on sierpinski(n)
if n > 0 then
set previous to sierpinski(n - 1)
set padding to replicate(2 ^ (n - 1), space)
script alignedCentre
on |λ|(s)
concat(padding & s & padding)
end |λ|
end script
script adjacentDuplicates
on |λ|(s)
unwords(replicate(2, s))
end |λ|
end script
-- Previous triangle block centered,
-- and placed on 2 adjacent duplicates.
map(alignedCentre, previous) & map(adjacentDuplicates, previous)
else
{"*"}
end if
end sierpinski
-- TEST ----------------------------------------------------------------------
on run
unlines(sierpinski(4))
end run
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- concat :: [[a]] -> [a] | [String] -> String
on concat(xs)
if length of xs > 0 and class of (item 1 of xs) is string then
set acc to ""
else
set acc to {}
end if
repeat with i from 1 to length of xs
set acc to acc & item i of xs
end repeat
acc
end concat
-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
-- 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 :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- replicate :: Int -> a -> [a]
on replicate(n, a)
set out to {}
if n < 1 then return out
set dbl to {a}
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
-- unlines, unwords :: [String] -> String
on unlines(xs)
intercalate(linefeed, xs)
end unlines
on unwords(xs)
intercalate(space, xs)
end unwords

View file

@ -1,3 +1,5 @@
-- SIERPINSKI TRIANGLE BY XOR / RULE 90 --------------------------------------
-- sierpinskiTriangle :: Int -> String
on sierpinskiTriangle(intOrder)
@ -7,7 +9,7 @@ on sierpinskiTriangle(intOrder)
-- pascalModTwo :: Int -> [[String]]
script pascalModTwo
on lambda(intRows)
on |λ|(intRows)
-- addRow [[Int]] -> [[Int]]
script addRow
@ -24,21 +26,25 @@ on sierpinskiTriangle(intOrder)
-- rule :: Character -> Character -> Character
script rule
on lambda(a, b)
cond(a = b, space, "*")
end lambda
on |λ|(a, b)
if a = b then
space
else
"*"
end if
end |λ|
end script
zipWith(rule, {" "} & row, row & {" "})
end nextRow
on lambda(xs)
on |λ|(xs)
xs & {nextRow(item -1 of xs)}
end lambda
end |λ|
end script
foldr(addRow, {{"*"}}, range(1, intRows - 1))
end lambda
foldr(addRow, {{"*"}}, enumFromTo(1, intRows - 1))
end |λ|
end script
-- The centring foldr (fold right) below starts from the end of the list,
@ -47,33 +53,45 @@ on sierpinskiTriangle(intOrder)
-- Each preceding row has one more indent space than the row below it.
script centred
on lambda(sofar, row)
on |λ|(sofar, row)
set strIndent to indent of sofar
{triangle:strIndent & intercalate(space, row) & linefeed & ¬
triangle of sofar, indent:strIndent & space}
end lambda
end |λ|
end script
triangle of foldr(centred, {triangle:"", indent:""}, ¬
pascalModTwo's lambda(intOrder ^ 2))
pascalModTwo's |λ|(intOrder ^ 2))
end sierpinskiTriangle
-- TEST
-- TEST ----------------------------------------------------------------------
on run
set strTriangle to sierpinskiTriangle(4)
set the clipboard to strTriangle
strTriangle
end run
-- GENERIC LIBRARY FUNCTIONS
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
if m > n then
set d to -1
else
set d to 1
end if
set lst to {}
repeat with i from m to n by d
set end of lst to i
end repeat
return lst
end enumFromTo
-- foldr :: (a -> b -> a) -> a -> [b] -> a
on foldr(f, startValue, xs)
@ -81,7 +99,7 @@ on foldr(f, startValue, xs)
set v to startValue
set lng to length of xs
repeat with i from lng to 1 by -1
set v to lambda(v, item i of xs, i, xs)
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
@ -95,6 +113,15 @@ on intercalate(strText, lstText)
return strJoined
end intercalate
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
@ -102,48 +129,19 @@ on mReturn(f)
f
else
script
property lambda : f
property |λ| : f
end script
end if
end mReturn
-- range :: Int -> Int -> [Int]
on range(m, n)
if n < m then
set d to -1
else
set d to 1
end if
set lst to {}
repeat with i from m to n by d
set end of lst to i
end repeat
return lst
end range
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set nx to length of xs
set ny to length of ys
if nx < 1 or ny < 1 then
{}
else
set lng to cond(nx < ny, nx, ny)
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to lambda(item i of xs, item i of ys)
end repeat
return lst
end tell
end if
set lng to min(length of xs, length of ys)
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, item i of ys)
end repeat
return lst
end tell
end zipWith
-- cond :: Bool -> (a -> b) -> (a -> b) -> (a -> b)
on cond(bool, f, g)
if bool then
f
else
g
end if
end cond

View file

@ -0,0 +1,16 @@
# Return a string space or star to print at x,y.
# Must have x<y. x<0 is the left side of the triangle.
# If x<-y then it's before the left edge and the return is a space.
char(x,y) = (y+x>=0 && ((y+x)%2)==0 && ((y+x)&(y-x))==0 ? "*" : " ")
# Return a string which is row y of the triangle from character
# position x through to the right hand end x==y, inclusive.
row(x,y) = (x<=y ? char(x,y).row(x+1,y) : "\n")
# Return a string of stars, spaces and newlines which is the
# Sierpinski triangle from row y to limit, inclusive.
# The first row is y=0.
triangle(y,limit) = (y <= limit ? row(-limit,y).triangle(y+1,limit) : "")
# Print rows 0 to 15, which is the order 4 triangle per the task.
print triangle(0,15)

View file

@ -1,9 +1,13 @@
import Data.Bits ((.&.))
import Data.List (intercalate)
sierpinski n = map row [m, m-1 .. 0] where
m = 2^n - 1
row y = replicate y ' ' ++ concatMap cell [0..m - y] where
cell x | y .&. x == 0 = " *"
| otherwise = " "
sierpinski :: Int -> [String]
sierpinski 0 = [""]
sierpinski n =
concat $
(<$> sierpinski (n - 1)) <$> -- Previous triangle,
[ flip intercalate ([replicate (2 ^ (n - 1))] <*> " -") -- centred,
, (++) <*> ('+' :) -- above singly spaced duplicates.
]
main :: IO ()
main = mapM_ putStrLn $ sierpinski 4

View file

@ -1,16 +1,9 @@
import Data.List (intersperse)
import Data.Bits ((.&.))
sierpinski :: Int -> String
sierpinski n = let
sierpinski n = map row [m, m-1 .. 0] where
m = 2^n - 1
row y = replicate y ' ' ++ concatMap cell [0..m - y] where
cell x | y .&. x == 0 = " *"
| otherwise = " "
-- Top down, each row after the first is an XOR rewrite
rule90 n = (scanl next ['*'] [1..n-1]) where
next line _ = zipWith xor (" " ++ line) (line ++ " ")
xor l r | l == r = ' ' | otherwise = '*'
-- Bottom up, each line above the base is indented 1 more space
in fst (foldr spacing ("", "") (rule90 (2^n))) where
spacing x (s, w) =
(concat [w, intersperse ' ' x, "\n", s], w ++ " ")
main = putStr $ sierpinski 4
main = mapM_ putStrLn $ sierpinski 4

View file

@ -0,0 +1,17 @@
import Data.List (intersperse)
-- Top down, each row after the first is an XOR / Rule90 rewrite.
-- Bottom up, each line above the base is indented 1 more space.
sierpinski :: Int -> String
sierpinski = fst . foldr spacing ([], []) . rule90 . (2 ^)
where
rule90 = scanl next "*" . enumFromTo 1 . subtract 1
where
next = const . ((zipWith xor . (' ' :)) <*> (++ " "))
xor l r
| l == r = ' '
| otherwise = '*'
spacing x (s, w) = (concat [w, intersperse ' ' x, "\n", s], w ++ " ")
main :: IO ()
main = putStr $ sierpinski 4

View file

@ -1,67 +1,62 @@
// A Sierpinski triangle of order N,
// constructed as 2^N lines of Pascal's triangle mod 2
// and mapped to centred {1:asterisk, 0:space} strings
(() => {
'use strict';
(order => {
// LINES OF SIERPINSKI TRIANGLE AT LEVEL N -------------------------------
// sierpinski :: Int -> [Bool]
let sierpinski = intOrder => {
// sierpinski :: Int -> [String]
const sierpTriangle = n =>
// Previous triangle centered with left and right padding,
(n > 0) ? concat(ap([
map(xs => intercalate(xs, ap(
[s => concat(replicate(Math.pow(2, (n - 1)), s))], [' ', '-']
))),
// asciiPascalMod2 :: Int -> [[Int]]
let asciiPascalMod2 = nRows =>
range(1, nRows - 1)
.reduce(sofar => {
let lstPrev = sofar.slice(-1)[0];
// above a pair of duplicates, placed one character apart.
map(xs => intercalate('+', [xs, xs]))
], [sierpTriangle(n - 1)])) : ['▲'];
// The composition of (asciiBinary . mod 2 . add)
// is reduced here to a rule from two parent characters
// to a single child character.
// Rule 90 also reduces to the same XOR
// relationship between left and right neighbours.
// GENERIC FUNCTIONS -----------------------------------------------------
return sofar
.concat([zipWith(
(left, right) => left === right ? ' ' : '*',
[' '].concat(lstPrev),
lstPrev.concat(' ')
)]);
}, [
['*'] // Tip of triangle
]);
// Reduce/folding from the last item (base of list)
// which has zero left indent.
// Each preceding row has one more indent space than the row beneath it
return asciiPascalMod2(Math.pow(2, intOrder))
.reduceRight((a, x) => {
return {
triangle: a.indent + x.join(' ') + '\n' + a.triangle,
indent: a.indent + ' '
}
}, {
triangle: '',
indent: ''
}).triangle
// replicate :: Int -> a -> [a]
const replicate = (n, a) => {
let v = [a],
o = [];
if (n < 1) return o;
while (n > 1) {
if (n & 1) o = o.concat(v);
n >>= 1;
v = v.concat(v);
}
return o.concat(v);
};
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
let zipWith = (f, xs, ys) =>
xs.length === ys.length ? (
xs.map((x, i) => f(x, ys[i]))
) : undefined,
// curry :: ((a, b) -> c) -> a -> b -> c
const curry = f => a => b => f(a, b);
// range(intFrom, intTo, optional intStep)
// Int -> Int -> Maybe Int -> [Int]
range = (m, n, step) => {
let d = (step || 1) * (n >= m ? 1 : -1);
// map :: (a -> b) -> [a] -> [b]
const map = curry((f, xs) => xs.map(f));
return Array.from({
length: Math.floor((n - m) / d) + 1
}, (_, i) => m + (i * d));
};
// Apply a list of functions to a list of arguments
// <*> :: [(a -> b)] -> [a] -> [b]
const ap = (fs, xs) => //
[].concat.apply([], fs.map(f => //
[].concat.apply([], xs.map(x => [f(x)]))));
return sierpinski(order);
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
})(4);
// intercalate :: String -> [a] -> String
const intercalate = (s, xs) => xs.join(s);
// concat :: [[a]] -> [a] || [String] -> String
const concat = xs => {
if (xs.length > 0) {
const unit = typeof xs[0] === 'string' ? '' : [];
return unit.concat.apply(unit, xs);
} else return [];
};
// TEST ------------------------------------------------------------------
return unlines(sierpTriangle(4));
})();

View file

@ -0,0 +1,62 @@
(order => {
// sierpinski :: Int -> [Bool]
let sierpinski = intOrder => {
// asciiPascalMod2 :: Int -> [[Int]]
let asciiPascalMod2 = nRows =>
range(1, nRows - 1)
.reduce(sofar => {
let lstPrev = sofar.slice(-1)[0];
// The composition of (asciiBinary . mod 2 . add)
// is reduced here to a rule from two parent characters
// to a single child character.
// Rule 90 also reduces to the same XOR
// relationship between left and right neighbours.
return sofar
.concat([zipWith(
(left, right) => left === right ? ' ' : '*',
[' '].concat(lstPrev),
lstPrev.concat(' ')
)]);
}, [
['*'] // Tip of triangle
]);
// Reduce/folding from the last item (base of list)
// which has zero left indent.
// Each preceding row has one more indent space than the row beneath it
return asciiPascalMod2(Math.pow(2, intOrder))
.reduceRight((a, x) => {
return {
triangle: a.indent + x.join(' ') + '\n' + a.triangle,
indent: a.indent + ' '
}
}, {
triangle: '',
indent: ''
}).triangle
};
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
let zipWith = (f, xs, ys) =>
xs.length === ys.length ? (
xs.map((x, i) => f(x, ys[i]))
) : undefined,
// range(intFrom, intTo, optional intStep)
// Int -> Int -> Maybe Int -> [Int]
range = (m, n, step) => {
let d = (step || 1) * (n >= m ? 1 : -1);
return Array.from({
length: Math.floor((n - m) / d) + 1
}, (_, i) => m + (i * d));
};
return sierpinski(order);
})(4);

View file

@ -0,0 +1,12 @@
// version 1.1.2
const val ORDER = 4
const val SIZE = 1 shl ORDER
fun main(args: Array<String>) {
for (y in SIZE - 1 downTo 0) {
for (i in 0 until y) print(" ")
for (x in 0 until SIZE - y) print(if ((x and y) != 0) " " else "* ")
println()
}
}

View file

@ -0,0 +1,7 @@
n = 4;
d = string('*');
for k = 0 : n - 1
sp = repelem(' ', 2 ^ k);
d = [sp + d + sp, d + ' ' + d];
end
disp(d.join(char(10)))

View file

@ -0,0 +1,6 @@
n = 2 ^ 4 - 1;
tr = + ~(-n : n);
for k = 1:n
tr(k + 1, :) = bitget(90, 1 + filter2([4 2 1], tr(k, :)));
end
char(10 * tr + 32)

View file

@ -0,0 +1,25 @@
# Project : Sierpinski triangle
# Date : 2017/09/20
# Author : Gal Zsolt (~ CalmoSoft ~)
# Email : <calmosoft@gmail.com>
norder=4
xy = list(40)
for i = 1 to 40
xy[i] = " "
next
triangle(1, 1, norder)
for i = 1 to 36
see xy[i] + nl
next
func triangle(x, y, n)
if n = 0
xy[y] = left(xy[y],x-1) + "*" + substr(xy[y],x+1)
else
n=n-1
length=pow(2,n)
triangle(x, y+length, n)
triangle(x+length, y, n)
triangle(x+length*2, y+length, n)
ok

View file

@ -1,11 +1,11 @@
func sierpinski_triangle(n) {
var triangle = ['*'];
var triangle = ['*']
{ |i|
var sp = (' ' * Math.pow(2, i-1));
var sp = (' ' * 2**i)
triangle = (triangle.map {|x| sp + x + sp} +
triangle.map {|x| x + ' ' + x});
} * n;
triangle.join("\n");
triangle.map {|x| x + ' ' + x})
} * n
triangle.join("\n")
}
say sierpinski_triangle(4);
 
say sierpinski_triangle(4)

View file

@ -0,0 +1,7 @@
level,d := 3,T("*");
foreach n in (level + 1){
sp:=" "*(2).pow(n);
d=d.apply('wrap(a){ String(sp,a,sp) }).extend(
d.apply(fcn(a){ String(a," ",a) }));
}
d.concat("\n").println();