forked from fsprojects/FSharp.Data.SqlClient
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreference architecture.fsx
More file actions
128 lines (110 loc) · 3.26 KB
/
reference architecture.fsx
File metadata and controls
128 lines (110 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
(*** hide ***)
#r "../../bin/FSharp.Data.SqlClient.dll"
(**
Beautiful Functional Architectures
===================
[Project Euler. #17.](https://projecteuler.net/problem=17)
F# solution:
-------------------------------------
*)
let ``1..9`` =
[""; "one"; "two"; "three"; "four"; "five"; "six"; "seven"; "eight"; "nine"]
let ``10..19`` =
["ten"; "eleven"; "twelve"; "thirteen"; "fourteen"; "fifteen"; "sixteen"; "seventeen"; "eighteen"; "nineteen"]
let dozens =
[""; ""; "twenty"; "thirty"; "forty"; "fifty"; "sixty"; "seventy"; "eighty"; "ninety"]
let spellNumber n =
[
if n = 1000 then yield! "onethousand"
else
let hundredsDigit = n / 100
if hundredsDigit > 0 then yield! sprintf "%shundred" ``1..9``.[hundredsDigit]
let moduloOf100 = n % 100
if hundredsDigit <> 0 && moduloOf100 <> 0 then yield! "and"
if moduloOf100 >= 10 && moduloOf100 <= 19 then yield! ``10..19``.[moduloOf100 - 10]
else
yield! dozens.[moduloOf100 / 10] + ``1..9``.[moduloOf100 % 10]
]
[ 1 .. 1000 ]
|> List.collect spellNumber
|> List.length
(**
T-SQL solution:
-------------------------------------
<pre lang = 'sql'>
<code>
CREATE FUNCTION dbo.SpellNumber
(
@n AS INT
)
RETURNS @result TABLE
(
Chars NVARCHAR(MAX) NOT NULL
)
AS
BEGIN
IF @n = 1000
INSERT INTO @result VALUES ('onethousand')
ELSE
WITH Digits AS
(
SELECT offset, value
FROM
(VALUES
(0, ''), (1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'),
(5, 'five'), (6, 'six'), (7, 'seven'), (8, 'eight'), (9, 'nine'))
AS T(offset, value)
),
TenToNineteen AS
(
SELECT offset, value
FROM
(VALUES
(0, 'ten'), (1, 'eleven'), (2, 'twelve'), (3, 'thirteen'), (4, 'fourteen'),
(5, 'fifteen'), (6, 'sixteen'), (7, 'seventeen'), (8, 'eighteen'), (9, 'nineteen'))
AS T(offset, value)
),
Dozens AS
(
SELECT offset, value
FROM
(VALUES
(0, ''), (1, ''), (2, 'twenty'), (3, 'thirty'), (4, 'forty'),
(5, 'fifty'), (6, 'sixty'), (7, 'seventy'), (8, 'eighty'), (9, 'ninety'))
AS T(offset, value)
)
INSERT INTO @result
SELECT value + 'hundred' FROM Digits WHERE @n / 100 > 0 AND offset = @n / 100
UNION ALL
SELECT 'and' WHERE @n / 100 > 0 AND @n % 100 > 0
UNION ALL
SELECT value FROM TenToNineteen WHERE (@n % 100) - 10 = offset
UNION ALL
SELECT value FROM Dozens WHERE (@n % 100 NOT BETWEEN 10 AND 19) AND ((@n % 100) / 10 = offset)
UNION ALL
SELECT value FROM Digits WHERE (@n % 100 NOT BETWEEN 10 AND 19) AND ((@n % 100) % 10 = offset)
RETURN
END
</code>
</pre>
*)
open FSharp.Data
[<Literal>]
let adventureWorks = @"Data Source=(LocalDb)\v12.0;Initial Catalog=AdventureWorks2012;Integrated Security=True;TrustServerCertificate=true"
[<Literal>]
let euler17 = "
WITH InfiniteSeq(N) AS
(
SELECT 1
UNION ALL
SELECT 1 + N FROM InfiniteSeq
)
SELECT SUM(LEN(ys.Chars))
FROM
(SELECT TOP 1000 * FROM InfiniteSeq ) AS xs
CROSS APPLY dbo.SpellNumber(xs.N) AS ys
OPTION (MAXRECURSION 0)
"
type Euler17 = SqlCommandProvider<euler17, adventureWorks, SingleRow = true>
let cmd = new Euler17()
cmd.Execute() |> Option.get |> Option.get |> printfn "%i"