patternMinor
Constructing a simple tree with ASCII in F#
Viewed 0 times
simplewithconstructingasciitree
Problem
This is just a basic HackerRank challenge I was working on to better understand F#. Its purpose is just to print a tree that has a straight 'trunk' of \$n\$, splits into 2 branches which diverge to \$n\$, then branches grow a straight trunk to \$\frac{n}{2}\$ which split and diverge to \$\frac{n}{2}\$, etc.
(Note: I was told to avoid using variables if possible, so the only one I used was to store the iterations which are meant to be \$n \le 5\$.)
```
[]
let main argv =
let iterations = System.Convert.ToInt32(System.Console.ReadLine())
//63 rows
//100 cols
//16 length
let splitRoots = fun x -> Array.collect (fun elem -> [|elem-1;elem+1|]) x
let isEven = fun i -> if i % 2 = 0 then true else false
let advanceBranch = fun x -> Array.mapi (fun i elem -> if isEven i then elem-1 else elem+1) x
let treeLine = fun oneLocs w ->
String.concat "" (Seq.map (fun x -> if Array.exists (fun elem -> elem = x) oneLocs then "1" else "_") w)
//if trunk and counter > 0 --> write more trunk
//if trunk and counter = 0 --> split and transition to branch
//if branch and counter > 0 --> write more branch
//if branch and counter = 0 --> transition to trunk and deecrement max
let rec tree = fun l w h max original counter branch roots acc ->
match branch with
| _ when max = 0 ->
acc
| false when counter > 0 ->
tree l w h max original (counter-1) false roots (acc @ [ treeLine roots (seq { 1 .. w }) ])
| false when counter = 0 ->
tree l w h max original (original-1) true (splitRoots roots) acc
| true when counter > 0 ->
tree l w h max original (counter-1) true (advanceBranch roots) (acc @ [ treeLine roots (seq { 1 .. w })])
| true when counter = 0 ->
tree l w h (max-1) (original/2) (original/2) false roots (acc @ [ treeLine roots (seq { 1 .. w }) ])
let emptyRow = String.concat "" (Seq.map (fun x
(Note: I was told to avoid using variables if possible, so the only one I used was to store the iterations which are meant to be \$n \le 5\$.)
```
[]
let main argv =
let iterations = System.Convert.ToInt32(System.Console.ReadLine())
//63 rows
//100 cols
//16 length
let splitRoots = fun x -> Array.collect (fun elem -> [|elem-1;elem+1|]) x
let isEven = fun i -> if i % 2 = 0 then true else false
let advanceBranch = fun x -> Array.mapi (fun i elem -> if isEven i then elem-1 else elem+1) x
let treeLine = fun oneLocs w ->
String.concat "" (Seq.map (fun x -> if Array.exists (fun elem -> elem = x) oneLocs then "1" else "_") w)
//if trunk and counter > 0 --> write more trunk
//if trunk and counter = 0 --> split and transition to branch
//if branch and counter > 0 --> write more branch
//if branch and counter = 0 --> transition to trunk and deecrement max
let rec tree = fun l w h max original counter branch roots acc ->
match branch with
| _ when max = 0 ->
acc
| false when counter > 0 ->
tree l w h max original (counter-1) false roots (acc @ [ treeLine roots (seq { 1 .. w }) ])
| false when counter = 0 ->
tree l w h max original (original-1) true (splitRoots roots) acc
| true when counter > 0 ->
tree l w h max original (counter-1) true (advanceBranch roots) (acc @ [ treeLine roots (seq { 1 .. w })])
| true when counter = 0 ->
tree l w h (max-1) (original/2) (original/2) false roots (acc @ [ treeLine roots (seq { 1 .. w }) ])
let emptyRow = String.concat "" (Seq.map (fun x
Solution
There's a couple of simple things you can do to reduce the clutter in your code. For example, this:
Firstly,
can always be written simply as
You're also missing a trick with your declaration:
Can simply be written as
So your
I'm coming back to F# after a long break (2+ years) so I'm not going to suggest anything else as I'm still relearning!
Edit:
Actually...
Is simply:
let isEven = fun i -> if i % 2 = 0 then true else falseFirstly,
if someCondition then true else falsecan always be written simply as
someConditionYou're also missing a trick with your declaration:
let someFunction = fun i -> ...Can simply be written as
let someFunction i = ...So your
isEven function is simply:let isEven i = i % 2 = 0I'm coming back to F# after a long break (2+ years) so I'm not going to suggest anything else as I'm still relearning!
Edit:
Actually...
let emptyRow = String.concat "" (Seq.map (fun x -> "_") (seq{ 1..100}))Is simply:
let emptyRow = String.replicate 100 "_"Code Snippets
let isEven = fun i -> if i % 2 = 0 then true else falseif someCondition then true else falsesomeConditionlet someFunction = fun i -> ...let someFunction i = ...Context
StackExchange Code Review Q#113273, answer score: 2
Revisions (0)
No revisions yet.