Closed ErikSchierboom closed 11 months ago
toRNA : Text -> Optional Text
toRNA dna = toRNA.recursive [] (toCharList dna)
toRNA.recursive : [Char] -> [Char] -> Optional Text
toRNA.recursive a =
cases
[] -> Some (fromCharList a)
h +: t ->
match toRNA.mapChar h with
Some c -> toRNA.recursive (a :+ c) t
Optional.None -> None
_ -> None
toRNA.mapChar : Char -> Optional Char
toRNA.mapChar =
cases
x
| x == ?G -> Some ?C
| x == ?C -> Some ?G
| x == ?T -> Some ?A
| x == ?A -> Some ?U
_ -> None
> toRNA "C"
construct:add
construct:char
construct:constructor
construct:function
construct:invocation
construct:lambda
construct:list
construct:match
construct:named-argument
construct:optional-type
construct:parameter
construct:pattern-matching
construct:recursion
construct:string
construct:underscore
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
technique:recursion
encode : Text -> Text
encode input =
render : (Optional (Char, Nat)) -> Text
render = cases
Some (c, count) ->
if count == 1 then toText c
else toText count ++ toText c
None -> ""
go = cases
(textOut, s @ (Some (prevC, count))), c ->
if prevC === c then (textOut, Some (c, increment count))
else (textOut ++ (render s), (Some (c, 1)))
(textOut, None), c -> (textOut, Some (c, 1))
match List.foldLeft go ("", None) (toCharList input) with
(acc, remainder) -> acc ++ (render remainder)
decode : Text -> Text
decode input =
go = cases
(output, digits), c ->
if isDigit c then (output, digits :+ c)
else
count = match digits with
[] -> 1
_ -> getOrBug "oops" (Nat.fromText (Text.fromCharList digits))
textToAdd = Text.repeat count (toText c)
(output ++ textToAdd, [])
List.foldLeft go ("", []) (toCharList input) |> at1
construct:==
construct:==⁼
construct:@
construct:char
construct:constructor
construct:if
construct:if-then-else
construct:infix-function
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:list
construct:match
construct:nat
construct:number
construct:parameter
construct:pattern-matching
construct:text
construct:then-expression
construct:tuple
construct:underscore
construct:variable
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
technique:type-extensions
uses:List
encode : Text -> Text
encode input =
go acc = cases
[] -> (acc, "")
hd +: tl ->
front = takeWhile (e -> hd === e) tl
fTlLen = size front
if fTlLen == 0 then
go (acc ++ Char.toText hd) tl
else
go (acc ++ toText (fTlLen + 1) ++ (Char.toText hd)) (drop fTlLen tl)
at1 (go "" (toCharList input))
decode : Text -> Text
decode input =
go acc = cases
[] -> acc
charList ->
match takeWhile isDigit charList with
[] -> match charList with
[] -> bug (Generic.failure "Should not come here")
hd +: tl -> go (acc ++ toText hd) tl
digits ->
rep = fromCharList digits |> fromText |> getOrBug "Not a digit"
match drop (size digits) charList with
[] -> bug (Generic.failure "Should not come here")
hd +: tl -> go (acc Text.++ (repeat rep (Char.toText hd))) tl
go "" (toCharList input)
construct:add
construct:boolean
construct:char
construct:if-then-else
construct:implicit-conversion
construct:invocation
construct:lambda
construct:list
construct:local-binding
construct:match
construct:number
construct:parameter
construct:pattern-matching
construct:recursion
construct:string
construct:text
construct:then-expression
construct:using-recursion
construct:variable-shadowing
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
use Int / toText *
use List +: size replace at at! foldRight
rebase : Int -> [Int] -> Int -> Optional [Int]
rebase inputBase inputDigits outputBase =
folder digit = if (digit < +0) || (digit >= inputBase) then abort else cases (acc, mult) ->
(acc + (digit * mult), mult * inputBase)
total = 'let
foldRight folder (+0, +1) inputDigits
go acc n =
if n <= +0 then acc
else m = (mod n outputBase)
d = (n / outputBase)
go (m +: acc) d
result = 'let
if (inputBase <= +1) || (outputBase <= +1) then abort else ()
result' = let go [] (at1 !total)
if (size result') === 0 then [+0]
else result'
!(toOptional result)
construct:add
construct:boolean
construct:divide
construct:if-then-else
construct:implicit-conversion
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:let
construct:list
construct:logical-or
construct:multiply
construct:number
construct:parameter
construct:pattern-matching
construct:recursion
construct:string
construct:subtract
construct:tuple
construct:underscore
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:logical
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
technique:looping
technique:recursion
fromDigits : Int -> [Int] -> Int
fromDigits base digits =
reverse digits
|> mapIndexed (idx d -> (pow base idx) * d)
|> foldLeft (Int.+) +0
toDigits : Int -> Int -> [Int]
toDigits base nr =
go : [Int] -> Int -> [Int]
go digits = cases
+0 -> digits
nr ->
digit = mod nr base
go (digit +: digits) (div nr base)
if nr == +0 then [+0] else go [] nr
rebase : Int -> [Int] -> Int -> Optional [Int]
rebase inputBase inputDigits outputBase =
baseValid b = b > +1
digitValid d = (d >= +0) && (d < inputBase)
digitsValid digits = digits |> List.all digitValid
if baseValid inputBase && baseValid outputBase && digitsValid inputDigits then
number = fromDigits inputBase inputDigits
Some (toDigits outputBase number)
else
None
construct:add
construct:boolean
construct:cases
construct:divide
construct:double
construct:eq
construct:floating-point-number
construct:function
construct:if-then-else
construct:implicit-conversion
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:list
construct:local-binding
construct:logical-and
construct:map
construct:multiply
construct:number
construct:optional-type
construct:parameter
construct:pattern-matching
construct:recursion
construct:reverse
construct:using-recursion
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
technique:looping
technique:recursion
uses:List
use Nat / increment
steps : Nat -> Optional Nat
steps n =
next n = if (mod n 2) === 0 then n / 2 else (3 * n) + 1
go count = cases
0 -> None
1 -> Some count
n -> go (increment count) (next n)
go 0 n
construct:add
construct:boolean
construct:cases
construct:divide
construct:else
construct:if-then-else
construct:invocation
construct:lambda
construct:multiply
construct:nat
construct:number
construct:optional-type
construct:parameter
construct:pattern-matching
construct:recursion
construct:subtract
construct:then
construct:variable
paradigm:functional
technique:higher-order-functions
technique:recursion
structural type LinkedList a = Nil | Cons a (LinkedList a)
LinkedList.new : a -> LinkedList a
LinkedList.new a = Cons a Nil
LinkedList.cons : a -> LinkedList a -> LinkedList a
LinkedList.cons a ls = Cons a ls
LinkedList.nil : LinkedList a
LinkedList.nil = Nil
LinkedList.fromList : [a] -> LinkedList a
LinkedList.fromList = foldRight Cons Nil
LinkedList.head : LinkedList a -> Optional a
LinkedList.head = cases
Nil -> None
Cons h _ -> Some h
LinkedList.isNil : LinkedList a -> Boolean
LinkedList.isNil = cases
Nil -> true
_ -> false
LinkedList.tail : LinkedList a -> LinkedList a
LinkedList.tail = cases
Nil -> Nil
Cons _ tl -> tl
LinkedList.reverseLinkedList : LinkedList a -> LinkedList a
LinkedList.reverseLinkedList = toList >> List.reverse >> fromList
LinkedList.toList : LinkedList a -> [a]
LinkedList.toList l =
go acc = cases
Nil -> acc
Cons h t -> go (acc :+ h) t
go [] l
construct:application
construct:boolean
construct:cases
construct:constructor
construct:function
construct:method
construct:parameter
construct:pattern-matching
construct:recursive-function
construct:string
construct:tagged-union
construct:to-list
construct:using-recursion
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
technique:looping
technique:recursion
uses:List.reverse
age : Text -> Nat -> Optional Float
age planet earthAgeSeconds =
use Nat toFloat
earthAgeYears = (toFloat earthAgeSeconds) / 31557600.0
match planet with
"Mercury" -> Some(earthAgeYears / 0.2408467)
"Venus" -> Some(earthAgeYears / 0.61519726)
"Earth" -> Some earthAgeYears
"Mars" -> Some(earthAgeYears / 1.8808158)
"Jupiter" -> Some(earthAgeYears / 11.862615)
"Saturn" -> Some(earthAgeYears / 29.447498)
"Uranus" -> Some(earthAgeYears / 84.016846)
"Neptune" -> Some(earthAgeYears / 164.79132)
_ -> None
construct:divide
construct:floating-point-number
construct:invocation
construct:lambda
construct:match
construct:optional-type
construct:parameter
construct:pattern-matching
construct:text
construct:use
construct:variable
paradigm:functional
technique:higher-order-functions
planets = Map.fromList [
("Mercury", 0.2408467),
("Venus", 0.61519726),
("Earth", 1.0),
("Mars", 1.8808158),
("Jupiter", 11.862615),
("Saturn", 29.447498),
("Uranus", 84.016846),
("Neptune", 164.79132)
]
age : Text -> Nat -> Optional Float
age planet earthAgeSeconds =
convert factor =
(Nat.toFloat earthAgeSeconds) / factor / 31557600.0
Optional.map convert (Map.get planet planets)
construct:divide
construct:double
construct:floating-point-number
construct:identifier
construct:implicit-conversion
construct:lambda
construct:list
construct:map
construct:number
construct:parameter
construct:pattern-matching
construct:text
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
uses:Map
use Nat / mod + >
use List foldLeft
isArmstrongNumber : Nat -> Boolean
isArmstrongNumber number =
toDigits: [Nat] -> Nat -> [Nat]
toDigits acc n =
m = mod n 10
d = n / 10
n' = acc :+ m
if d > 0 then toDigits n' d else n'
digits = toDigits [] number
number' = foldLeft (ns -> n -> ns + (pow n (size digits))) 0 digits
number === number'
construct:add
construct:boolean
construct:divide
construct:double
construct:else
construct:eq
construct:floating-point-number
construct:if-then-else
construct:implicit-conversion
construct:invocation
construct:lambda
construct:list
construct:local-binding
construct:number
construct:parameter
construct:pattern-matching
construct:recursion
construct:ternary
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
technique:looping
technique:math
allergens : [Text]
allergens = ["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]
allergies.allergicTo : Text -> Nat -> Boolean
allergies.allergicTo allergen score =
allergens
|> indexOf allergen
|> map (idx -> isSetBit idx score)
|> getOrElse false
allergies.list : Nat -> [Text]
allergies.list score = filter (allergen -> allergicTo allergen score) allergens
construct:application
construct:boolean
construct:define
construct:function
construct:invocation
construct:lambda
construct:list
construct:method
construct:parameter
construct:pipeline
construct:set
construct:string
construct:variable
paradigm:functional
technique:functional-composition
uses:List
-- This recursive solution draws a single row of the matrix
-- then draws a rotated spiral matrix below it.
-- We use `reverse` because transpose rotates counterclockwise
-- and we want clockwise
spiralMatrix : Nat -> [[Nat]]
spiralMatrix n =
spiral' = cases
0, _, _ -> []
x, y, offset ->
List.rangeClosed (offset + 1) (offset + x)
+: map reverse (transpose (spiral' (y - 1) x (offset + x)))
spiral' n n 0
-- `transpose` swaps the rows and columns of a matrix,
-- which has the effect of rotating it counterclockwise.
-- E.g. > transpose [[1, 2, 3],
-- [4, 5, 6],
-- [7, 8, 9]]
-- ⧩
-- [[1, 4, 7],
-- [2, 5, 8],
-- [3, 6, 9]]
transpose : [[a]] -> [[a]]
transpose = cases
[] -> []
[] +: xss -> transpose xss
((x +: xs) +: xss) ->
((hds, tls)) = unzip let Each.toList 'let
(hd +: tl) = each xss
(hd, tl)
combine y h ys t = (y List.+: h) List.+: transpose (ys List.+: t)
combine x hds xs tls
-- Turns a list of pairs into a pair of lists
unzip : [(a,b)] -> ([a], [b])
unzip = cases
[] -> ([], [])
((a,b) +: xs) ->
((as, bs)) = unzip xs
(a +: as, b +: bs)
construct:add
construct:assignment
construct:char
construct:comment
construct:constructor
construct:expression
construct:function
construct:invocation
construct:lambda
construct:let
construct:list
construct:nat
construct:number
construct:parameter
construct:pattern-matching
construct:recursion
construct:string
construct:subtract
construct:tuple
construct:underscore
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:lambda
technique:higher-order-functions
technique:recursion
use List foldLeft
unique type Chromatic = A | As | B | C | Cs | D | Ds | E | F | Fs | G | Gs
Chromatic.toSharpText = cases
A -> "A"
As -> "A#"
B -> "B"
C -> "C"
Cs -> "C#"
D -> "D"
Ds -> "D#"
E -> "E"
F -> "F"
Fs -> "F#"
G -> "G"
Gs -> "G#"
Chromatic.toFlatText = cases
A -> "A"
As -> "Bb"
B -> "B"
C -> "C"
Cs -> "Db"
D -> "D"
Ds -> "Eb"
E -> "E"
F -> "F"
Fs -> "Gb"
G -> "G"
Gs -> "Ab"
Chromatic.halfStep = cases
A -> As
As -> B
B -> C
C -> Cs
Cs -> D
D -> Ds
Ds -> E
E -> F
F -> Fs
Fs -> G
G -> Gs
Gs -> A
Chromatic.wholeStep = cases
A -> B
As -> C
B -> Cs
C -> D
Cs -> Ds
D -> E
Ds -> F
E -> Fs
F -> G
Fs -> Gs
G -> A
Gs -> As
starting: Text -> (Boolean, Chromatic)
starting = cases
"C" -> (true, C)
"a" -> (true, A)
"G" -> (true, G)
"D" -> (true, D)
"E" -> (true, E)
"A" -> (true, A)
"G" -> (true, G)
"F#" -> (true, Fs)
"e" -> (true, E)
"b" -> (true, B)
"f#" -> (true, Fs)
"c#" -> (true, Cs)
"g#" -> (true, Gs)
"d#" -> (true, Ds)
"F" -> (false, F)
"Bb" -> (false, As)
"Eb" -> (false, Ds)
"Ab" -> (false, Gs)
"Db" -> (false, Cs)
"Gb" -> (false, Fs)
"d" -> (false, D)
"g" -> (false, G)
"c" -> (false, G)
"f" -> (false, F)
"bb" -> (false, As)
"eb" -> (false, Ds)
interval : Text -> Text -> [Text]
interval tonal pattern =
(sharp, start) = starting tonal
sharpFlat = if sharp then toSharpText else toFlatText
fold = cases (acc, c) -> cases
?M -> ((acc :+ c), (wholeStep c))
?A -> ((acc :+ c), (halfStep (wholeStep c)))
_ -> ((acc :+ c), halfStep c)
tones = foldLeft fold ([], start) (toCharList pattern) |> at1
map sharpFlat (tones :+ start)
chromatic : Text -> [Text]
chromatic start = match interval start "mmmmmmmmmmmm" with notes :+ _ -> notes
construct:assignment
construct:boolean
construct:char
construct:constructor
construct:if-then-else
construct:invocation
construct:lambda
construct:list
construct:match
construct:parameter
construct:pattern
construct:pipe
construct:text
construct:tuple
construct:type
construct:use
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
{{ This type is used to capture the expected error message }}
unique type Error = Error Text
{{ This is all the states a frame could be in:
BallOne - new frame, no balls rolled yet
BallTwo n - second ball, first was n (0 <= n < 10)
Spare - Two balls totalling 10 have been rolled
Strike - One ball totalling 10 has been rolled
Strike1 n - Strike was rolled, since there was one ball with n pins
Complete n - Frame is complete and scored n
}}
unique type Frame =
BallOne |
BallTwo Nat |
Spare |
Strike |
Strike1 Nat |
Complete Nat
{{ This tracks the current state of the game }}
unique type GameState = {
completedFrames: Nat,
currentScore: Nat,
currentFrame: Optional Frame,
activeFrames: [Frame]
}
{{ useful for debugging }}
Frame.toText = cases
BallOne -> "BallOne"
BallTwo n -> "BallTwo(" ++ (Nat.toText n) ++ ")"
Spare -> "Spare"
Strike -> "Strike"
Strike1 n -> "Strike1(" ++ (Nat.toText n) ++ ")"
Complete n -> "Complete(" ++ (Nat.toText n) ++ ")"
Frame.toTextO = cases
None -> "None"
Some f -> Frame.toText f
GameState.toText = cases
GameState complete score current active -> (Nat.toText complete) ++ " frames complete, Current Score: " ++ (Nat.toText score) ++ "Current Frame: " ++ (Frame.toTextO current) ++ " Active: " ++ (List.foldLeft (acc -> s -> acc ++ " " ++ (Frame.toText s)) "" active)
{{ given the next ball in the sequence, what is the next state of this frame }}
Frame.nextBall n = cases
BallOne -> if n === 10 then Strike else BallTwo n
BallTwo m | n + m === 10 -> Spare
BallTwo m -> Complete (n + m)
Spare -> Complete (n + 10)
Strike -> Strike1 n
Strike1 m -> Complete (10 + m + n)
{{ should this frame remain the current frame }}
Frame.active = cases
Spare -> false
Strike -> false
Strike1 _ -> false
Complete _ -> false
_ -> true
{{ given the next ball, update the state of the current frame }}
GameState.updateCurrent: Nat -> GameState -> GameState
GameState.updateCurrent n = cases
GameState count c None fs -> GameState count c None fs
GameState count c (Some f) fs ->
match Frame.nextBall n f with
Complete s ->
if count == 9 then GameState 10 (c + s) None fs
else GameState (increment count) (c + s) (Some BallOne) fs
f' | active f' -> GameState count c (Some f') fs
f' ->
if count == 9 then GameState 10 c None (fs :+ f')
else GameState (increment count) c (Some BallOne) (fs :+ f')
{{ given the next ball, update the state of the active frames other than current frame }}
GameState.updateActive: Nat -> GameState -> GameState
GameState.updateActive n = cases GameState count c f as ->
go score acc = cases
[] -> GameState count (c+score) f acc
h +: t -> match Frame.nextBall n h with
Complete s -> go (score + s) acc t
h -> go score (acc :+ h) t
go 0 [] as
{{ given a current state and the next ball, what is the next state }}
GameState.next: Nat -> GameState -> GameState
GameState.next n s = updateActive n s |> updateCurrent n
GameState.new = GameState 0 0 (Some BallOne) []
score : [Nat] -> Either Error Nat
score rolls =
match List.foldRight GameState.next GameState.new (reverse rolls) with
GameState 10 n _ [] -> Right n
n -> Left (Error "Score cannot be taken until the end of the game")
construct:add
construct:boolean
construct:cases
construct:comment
construct:constructor
construct:curried-function
construct:custom-type
construct:definition-site
construct:else
construct:if-expression
construct:implicit-conversion
construct:invocation
construct:lambda
construct:list
construct:match-expression
construct:nat
construct:number
construct:optional-type
construct:parameter
construct:pattern
construct:record
construct:string
construct:then
construct:type-alias
construct:union-type
construct:unique-type
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
technique:recursion
uses:List
use List +:
use Nat ==
sieve.primes : Nat -> [Nat]
sieve.primes n = Stream.toList! <| do sieve.stream (List.rangeClosed 2 n)
sieve.stream : [Nat] -> { Stream Nat } ()
sieve.stream xs =
match xs with
[] -> ()
(x +: xs) ->
sieved = sieve.removeMultiples x xs
Stream.emit x
sieve.stream sieved
sieve.removeMultiples : Nat -> [Nat] -> [Nat]
sieve.removeMultiples a xs =
go : Nat -> Nat -> [Nat] -> [Nat]
go a b xs =
match xs with
[] -> []
(y +: ys) ->
if b == y then
go a (a+b) ys
else
if b < y then
go a (a+b) xs
else
y +: go a b ys
go a a xs
construct:add
construct:assignment
construct:do
construct:function
construct:if-then-else
construct:invocation
construct:lambda
construct:let
construct:list
construct:match
construct:nat
construct:number
construct:parameter
construct:pattern-matching
construct:recursion
construct:stream
construct:tuple
construct:variable-shadowing
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
technique:laziness
technique:looping
technique:recursion
uses:List
uses:Stream
proteinTranslation.translate : [Text] -> [Text] -> {Exception} [Text]
proteinTranslation.translate proteins codons = match codons with
[] -> proteins
c +: cs | (c === "UAA") || (c === "UAG") || (c === "UGA") -> proteins
| (c === "AUG") -> translate (proteins :+ "Methionine") cs
| (c === "UUU") || (c === "UUC") -> translate (proteins :+ "Phenylalanine") cs
| (c === "UUA") || (c === "UUG") -> translate (proteins :+ "Leucine") cs
| (c === "UCU") || (c === "UCC") || (c === "UCA") || (c === "UCG") -> translate (proteins :+ "Serine") cs
| (c === "UAU") || (c === "UAC") -> translate (proteins :+ "Tyrosine") cs
| (c === "UGU") || (c === "UGC") -> translate (proteins :+ "Cysteine") cs
| (c === "UGG") -> translate (proteins :+ "Tryptophan") cs
c +: cs -> Exception.raise(Generic.failure "Unknown codon" c)
proteinTranslation.proteins : Text -> [Text]
proteinTranslation.proteins rna = Exception.unsafeRun! '((Text.chunk 3 >> translate []) rna)
construct:add
construct:boolean
construct:char
construct:constructor
construct:function
construct:invocation
construct:lambda
construct:list
construct:logical-or
construct:match
construct:number
construct:parameter
construct:pattern
construct:recursive-call
construct:string
construct:throw
construct:using-directives
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:boolean-logic
technique:exceptions
technique:higher-order-functions
technique:recursion
proteinTranslation.proteins : Text -> [Text]
proteinTranslation.proteins rna =
translate codon = match codon with
"AUG" -> "Methionine"
"UGG" -> "Tryptophan"
c | (c == "UUU") || (c == "UUC") -> "Phenylalanine"
c | (c == "UUA") || (c == "UUG") -> "Leucine"
c | (c == "UCU") || (c == "UCC") || (c == "UCA") || (c == "UCG") -> "Serine"
c | (c == "UAU") || (c == "UAC") -> "Tyrosine"
c | (c == "UGU") || (c == "UGC") -> "Cysteine"
_ -> "STOP"
takeWhile (p -> p != "STOP") <| map translate (Text.chunk 3 rna)
construct:boolean
construct:char
construct:expression
construct:function
construct:invocation
construct:lambda
construct:list
construct:map
construct:match
construct:number
construct:parameter
construct:pattern-matching
construct:string
construct:takeWhile
construct:text
construct:using-directives
construct:visibility-modifiers
paradigm:functional
technique:higher-order-functions
uses:List
uses:Text
differenceOfSquares.square : Nat -> Nat
differenceOfSquares.square n = n * n
differenceOfSquares.squareOfSum : Nat -> Nat
differenceOfSquares.squareOfSum number =
List.rangeClosed 1 number |> sum |> square
differenceOfSquares.sumOfSquares : Nat -> Nat
differenceOfSquares.sumOfSquares number =
List.rangeClosed 1 number |> List.map square |> sum
differenceOfSquares.difference : Nat -> Nat
differenceOfSquares.difference number =
squareOfSum number - sumOfSquares number
construct:application
construct:binding
construct:subtract
construct:function
construct:invocation
construct:lambda
construct:list
construct:multiply
construct:number
construct:parameter
construct:pattern-matching
construct:pipe-forward
construct:subtract
construct:variable
paradigm:functional
technique:higher-order-functions
romanNumerals.toRoman : Nat -> Text
romanNumerals.toRoman = toRomanAcc []
use List +:
romanNumerals.toRomanAcc : [Text] -> Nat -> Text
romanNumerals.toRomanAcc acc decimal = match decimal with
x
| x >= 1000 -> toRomanAcc ("M" +: acc) (x - 1000)
| x >= 900 -> toRomanAcc ("CM" +: acc) (x - 900)
| x >= 500 -> toRomanAcc ("D" +: acc) (x - 500)
| x >= 400 -> toRomanAcc ("CD" +: acc) (x - 400)
| x >= 100 -> toRomanAcc ("C" +: acc) (x - 100)
| x >= 90 -> toRomanAcc ("XC" +: acc) (x - 90)
| x >= 50 -> toRomanAcc ("L" +: acc) (x - 50)
| x >= 40 -> toRomanAcc ("XL" +: acc) (x - 40)
| x >= 10 -> toRomanAcc ("X" +: acc) (x - 10)
| x >= 9 -> toRomanAcc ("IX" +: acc) (x - 9)
| x >= 5 -> toRomanAcc ("V" +: acc) (x - 5)
| x >= 4 -> toRomanAcc ("IV" +: acc) (x - 4)
| x >= 1 -> toRomanAcc ("I" +: acc) (x - 1)
_ -> join "" (reverse acc)
construct:add
construct:char
construct:constructor
construct:function
construct:invocation
construct:lambda
construct:list
construct:match
construct:nat
construct:number
construct:parameter
construct:pattern-matching
construct:recursion
construct:string
construct:subtract
construct:text
construct:underscore
construct:use
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
technique:recursion
uses:List+
etl.transform : Map Nat [Char] -> Map Char Nat
etl.transform lettersByScore = --todo "implement transform"
Each.toList do
k = each (Map.keys lettersByScore)
b = Map.get k lettersByScore
|> getOrElse []
|> List.map toLowercase
|> each
(b, k)
|> Map.fromList
construct:char
construct:comment
construct:do
construct:each
construct:function
construct:invocation
construct:lambda
construct:list
construct:map
construct:parameter
construct:pipeline
construct:tuple
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
uses:List
uses:Map
uses:Tuple
This is an automated comment
Hello :wave: Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!
Hello lovely maintainers :wave:
We've recently added "tags" to student's solutions. These express the constructs, paradigms and techniques that a solution uses. We are going to be using these tags for lots of things including filtering, pointing a student to alternative approaches, and much more.
In order to do this, we've built out a full AST-based tagger in C#, which has allowed us to do things like detect recursion or bit shifting. We've set things up so other tracks can do the same for their languages, but its a lot of work, and we've determined that actually it may be unnecessary. Instead we think that we can use machine learning to achieve tagging with good enough results. We've fine-tuned a model that can determine the correct tags for C# from the examples with a high success rate. It's also doing reasonably well in an untrained state for other languages. We think that with only a few examples per language, we can potentially get some quite good results, and that we can then refine things further as we go.
I released a new video on the Insiders page that talks through this in more detail.
We're going to be adding a fully-fledged UI in the coming weeks that allow maintainers and mentors to tag solutions and create training sets for the neural networks, but to start with, we're hoping you would be willing to manually tag 20 solutions for this track. In this post we'll add 20 comments, each with a student's solution, and the tags our model has generated. Your mission (should you choose to accept it) is to edit the tags on each issue, removing any incorrect ones, and add any that are missing. In order to build one model that performs well across languages, it's best if you stick as closely as possible to the C# tags as you can. Those are listed here. If you want to add extra tags, that's totally fine, but please don't arbitrarily reword existing tags, even if you don't like what Erik's chosen, as it'll just make it less likely that your language gets the correct tags assigned by the neural network.
To summarise - there are two paths forward for this issue:
If you tell us you're not able/wanting to help or there's no comment added, we'll automatically crowd-source this in a week or so.
Finally, if you have questions or want to discuss things, it would be best done on the forum, so the knowledge can be shared across all maintainers in all tracks.
Thanks for your help! :blue_heart:
Note: Meta discussion on the forum