Pascal's triangle: Difference between revisions
→{{header|AppleScript}}: Updated primitives and approach
(Added Fōrmulæ) |
(→{{header|AppleScript}}: Updated primitives and approach) |
||
Line 308:
=={{header|AppleScript}}==
Drawing n rows from a generator:
<lang AppleScript>
-- pascal :: Generator [[Int]]
zipWith(my plus, {0} & row, row &
end |λ|
end script
iterate(nextRow, {1})
end pascal
-- TEST
on run
end run
-- showPascal :: [[Int]] -> String
on showPascal(xs)
set w to length of intercalate(" ",
script align
on
|center|(w, space, intercalate(" ", x))
end |λ|
end script
unlines(map(align, xs))
end showPascal
-- GENERIC ABSTRACTIONS ---------------------------------
-- center :: Int -> Char -> String -> String
on |center|(n, cFiller, strText)
set lngFill to n - (length of strText)
if lngFill > 0 then
set strPad to replicate(lngFill div 2, cFiller) as text
set strCenter to strPad & strText & strPad
if lngFill mod 2 > 0 then
cFiller & strCenter
else
strCenter
end if
else
end if
end |center|
--
on
set {dlm, my text item delimiters} to {my text item delimiters, sep}
set s to xs
set my text item delimiters to dlm
return
end intercalate
-- iterate :: (a -> a) -> a -> Generator [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
-- length :: [a] -> Int
on |length|(xs)
set c to class of xs
if list is c or string is c then
length of xs
else
2 ^ 30 -- (simple proxy for non-finite)
end if
end |length|
-- map :: (a -> b) -> [a] -> [b]
Line 421 ⟶ 414:
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn ::
on mReturn(f)
if class of f is script then
Line 431 ⟶ 424:
end if
end mReturn
-- plus :: Num -> Num -> Num
on plus(a, b)
a + b
end plus
-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary
-- assembly of a target length
-- 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
-- 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 end of ys to xs's |λ|()
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
-- unwords :: [String] -> String
on unwords(xs)
set {dlm, my text item delimiters} to {my text item delimiters, space}
set s to xs as text
set my text item delimiters to dlm
return s
end unwords
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set lng to min(|length
if 1 > lng then return {}
set xs_ to take(lng, xs) -- Allow for non-finite
set ys_ to take(lng, ys) -- generators like cycle etc
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of
end repeat
return lst
Line 444 ⟶ 506:
end zipWith</lang>
{{Out}}
<pre> 1
1 1
1 2 1
1 3
=={{header|AutoHotkey}}==
|