12 Days of Christmas with F#

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
6
down vote
favorite
I've implemented 12 Days of Christmas just by using pattern matching. It's not very efficient as it performs 12 iterations, each performing its own iteration (potentially from 12 down to 1... does tail recursion kick in here though?) but I supposed I can live with that at the moment. I'm more concerned with learning how idiomatic F# is written. Would an F# programmer be more concerned with creating types, etc.?
module Christmas
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let rec getVerse verse num =
match num with
| 12 -> getVerse (List.append verse ["12 drummers drumming"]) (num - 1)
| 11 -> getVerse (List.append verse ["11 pipers piping"]) (num - 1)
| 10 -> getVerse (List.append verse ["10 lords a-leaping"]) (num - 1)
| 9 -> getVerse (List.append verse ["9 ladies dancing"]) (num - 1)
| 8 -> getVerse (List.append verse ["8 maids a-milking"]) (num - 1)
| 7 -> getVerse (List.append verse ["7 swans a-swimming"]) (num - 1)
| 6 -> getVerse (List.append verse ["6 geese a-laying"]) (num - 1)
| 5 -> getVerse (List.append verse ["5 golden rings"]) (num - 1)
| 4 -> getVerse (List.append verse ["4 calling birds"]) (num - 1)
| 3 -> getVerse (List.append verse ["3 French hens"]) (num - 1)
| 2 -> getVerse (List.append verse ["2 turtle doves, and"]) (num - 1)
| _ -> List.append verse ["A partridge in a pear tree"]
let composeVerse num =
List.append [getPreamble num] (getVerse num)
|> List.fold (fun r s -> r + s + "n") ""
[1 .. 12]
|> Seq.iter (fun a -> printfn "%s" (composeVerse a))
f#
add a comment |Â
up vote
6
down vote
favorite
I've implemented 12 Days of Christmas just by using pattern matching. It's not very efficient as it performs 12 iterations, each performing its own iteration (potentially from 12 down to 1... does tail recursion kick in here though?) but I supposed I can live with that at the moment. I'm more concerned with learning how idiomatic F# is written. Would an F# programmer be more concerned with creating types, etc.?
module Christmas
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let rec getVerse verse num =
match num with
| 12 -> getVerse (List.append verse ["12 drummers drumming"]) (num - 1)
| 11 -> getVerse (List.append verse ["11 pipers piping"]) (num - 1)
| 10 -> getVerse (List.append verse ["10 lords a-leaping"]) (num - 1)
| 9 -> getVerse (List.append verse ["9 ladies dancing"]) (num - 1)
| 8 -> getVerse (List.append verse ["8 maids a-milking"]) (num - 1)
| 7 -> getVerse (List.append verse ["7 swans a-swimming"]) (num - 1)
| 6 -> getVerse (List.append verse ["6 geese a-laying"]) (num - 1)
| 5 -> getVerse (List.append verse ["5 golden rings"]) (num - 1)
| 4 -> getVerse (List.append verse ["4 calling birds"]) (num - 1)
| 3 -> getVerse (List.append verse ["3 French hens"]) (num - 1)
| 2 -> getVerse (List.append verse ["2 turtle doves, and"]) (num - 1)
| _ -> List.append verse ["A partridge in a pear tree"]
let composeVerse num =
List.append [getPreamble num] (getVerse num)
|> List.fold (fun r s -> r + s + "n") ""
[1 .. 12]
|> Seq.iter (fun a -> printfn "%s" (composeVerse a))
f#
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I've implemented 12 Days of Christmas just by using pattern matching. It's not very efficient as it performs 12 iterations, each performing its own iteration (potentially from 12 down to 1... does tail recursion kick in here though?) but I supposed I can live with that at the moment. I'm more concerned with learning how idiomatic F# is written. Would an F# programmer be more concerned with creating types, etc.?
module Christmas
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let rec getVerse verse num =
match num with
| 12 -> getVerse (List.append verse ["12 drummers drumming"]) (num - 1)
| 11 -> getVerse (List.append verse ["11 pipers piping"]) (num - 1)
| 10 -> getVerse (List.append verse ["10 lords a-leaping"]) (num - 1)
| 9 -> getVerse (List.append verse ["9 ladies dancing"]) (num - 1)
| 8 -> getVerse (List.append verse ["8 maids a-milking"]) (num - 1)
| 7 -> getVerse (List.append verse ["7 swans a-swimming"]) (num - 1)
| 6 -> getVerse (List.append verse ["6 geese a-laying"]) (num - 1)
| 5 -> getVerse (List.append verse ["5 golden rings"]) (num - 1)
| 4 -> getVerse (List.append verse ["4 calling birds"]) (num - 1)
| 3 -> getVerse (List.append verse ["3 French hens"]) (num - 1)
| 2 -> getVerse (List.append verse ["2 turtle doves, and"]) (num - 1)
| _ -> List.append verse ["A partridge in a pear tree"]
let composeVerse num =
List.append [getPreamble num] (getVerse num)
|> List.fold (fun r s -> r + s + "n") ""
[1 .. 12]
|> Seq.iter (fun a -> printfn "%s" (composeVerse a))
f#
I've implemented 12 Days of Christmas just by using pattern matching. It's not very efficient as it performs 12 iterations, each performing its own iteration (potentially from 12 down to 1... does tail recursion kick in here though?) but I supposed I can live with that at the moment. I'm more concerned with learning how idiomatic F# is written. Would an F# programmer be more concerned with creating types, etc.?
module Christmas
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let rec getVerse verse num =
match num with
| 12 -> getVerse (List.append verse ["12 drummers drumming"]) (num - 1)
| 11 -> getVerse (List.append verse ["11 pipers piping"]) (num - 1)
| 10 -> getVerse (List.append verse ["10 lords a-leaping"]) (num - 1)
| 9 -> getVerse (List.append verse ["9 ladies dancing"]) (num - 1)
| 8 -> getVerse (List.append verse ["8 maids a-milking"]) (num - 1)
| 7 -> getVerse (List.append verse ["7 swans a-swimming"]) (num - 1)
| 6 -> getVerse (List.append verse ["6 geese a-laying"]) (num - 1)
| 5 -> getVerse (List.append verse ["5 golden rings"]) (num - 1)
| 4 -> getVerse (List.append verse ["4 calling birds"]) (num - 1)
| 3 -> getVerse (List.append verse ["3 French hens"]) (num - 1)
| 2 -> getVerse (List.append verse ["2 turtle doves, and"]) (num - 1)
| _ -> List.append verse ["A partridge in a pear tree"]
let composeVerse num =
List.append [getPreamble num] (getVerse num)
|> List.fold (fun r s -> r + s + "n") ""
[1 .. 12]
|> Seq.iter (fun a -> printfn "%s" (composeVerse a))
f#
edited Mar 26 at 3:16
Jamalâ¦
30.1k11114225
30.1k11114225
asked Mar 26 at 2:59
Jim Wharton
1655
1655
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
3
down vote
accepted
You should generally avoid List.append because appending to a singly-linked list is quite inefficient.
I think your getVerse function is probably doing too much. You can have a function to get a line at a time which is just int -> string
Recursion can be avoided here if you switch to a list comprehension (the for...in syntax). Recursion is rarely needed in F#.
Even folding can be avoided here as it's simpler to use String.concat.
With all of these changes and a couple more:
let ordinalSuffix = function 1 -> "st" | 2 -> "nd" | 3 -> "rd" | _ -> "th"
let preamble num =
sprintf "On the %i%s day of Christmas, my true love gave to me" num (ordinalSuffix num)
let line num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let verse num =
preamble num :: [ for i in num .. -1 .. 1 -> line i ]
|> String.concat "n"
[1 .. 12] |> List.map verse |> String.concat "nn" |> printfn "%s"
Great point on appending to a singly-linked list. I was completely unaware that F# devs avoid recursion. Thank you for reminding me of the cons operator in the verse function. Great feedback! Thank you!
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
up vote
2
down vote
I think TheQuickBownFox's suggestion is rather elegant. With a little twist (the use of List.mapFold) it is only necessary to call line num once per num:
module Christmas =
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let getVerseLine num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let composeVerse num verseLines =
let verse = (getVerseLine num)::verseLines
(getPreamble num)::verse, verse
let getVerses=
fst ([1 .. 12] |> List.mapFold (fun verseLines num -> composeVerse num verseLines) )
1
mapFoldThat's actually a new one for me. Super cool suggestion.
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
You should generally avoid List.append because appending to a singly-linked list is quite inefficient.
I think your getVerse function is probably doing too much. You can have a function to get a line at a time which is just int -> string
Recursion can be avoided here if you switch to a list comprehension (the for...in syntax). Recursion is rarely needed in F#.
Even folding can be avoided here as it's simpler to use String.concat.
With all of these changes and a couple more:
let ordinalSuffix = function 1 -> "st" | 2 -> "nd" | 3 -> "rd" | _ -> "th"
let preamble num =
sprintf "On the %i%s day of Christmas, my true love gave to me" num (ordinalSuffix num)
let line num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let verse num =
preamble num :: [ for i in num .. -1 .. 1 -> line i ]
|> String.concat "n"
[1 .. 12] |> List.map verse |> String.concat "nn" |> printfn "%s"
Great point on appending to a singly-linked list. I was completely unaware that F# devs avoid recursion. Thank you for reminding me of the cons operator in the verse function. Great feedback! Thank you!
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
up vote
3
down vote
accepted
You should generally avoid List.append because appending to a singly-linked list is quite inefficient.
I think your getVerse function is probably doing too much. You can have a function to get a line at a time which is just int -> string
Recursion can be avoided here if you switch to a list comprehension (the for...in syntax). Recursion is rarely needed in F#.
Even folding can be avoided here as it's simpler to use String.concat.
With all of these changes and a couple more:
let ordinalSuffix = function 1 -> "st" | 2 -> "nd" | 3 -> "rd" | _ -> "th"
let preamble num =
sprintf "On the %i%s day of Christmas, my true love gave to me" num (ordinalSuffix num)
let line num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let verse num =
preamble num :: [ for i in num .. -1 .. 1 -> line i ]
|> String.concat "n"
[1 .. 12] |> List.map verse |> String.concat "nn" |> printfn "%s"
Great point on appending to a singly-linked list. I was completely unaware that F# devs avoid recursion. Thank you for reminding me of the cons operator in the verse function. Great feedback! Thank you!
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
You should generally avoid List.append because appending to a singly-linked list is quite inefficient.
I think your getVerse function is probably doing too much. You can have a function to get a line at a time which is just int -> string
Recursion can be avoided here if you switch to a list comprehension (the for...in syntax). Recursion is rarely needed in F#.
Even folding can be avoided here as it's simpler to use String.concat.
With all of these changes and a couple more:
let ordinalSuffix = function 1 -> "st" | 2 -> "nd" | 3 -> "rd" | _ -> "th"
let preamble num =
sprintf "On the %i%s day of Christmas, my true love gave to me" num (ordinalSuffix num)
let line num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let verse num =
preamble num :: [ for i in num .. -1 .. 1 -> line i ]
|> String.concat "n"
[1 .. 12] |> List.map verse |> String.concat "nn" |> printfn "%s"
You should generally avoid List.append because appending to a singly-linked list is quite inefficient.
I think your getVerse function is probably doing too much. You can have a function to get a line at a time which is just int -> string
Recursion can be avoided here if you switch to a list comprehension (the for...in syntax). Recursion is rarely needed in F#.
Even folding can be avoided here as it's simpler to use String.concat.
With all of these changes and a couple more:
let ordinalSuffix = function 1 -> "st" | 2 -> "nd" | 3 -> "rd" | _ -> "th"
let preamble num =
sprintf "On the %i%s day of Christmas, my true love gave to me" num (ordinalSuffix num)
let line num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let verse num =
preamble num :: [ for i in num .. -1 .. 1 -> line i ]
|> String.concat "n"
[1 .. 12] |> List.map verse |> String.concat "nn" |> printfn "%s"
edited Mar 26 at 15:19
answered Mar 26 at 12:36
TheQuickBrownFox
38116
38116
Great point on appending to a singly-linked list. I was completely unaware that F# devs avoid recursion. Thank you for reminding me of the cons operator in the verse function. Great feedback! Thank you!
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
Great point on appending to a singly-linked list. I was completely unaware that F# devs avoid recursion. Thank you for reminding me of the cons operator in the verse function. Great feedback! Thank you!
â Jim Wharton
Mar 26 at 15:16
Great point on appending to a singly-linked list. I was completely unaware that F# devs avoid recursion. Thank you for reminding me of the cons operator in the verse function. Great feedback! Thank you!
â Jim Wharton
Mar 26 at 15:16
Great point on appending to a singly-linked list. I was completely unaware that F# devs avoid recursion. Thank you for reminding me of the cons operator in the verse function. Great feedback! Thank you!
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
up vote
2
down vote
I think TheQuickBownFox's suggestion is rather elegant. With a little twist (the use of List.mapFold) it is only necessary to call line num once per num:
module Christmas =
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let getVerseLine num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let composeVerse num verseLines =
let verse = (getVerseLine num)::verseLines
(getPreamble num)::verse, verse
let getVerses=
fst ([1 .. 12] |> List.mapFold (fun verseLines num -> composeVerse num verseLines) )
1
mapFoldThat's actually a new one for me. Super cool suggestion.
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
up vote
2
down vote
I think TheQuickBownFox's suggestion is rather elegant. With a little twist (the use of List.mapFold) it is only necessary to call line num once per num:
module Christmas =
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let getVerseLine num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let composeVerse num verseLines =
let verse = (getVerseLine num)::verseLines
(getPreamble num)::verse, verse
let getVerses=
fst ([1 .. 12] |> List.mapFold (fun verseLines num -> composeVerse num verseLines) )
1
mapFoldThat's actually a new one for me. Super cool suggestion.
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
up vote
2
down vote
up vote
2
down vote
I think TheQuickBownFox's suggestion is rather elegant. With a little twist (the use of List.mapFold) it is only necessary to call line num once per num:
module Christmas =
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let getVerseLine num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let composeVerse num verseLines =
let verse = (getVerseLine num)::verseLines
(getPreamble num)::verse, verse
let getVerses=
fst ([1 .. 12] |> List.mapFold (fun verseLines num -> composeVerse num verseLines) )
I think TheQuickBownFox's suggestion is rather elegant. With a little twist (the use of List.mapFold) it is only necessary to call line num once per num:
module Christmas =
let getOrdinal num =
match num with
| 1 -> sprintf "%ist" num
| 2 -> sprintf "%ind" num
| 3 -> sprintf "%ird" num
| _ -> sprintf "%ith" num
let getPreamble num =
sprintf "On the %s day of Christmas, my true love gave to me" (getOrdinal num)
let getVerseLine num =
match num with
| 12 -> "12 drummers drumming"
| 11 -> "11 pipers piping"
| 10 -> "10 lords a-leaping"
| 9 -> "9 ladies dancing"
| 8 -> "8 maids a-milking"
| 7 -> "7 swans a-swimming"
| 6 -> "6 geese a-laying"
| 5 -> "5 golden rings"
| 4 -> "4 calling birds"
| 3 -> "3 French hens"
| 2 -> "2 turtle doves, and"
| _ -> "A partridge in a pear tree"
let composeVerse num verseLines =
let verse = (getVerseLine num)::verseLines
(getPreamble num)::verse, verse
let getVerses=
fst ([1 .. 12] |> List.mapFold (fun verseLines num -> composeVerse num verseLines) )
answered Mar 26 at 13:36
Henrik Hansen
3,8931417
3,8931417
1
mapFoldThat's actually a new one for me. Super cool suggestion.
â Jim Wharton
Mar 26 at 15:16
add a comment |Â
1
mapFoldThat's actually a new one for me. Super cool suggestion.
â Jim Wharton
Mar 26 at 15:16
1
1
mapFold That's actually a new one for me. Super cool suggestion.â Jim Wharton
Mar 26 at 15:16
mapFold That's actually a new one for me. Super cool suggestion.â Jim Wharton
Mar 26 at 15:16
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f190467%2f12-days-of-christmas-with-f%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password