trackler 2.0.6.11 → 2.0.6.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/common/CONTRIBUTING.md +6 -1
- data/common/exercises/difference-of-squares/metadata.yml +1 -1
- data/common/exercises/luhn/canonical-data.json +2 -2
- data/common/exercises/rectangles/canonical-data.json +25 -0
- data/common/exercises/rectangles/description.md +11 -3
- data/lib/trackler/version.rb +1 -1
- data/tracks/ceylon/config.json +9 -0
- data/tracks/ceylon/exercises/anagram/source/anagram/AnagramTest.ceylon +38 -39
- data/tracks/ceylon/exercises/bracket-push/source/bracketpush/BracketsTest.ceylon +28 -29
- data/tracks/ceylon/exercises/largest-series-product/example/Series.ceylon +13 -0
- data/tracks/ceylon/exercises/largest-series-product/source/largestseriesproduct/Series.ceylon +5 -0
- data/tracks/ceylon/exercises/largest-series-product/source/largestseriesproduct/SeriesTest.ceylon +30 -0
- data/tracks/ceylon/exercises/largest-series-product/source/largestseriesproduct/module.ceylon +3 -0
- data/tracks/csharp/config.json +41 -0
- data/tracks/csharp/exercises/alphametics/AlphameticsTest.cs +122 -0
- data/tracks/csharp/exercises/alphametics/Example.cs +139 -0
- data/tracks/csharp/exercises/dot-dsl/DotDslTest.cs +91 -0
- data/tracks/csharp/exercises/dot-dsl/Example.cs +90 -0
- data/tracks/csharp/exercises/dot-dsl/HINTS.md +2 -0
- data/tracks/csharp/exercises/error-handling/ErrorHandlingTest.cs +65 -0
- data/tracks/csharp/exercises/error-handling/Example.cs +34 -0
- data/tracks/csharp/exercises/exercises.csproj +1 -1
- data/tracks/csharp/exercises/hangman/Example.cs +85 -0
- data/tracks/csharp/exercises/hangman/HangmanTest.cs +140 -0
- data/tracks/csharp/exercises/ledger/Example.cs +106 -0
- data/tracks/csharp/exercises/ledger/Ledger.cs +166 -0
- data/tracks/csharp/exercises/ledger/LedgerTest.cs +168 -0
- data/tracks/elixir/exercises/allergies/allergies_test.exs +2 -2
- data/tracks/elixir/exercises/markdown/example.exs +3 -3
- data/tracks/elixir/exercises/phone-number/example.exs +0 -2
- data/tracks/elixir/exercises/queen-attack/example.exs +1 -1
- data/tracks/elixir/exercises/wordy/example.exs +6 -6
- data/tracks/elixir/exercises/zipper/zipper_test.exs +12 -12
- data/tracks/elixir/mix.exs +1 -1
- data/tracks/fsharp/config.json +8 -8
- data/tracks/fsharp/docs/ABOUT.md +4 -0
- data/tracks/fsharp/exercises/alphametics/AlphameticsTest.fs +33 -13
- data/tracks/fsharp/exercises/alphametics/Example.fs +29 -64
- data/tracks/fsharp/exercises/binary-search-tree/BinarySearchTreeTest.fs +14 -14
- data/tracks/fsharp/exercises/binary-search-tree/Example.fs +17 -14
- data/tracks/fsharp/exercises/triangle/TriangleTest.fs +0 -5
- data/tracks/go/README.md +3 -3
- data/tracks/go/config.json +10 -3
- data/tracks/go/exercises/acronym/acronym.go +5 -0
- data/tracks/go/exercises/bob/example_gen.go +1 -1
- data/tracks/go/exercises/clock/example_gen.go +1 -1
- data/tracks/go/exercises/connect/example_gen.go +1 -1
- data/tracks/go/exercises/custom-set/example_gen.go +1 -1
- data/tracks/go/exercises/gigasecond/example_gen.go +1 -1
- data/tracks/go/exercises/hamming/example_gen.go +1 -1
- data/tracks/go/exercises/largest-series-product/example_gen.go +1 -1
- data/tracks/go/exercises/leap/cases_test.go +5 -7
- data/tracks/go/exercises/leap/example.go +1 -1
- data/tracks/go/exercises/leap/example_gen.go +1 -1
- data/tracks/go/exercises/leap/leap.go +1 -1
- data/tracks/go/exercises/leap/leap_test.go +1 -1
- data/tracks/go/exercises/meetup/example_gen.go +1 -1
- data/tracks/go/exercises/nucleotide-count/nucleotide_count_test.go +0 -5
- data/tracks/go/exercises/pangram/pangram.go +5 -0
- data/tracks/go/exercises/raindrops/example_gen.go +1 -1
- data/tracks/go/exercises/rna-transcription/example_gen.go +1 -1
- data/tracks/go/exercises/roman-numerals/example_gen.go +1 -1
- data/tracks/go/exercises/word-count/example_gen.go +1 -1
- data/tracks/go/gen/gen.go +3 -2
- data/tracks/haskell/exercises/accumulate/src/Accumulate.hs +1 -1
- data/tracks/haskell/exercises/all-your-base/src/Base.hs +1 -1
- data/tracks/haskell/exercises/allergies/src/Allergies.hs +2 -2
- data/tracks/haskell/exercises/alphametics/src/Alphametics.hs +1 -1
- data/tracks/haskell/exercises/anagram/src/Anagram.hs +1 -1
- data/tracks/haskell/exercises/atbash-cipher/src/Atbash.hs +2 -2
- data/tracks/haskell/exercises/bank-account/src/BankAccount.hs +4 -4
- data/tracks/haskell/exercises/binary/src/Binary.hs +1 -1
- data/tracks/haskell/exercises/binary-search-tree/src/BST.hs +8 -8
- data/tracks/haskell/exercises/bob/src/Bob.hs +1 -1
- data/tracks/haskell/exercises/bowling/src/Bowling.hs +1 -1
- data/tracks/haskell/exercises/change/src/Change.hs +1 -1
- data/tracks/haskell/exercises/clock/src/Clock.hs +4 -4
- data/tracks/haskell/exercises/connect/src/Connect.hs +1 -1
- data/tracks/haskell/exercises/crypto-square/src/CryptoSquare.hs +1 -1
- data/tracks/haskell/exercises/custom-set/src/CustomSet.hs +13 -13
- data/tracks/haskell/exercises/difference-of-squares/src/Squares.hs +3 -3
- data/tracks/haskell/exercises/dominoes/src/Dominoes.hs +1 -1
- data/tracks/haskell/exercises/etl/src/ETL.hs +1 -1
- data/tracks/haskell/exercises/forth/src/Forth.hs +3 -3
- data/tracks/haskell/exercises/gigasecond/src/Gigasecond.hs +1 -1
- data/tracks/haskell/exercises/go-counting/src/Counting.hs +2 -2
- data/tracks/haskell/exercises/grade-school/src/School.hs +4 -4
- data/tracks/haskell/exercises/grains/src/Grains.hs +2 -2
- data/tracks/haskell/exercises/hamming/src/Hamming.hs +1 -1
- data/tracks/haskell/exercises/hexadecimal/src/Hexadecimal.hs +1 -1
- data/tracks/haskell/exercises/kindergarten-garden/src/Garden.hs +3 -3
- data/tracks/haskell/exercises/largest-series-product/src/Series.hs +1 -1
- data/tracks/haskell/exercises/leap/src/LeapYear.hs +1 -1
- data/tracks/haskell/exercises/lens-person/src/Person.hs +4 -4
- data/tracks/haskell/exercises/linked-list/src/Deque.hs +5 -5
- data/tracks/haskell/exercises/list-ops/src/ListOps.hs +8 -8
- data/tracks/haskell/exercises/luhn/src/Luhn.hs +5 -5
- data/tracks/haskell/exercises/matrix/src/Matrix.hs +10 -10
- data/tracks/haskell/exercises/meetup/src/Meetup.hs +1 -1
- data/tracks/haskell/exercises/minesweeper/src/Minesweeper.hs +1 -1
- data/tracks/haskell/exercises/nth-prime/src/Prime.hs +1 -1
- data/tracks/haskell/exercises/nucleotide-count/src/DNA.hs +2 -2
- data/tracks/haskell/exercises/ocr-numbers/src/OCR.hs +1 -1
- data/tracks/haskell/exercises/octal/src/Octal.hs +2 -2
- data/tracks/haskell/exercises/palindrome-products/src/Palindromes.hs +2 -2
- data/tracks/haskell/exercises/parallel-letter-frequency/src/Frequency.hs +1 -1
- data/tracks/haskell/exercises/pascals-triangle/src/Triangle.hs +1 -1
- data/tracks/haskell/exercises/phone-number/src/Phone.hs +3 -3
- data/tracks/haskell/exercises/pig-latin/src/PigLatin.hs +1 -1
- data/tracks/haskell/exercises/pov/src/POV.hs +2 -2
- data/tracks/haskell/exercises/prime-factors/src/PrimeFactors.hs +1 -1
- data/tracks/haskell/exercises/pythagorean-triplet/src/Triplet.hs +3 -3
- data/tracks/haskell/exercises/queen-attack/src/Queens.hs +2 -2
- data/tracks/haskell/exercises/raindrops/src/Raindrops.hs +1 -1
- data/tracks/haskell/exercises/rna-transcription/src/DNA.hs +1 -1
- data/tracks/haskell/exercises/robot-name/src/Robot.hs +3 -3
- data/tracks/haskell/exercises/robot-simulator/src/Robot.hs +6 -6
- data/tracks/haskell/exercises/roman-numerals/src/Roman.hs +1 -1
- data/tracks/haskell/exercises/run-length-encoding/src/RunLength.hs +2 -2
- data/tracks/haskell/exercises/saddle-points/src/Matrix.hs +1 -1
- data/tracks/haskell/exercises/say/src/Say.hs +1 -1
- data/tracks/haskell/exercises/scrabble-score/src/Scrabble.hs +2 -2
- data/tracks/haskell/exercises/secret-handshake/src/SecretHandshake.hs +1 -1
- data/tracks/haskell/exercises/series/src/Series.hs +1 -1
- data/tracks/haskell/exercises/sgf-parsing/src/Sgf.hs +1 -1
- data/tracks/haskell/exercises/sieve/src/Sieve.hs +1 -1
- data/tracks/haskell/exercises/simple-cipher/src/Cipher.hs +3 -3
- data/tracks/haskell/exercises/simple-linked-list/src/LinkedList.hs +8 -8
- data/tracks/haskell/exercises/space-age/src/SpaceAge.hs +1 -1
- data/tracks/haskell/exercises/strain/src/Strain.hs +2 -2
- data/tracks/haskell/exercises/sublist/src/Sublist.hs +1 -1
- data/tracks/haskell/exercises/sum-of-multiples/src/SumOfMultiples.hs +1 -1
- data/tracks/haskell/exercises/triangle/src/Triangle.hs +1 -1
- data/tracks/haskell/exercises/trinary/src/Trinary.hs +2 -2
- data/tracks/haskell/exercises/word-count/src/WordCount.hs +1 -1
- data/tracks/haskell/exercises/wordy/src/WordProblem.hs +1 -1
- data/tracks/haskell/exercises/zebra-puzzle/src/ZebraPuzzle.hs +1 -1
- data/tracks/haskell/exercises/zipper/src/Zipper.hs +9 -9
- data/tracks/java/docs/MAINTAINING.md +48 -0
- data/tracks/java/exercises/queen-attack/src/test/java/QueenAttackCalculatorTest.java +51 -51
- data/tracks/kotlin/exercises/etl/src/example/kotlin/ETL.kt +1 -1
- data/tracks/kotlin/exercises/etl/src/test/kotlin/ETLTest.kt +19 -19
- data/tracks/kotlin/exercises/pangram/src/test/kotlin/PangramTest.kt +5 -0
- data/tracks/lisp/docs/ABOUT.md +9 -0
- data/tracks/lua/exercises/transpose/example.lua +1 -1
- data/tracks/lua/exercises/transpose/transpose_spec.lua +16 -0
- data/tracks/pascal/config.json +36 -36
- data/tracks/pascal/exercises/bob/uBobTests.pas +0 -1
- data/tracks/pascal/exercises/hamming/uHammingTests.pas +0 -1
- data/tracks/pascal/exercises/leap/uLeapTests.pas +0 -1
- data/tracks/pascal/exercises/saddle-points/uSaddlePointsExample.pas +11 -0
- data/tracks/pascal/exercises/saddle-points/uSaddlePointsTests.pas +9 -1
- data/tracks/perl6/exercises/atbash-cipher/cipher.t +1 -1
- data/tracks/php/config.json +7 -0
- data/tracks/php/exercises/robot-simulator/example.php +148 -0
- data/tracks/php/exercises/robot-simulator/robot-simulator_test.php +168 -0
- data/tracks/pony/config.json +16 -7
- data/tracks/pony/exercises/roman-numerals/example.pony +35 -0
- data/tracks/pony/exercises/roman-numerals/test.pony +45 -0
- data/tracks/python/requirements-travis.txt +1 -1
- data/tracks/ruby/.rubocop.yml +1 -1
- data/tracks/ruby/bin/enable-executable +1 -1
- data/tracks/ruby/bin/executable-tests-check +1 -1
- data/tracks/ruby/exercises/acronym/example.tt +2 -3
- data/tracks/ruby/exercises/all-your-base/example.tt +2 -2
- data/tracks/ruby/exercises/alphametics/example.tt +2 -2
- data/tracks/ruby/exercises/anagram/example.tt +2 -3
- data/tracks/ruby/exercises/binary/example.tt +2 -3
- data/tracks/ruby/exercises/bowling/example.tt +2 -3
- data/tracks/ruby/exercises/bracket-push/example.tt +2 -3
- data/tracks/ruby/exercises/clock/example.tt +2 -3
- data/tracks/ruby/exercises/connect/example.rb +1 -1
- data/tracks/ruby/exercises/connect/example.tt +1 -1
- data/tracks/ruby/exercises/custom-set/example.tt +2 -3
- data/tracks/ruby/exercises/diamond/example.rb +1 -1
- data/tracks/ruby/exercises/difference-of-squares/example.tt +2 -3
- data/tracks/ruby/exercises/dominoes/example.tt +2 -2
- data/tracks/ruby/exercises/gigasecond/example.tt +2 -3
- data/tracks/ruby/exercises/grains/example.tt +2 -2
- data/tracks/ruby/exercises/hamming/example.tt +2 -3
- data/tracks/ruby/exercises/hello-world/example.tt +1 -2
- data/tracks/ruby/exercises/isogram/example.tt +2 -2
- data/tracks/ruby/exercises/largest-series-product/example.tt +2 -4
- data/tracks/ruby/exercises/leap/example.tt +2 -3
- data/tracks/ruby/exercises/nth-prime/example.tt +2 -4
- data/tracks/ruby/exercises/pangram/example.tt +2 -2
- data/tracks/ruby/exercises/queen-attack/example.tt +2 -3
- data/tracks/ruby/exercises/raindrops/example.tt +2 -3
- data/tracks/ruby/exercises/rna-transcription/example.tt +2 -3
- data/tracks/ruby/exercises/roman-numerals/example.tt +2 -3
- data/tracks/ruby/exercises/run-length-encoding/example.tt +2 -3
- data/tracks/ruby/exercises/sieve/example.tt +2 -4
- data/tracks/ruby/exercises/simple-linked-list/simple_linked_list_test.rb +6 -6
- data/tracks/ruby/exercises/tournament/example.tt +2 -3
- data/tracks/ruby/exercises/transpose/example.tt +2 -3
- data/tracks/ruby/exercises/triangle/example.tt +2 -3
- data/tracks/ruby/exercises/two-bucket/example.tt +2 -3
- data/tracks/ruby/exercises/word-count/example.tt +2 -3
- data/tracks/ruby/exercises/wordy/example.tt +2 -2
- data/tracks/ruby/lib/acronym_cases.rb +2 -0
- data/tracks/ruby/lib/all_your_base_cases.rb +3 -1
- data/tracks/ruby/lib/alphametics_cases.rb +6 -4
- data/tracks/ruby/lib/anagram_cases.rb +2 -0
- data/tracks/ruby/lib/binary_cases.rb +2 -0
- data/tracks/ruby/lib/bowling_cases.rb +2 -0
- data/tracks/ruby/lib/bracket_push_cases.rb +2 -0
- data/tracks/ruby/lib/clock_cases.rb +2 -0
- data/tracks/ruby/lib/connect_cases.rb +2 -0
- data/tracks/ruby/lib/custom_set_cases.rb +2 -0
- data/tracks/ruby/lib/difference_of_squares_cases.rb +2 -0
- data/tracks/ruby/lib/dominoes_cases.rb +2 -0
- data/tracks/ruby/lib/exercise_cases.rb +2 -0
- data/tracks/ruby/lib/generator/files/track_files.rb +3 -3
- data/tracks/ruby/lib/generator/files.rb +1 -1
- data/tracks/ruby/lib/generator/template_values.rb +5 -14
- data/tracks/ruby/lib/gigasecond_cases.rb +2 -0
- data/tracks/ruby/lib/grains_cases.rb +3 -1
- data/tracks/ruby/lib/hamming_cases.rb +2 -0
- data/tracks/ruby/lib/hello_world_cases.rb +2 -0
- data/tracks/ruby/lib/isogram_cases.rb +3 -1
- data/tracks/ruby/lib/largest_series_product_cases.rb +2 -0
- data/tracks/ruby/lib/leap_cases.rb +2 -0
- data/tracks/ruby/lib/nth_prime_cases.rb +2 -0
- data/tracks/ruby/lib/pangram_cases.rb +3 -1
- data/tracks/ruby/lib/queen_attack_cases.rb +2 -0
- data/tracks/ruby/lib/raindrops_cases.rb +2 -0
- data/tracks/ruby/lib/rna_transcription_cases.rb +2 -0
- data/tracks/ruby/lib/roman_numerals_cases.rb +2 -0
- data/tracks/ruby/lib/run_length_encoding_cases.rb +2 -0
- data/tracks/ruby/lib/sieve_cases.rb +2 -0
- data/tracks/ruby/lib/tournament_cases.rb +2 -0
- data/tracks/ruby/lib/transpose_cases.rb +2 -0
- data/tracks/ruby/lib/triangle_cases.rb +2 -0
- data/tracks/ruby/lib/two_bucket_cases.rb +2 -0
- data/tracks/ruby/lib/word_count_cases.rb +2 -0
- data/tracks/ruby/lib/wordy_cases.rb +2 -0
- data/tracks/ruby/test/fixtures/xruby/exercises/alpha/example.tt +2 -2
- data/tracks/ruby/test/fixtures/xruby/lib/alpha_cases.rb +1 -1
- data/tracks/ruby/test/generator/command_line_test.rb +1 -1
- data/tracks/ruby/test/generator/template_values_test.rb +7 -7
- data/tracks/rust/.travis.yml +4 -0
- data/tracks/rust/_test/check-exercises.sh +11 -2
- data/tracks/rust/config.json +9 -0
- data/tracks/rust/exercises/luhn/.gitignore +7 -0
- data/tracks/rust/exercises/luhn/Cargo.toml +3 -0
- data/tracks/rust/exercises/luhn/example.rs +13 -0
- data/tracks/rust/exercises/luhn/tests/luhn.rs +38 -0
- data/tracks/rust/exercises/parallel-letter-frequency/HINTS.md +32 -0
- data/tracks/rust/exercises/parallel-letter-frequency/benches/benchmark.rs +99 -0
- data/tracks/scala/config.json +57 -1
- data/tracks/scala/exercises/allergies/build.sbt +2 -2
- data/tracks/scala/exercises/atbash-cipher/build.sbt +2 -2
- data/tracks/scala/exercises/bank-account/build.sbt +3 -2
- data/tracks/scala/exercises/binary-search-tree/build.sbt +2 -2
- data/tracks/scala/exercises/clock/build.sbt +2 -2
- data/tracks/scala/exercises/crypto-square/build.sbt +2 -2
- data/tracks/scala/exercises/custom-set/build.sbt +3 -2
- data/tracks/scala/exercises/food-chain/build.sbt +3 -2
- data/tracks/scala/exercises/house/build.sbt +2 -2
- data/tracks/scala/exercises/kindergarten-garden/build.sbt +3 -2
- data/tracks/scala/exercises/largest-series-product/build.sbt +2 -2
- data/tracks/scala/exercises/linked-list/build.sbt +3 -2
- data/tracks/scala/exercises/matrix/build.sbt +2 -2
- data/tracks/scala/exercises/minesweeper/build.sbt +2 -2
- data/tracks/scala/exercises/nth-prime/build.sbt +2 -2
- data/tracks/scala/exercises/ocr-numbers/build.sbt +2 -2
- data/tracks/scala/exercises/palindrome-products/build.sbt +2 -2
- data/tracks/scala/exercises/prime-factors/build.sbt +3 -2
- data/tracks/scala/exercises/queen-attack/build.sbt +2 -2
- data/tracks/scala/exercises/raindrops/build.sbt +2 -2
- data/tracks/scala/exercises/robot-simulator/build.sbt +2 -2
- data/tracks/scala/exercises/triangle/build.sbt +2 -2
- data/tracks/scala/exercises/trinary/build.sbt +2 -2
- data/tracks/scala/exercises/wordy/build.sbt +3 -3
- metadata +33 -2
@@ -0,0 +1,106 @@
|
|
1
|
+
using System;
|
2
|
+
using System.Collections.Generic;
|
3
|
+
using System.Globalization;
|
4
|
+
using System.Linq;
|
5
|
+
|
6
|
+
public class LedgerEntry
|
7
|
+
{
|
8
|
+
public LedgerEntry(DateTime date, string description, float change)
|
9
|
+
{
|
10
|
+
Date = date;
|
11
|
+
Description = description;
|
12
|
+
Change = change;
|
13
|
+
}
|
14
|
+
|
15
|
+
public DateTime Date { get; }
|
16
|
+
public string Description { get; }
|
17
|
+
public float Change { get; }
|
18
|
+
}
|
19
|
+
|
20
|
+
public static class Ledger
|
21
|
+
{
|
22
|
+
private const int TruncateLength = 25;
|
23
|
+
private const string TruncateSuffix = "...";
|
24
|
+
|
25
|
+
public static LedgerEntry CreateEntry(string date, string description, int change) =>
|
26
|
+
new LedgerEntry(ParseDate(date), description, ParseChange(change));
|
27
|
+
|
28
|
+
private static DateTime ParseDate(string date) => DateTime.Parse(date, System.Globalization.CultureInfo.InvariantCulture);
|
29
|
+
|
30
|
+
private static float ParseChange(int change) => change / 100.0f;
|
31
|
+
|
32
|
+
private static string CurrencySymbol(string currency)
|
33
|
+
{
|
34
|
+
switch (currency)
|
35
|
+
{
|
36
|
+
case "USD": return "$";
|
37
|
+
case "EUR": return "€";
|
38
|
+
default: throw new ArgumentException("Invalid currency");
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
private static CultureInfo CultureInfo(string locale)
|
43
|
+
{
|
44
|
+
switch (locale)
|
45
|
+
{
|
46
|
+
case "en-US": return new CultureInfo(locale);
|
47
|
+
case "nl-NL": return new CultureInfo(locale);
|
48
|
+
default: throw new ArgumentException("Invalid locale");
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
private static string ShortDateFormat(string locale)
|
53
|
+
{
|
54
|
+
switch (locale)
|
55
|
+
{
|
56
|
+
case "en-US": return "MM/dd/yyyy";
|
57
|
+
case "nl-NL": return "dd/MM/yyyy";
|
58
|
+
default: throw new ArgumentException("Invalid locale");
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
private static CultureInfo getCulture(string currency, string locale)
|
63
|
+
{
|
64
|
+
var culture = CultureInfo(locale);
|
65
|
+
culture.NumberFormat.CurrencySymbol = CurrencySymbol(currency);
|
66
|
+
culture.DateTimeFormat.ShortDatePattern = ShortDateFormat(locale);
|
67
|
+
return culture;
|
68
|
+
}
|
69
|
+
|
70
|
+
private static string FormatHeader(CultureInfo culture)
|
71
|
+
{
|
72
|
+
switch (culture.Name)
|
73
|
+
{
|
74
|
+
case "en-US": return "Date | Description | Change ";
|
75
|
+
case "nl-NL": return "Datum | Omschrijving | Verandering ";
|
76
|
+
default: throw new ArgumentException("Invalid locale");
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
private static string FormatDate(IFormatProvider culture, DateTime date) => date.ToString("d", culture);
|
81
|
+
|
82
|
+
private static string FoormatDescription(string description) =>
|
83
|
+
description.Length <= TruncateLength ? description : description.Substring(0, TruncateLength - TruncateSuffix.Length) + TruncateSuffix;
|
84
|
+
|
85
|
+
private static string FormatChange(IFormatProvider culture, float change) =>
|
86
|
+
change < 0.0 ? change.ToString("C", culture) : change.ToString("C", culture) + " ";
|
87
|
+
|
88
|
+
private static string FormatEntry(IFormatProvider culture, LedgerEntry entry) =>
|
89
|
+
string.Format("{0} | {1,-25} | {2,13}", FormatDate(culture, entry.Date), FoormatDescription(entry.Description), FormatChange(culture, entry.Change));
|
90
|
+
|
91
|
+
private static IEnumerable<LedgerEntry> OrderEntries(LedgerEntry[] entries) =>
|
92
|
+
entries
|
93
|
+
.OrderBy(x => x.Date)
|
94
|
+
.ThenBy(x => x.Description)
|
95
|
+
.ThenBy(x => x.Change);
|
96
|
+
|
97
|
+
public static string Format(string currency, string locale, LedgerEntry[] entries)
|
98
|
+
{
|
99
|
+
var culture = getCulture(currency, locale);
|
100
|
+
var header = FormatHeader(culture);
|
101
|
+
var printedEntries = OrderEntries(entries).Select(entry => FormatEntry(culture, entry));
|
102
|
+
var lines = new[] { header }.Concat(printedEntries);
|
103
|
+
|
104
|
+
return string.Join("\n", lines);
|
105
|
+
}
|
106
|
+
}
|
@@ -0,0 +1,166 @@
|
|
1
|
+
using System;
|
2
|
+
using System.Collections.Generic;
|
3
|
+
using System.Globalization;
|
4
|
+
using System.Linq;
|
5
|
+
|
6
|
+
public class LedgerEntry
|
7
|
+
{
|
8
|
+
public LedgerEntry(DateTime date, string desc, float chg)
|
9
|
+
{
|
10
|
+
Date = date;
|
11
|
+
Desc = desc;
|
12
|
+
Chg = chg;
|
13
|
+
}
|
14
|
+
|
15
|
+
public DateTime Date { get; }
|
16
|
+
public string Desc { get; }
|
17
|
+
public float Chg { get; }
|
18
|
+
}
|
19
|
+
|
20
|
+
public static class Ledger
|
21
|
+
{
|
22
|
+
public static LedgerEntry CreateEntry(string date, string desc, int chng)
|
23
|
+
{
|
24
|
+
return new LedgerEntry(DateTime.Parse(date, CultureInfo.InvariantCulture), desc, chng / 100.0f);
|
25
|
+
}
|
26
|
+
|
27
|
+
private static CultureInfo CreateCulture(string cur, string loc)
|
28
|
+
{
|
29
|
+
string curSymb = null;
|
30
|
+
string datPat = null;
|
31
|
+
|
32
|
+
if (cur != "USD" && cur != "EUR")
|
33
|
+
{
|
34
|
+
throw new ArgumentException("Invalid currency");
|
35
|
+
}
|
36
|
+
else
|
37
|
+
{
|
38
|
+
if (loc != "nl-NL" && loc != "en-US")
|
39
|
+
{
|
40
|
+
throw new ArgumentException("Invalid currency");
|
41
|
+
}
|
42
|
+
|
43
|
+
if (cur == "USD")
|
44
|
+
{
|
45
|
+
if (loc == "en-US")
|
46
|
+
{
|
47
|
+
curSymb = "$";
|
48
|
+
datPat = "MM/dd/yyyy";
|
49
|
+
}
|
50
|
+
else if (loc == "nl-NL")
|
51
|
+
{
|
52
|
+
curSymb = "$";
|
53
|
+
datPat = "dd/MM/yyyy";
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
|
58
|
+
if (cur == "EUR")
|
59
|
+
{
|
60
|
+
if (loc == "en-US")
|
61
|
+
{
|
62
|
+
curSymb = "€";
|
63
|
+
datPat = "MM/dd/yyyy";
|
64
|
+
}
|
65
|
+
else if (loc == "nl-NL")
|
66
|
+
{
|
67
|
+
curSymb = "€";
|
68
|
+
datPat = "dd/MM/yyyy";
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
var culture = new CultureInfo(loc);
|
74
|
+
culture.NumberFormat.CurrencySymbol = curSymb;
|
75
|
+
culture.DateTimeFormat.ShortDatePattern = datPat;
|
76
|
+
return culture;
|
77
|
+
}
|
78
|
+
|
79
|
+
private static string PrintHead(string loc)
|
80
|
+
{
|
81
|
+
if (loc == "en-US")
|
82
|
+
{
|
83
|
+
return "Date | Description | Change ";
|
84
|
+
}
|
85
|
+
|
86
|
+
else
|
87
|
+
{
|
88
|
+
if (loc == "nl-NL")
|
89
|
+
{
|
90
|
+
return "Datum | Omschrijving | Verandering ";
|
91
|
+
}
|
92
|
+
else
|
93
|
+
{
|
94
|
+
throw new ArgumentException("Invalid locale");
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
private static string Date(IFormatProvider culture, DateTime date) => date.ToString("d", culture);
|
100
|
+
|
101
|
+
private static string Description(string desc)
|
102
|
+
{
|
103
|
+
if (desc.Length > 25)
|
104
|
+
{
|
105
|
+
var trunc = desc.Substring(0, 22);
|
106
|
+
trunc += "...";
|
107
|
+
return trunc;
|
108
|
+
}
|
109
|
+
|
110
|
+
return desc;
|
111
|
+
}
|
112
|
+
|
113
|
+
private static string Change(IFormatProvider culture, float cgh)
|
114
|
+
{
|
115
|
+
return cgh < 0.0 ? cgh.ToString("C", culture) : cgh.ToString("C", culture) + " ";
|
116
|
+
}
|
117
|
+
|
118
|
+
private static string PrintEntry(IFormatProvider culture, LedgerEntry entry)
|
119
|
+
{
|
120
|
+
var formatted = "";
|
121
|
+
var date = Date(culture, entry.Date);
|
122
|
+
var description = Description(entry.Desc);
|
123
|
+
var change = Change(culture, entry.Chg);
|
124
|
+
|
125
|
+
formatted += date;
|
126
|
+
formatted += " | ";
|
127
|
+
formatted += string.Format("{0,-25}", description);
|
128
|
+
formatted += " | ";
|
129
|
+
formatted += string.Format("{0,13}", change);
|
130
|
+
|
131
|
+
return formatted;
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
private static IEnumerable<LedgerEntry> sort(LedgerEntry[] entries)
|
136
|
+
{
|
137
|
+
var neg = entries.Where(e => e.Chg < 0).OrderBy(x => x.Date + "@" + x.Desc + "@" + x.Chg);
|
138
|
+
var post = entries.Where(e => e.Chg >= 0).OrderBy(x => x.Date + "@" + x.Desc + "@" + x.Chg);
|
139
|
+
|
140
|
+
var result = new List<LedgerEntry>();
|
141
|
+
result.AddRange(neg);
|
142
|
+
result.AddRange(post);
|
143
|
+
|
144
|
+
return result;
|
145
|
+
}
|
146
|
+
|
147
|
+
public static string Format(string currency, string locale, LedgerEntry[] entries)
|
148
|
+
{
|
149
|
+
var formatted = "";
|
150
|
+
formatted += PrintHead(locale);
|
151
|
+
|
152
|
+
var culture = CreateCulture(currency, locale);
|
153
|
+
|
154
|
+
if (entries.Length > 0)
|
155
|
+
{
|
156
|
+
var entriesForOutput = sort(entries);
|
157
|
+
|
158
|
+
for (var i = 0; i < entriesForOutput.Count(); i++)
|
159
|
+
{
|
160
|
+
formatted += "\n" + PrintEntry(culture, entriesForOutput.Skip(i).First());
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
return formatted;
|
165
|
+
}
|
166
|
+
}
|
@@ -0,0 +1,168 @@
|
|
1
|
+
using NUnit.Framework;
|
2
|
+
|
3
|
+
public class LedgerTest
|
4
|
+
{
|
5
|
+
[Test]
|
6
|
+
public void Empty_ledger()
|
7
|
+
{
|
8
|
+
var currency = "USD";
|
9
|
+
var locale = "en-US";
|
10
|
+
var entries = new LedgerEntry[0];
|
11
|
+
var expected =
|
12
|
+
"Date | Description | Change ";
|
13
|
+
|
14
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
15
|
+
}
|
16
|
+
|
17
|
+
[Test]
|
18
|
+
public void One_entry()
|
19
|
+
{
|
20
|
+
var currency = "USD";
|
21
|
+
var locale = "en-US";
|
22
|
+
var entries = new[]
|
23
|
+
{
|
24
|
+
Ledger.CreateEntry("2015-01-01", "Buy present", -1000)
|
25
|
+
};
|
26
|
+
var expected =
|
27
|
+
"Date | Description | Change \n" +
|
28
|
+
"01/01/2015 | Buy present | ($10.00)";
|
29
|
+
|
30
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
31
|
+
}
|
32
|
+
|
33
|
+
[Test]
|
34
|
+
public void Credit_and_debit()
|
35
|
+
{
|
36
|
+
var currency = "USD";
|
37
|
+
var locale = "en-US";
|
38
|
+
var entries = new[]
|
39
|
+
{
|
40
|
+
Ledger.CreateEntry("2015-01-02", "Get present", 1000),
|
41
|
+
Ledger.CreateEntry("2015-01-01", "Buy present", -1000)
|
42
|
+
};
|
43
|
+
var expected =
|
44
|
+
"Date | Description | Change \n" +
|
45
|
+
"01/01/2015 | Buy present | ($10.00)\n" +
|
46
|
+
"01/02/2015 | Get present | $10.00 ";
|
47
|
+
|
48
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
49
|
+
}
|
50
|
+
|
51
|
+
[Test]
|
52
|
+
public void Multiple_entries_on_same_date_ordered_by_description()
|
53
|
+
{
|
54
|
+
var currency = "USD";
|
55
|
+
var locale = "en-US";
|
56
|
+
var entries = new[]
|
57
|
+
{
|
58
|
+
Ledger.CreateEntry("2015-01-01", "Buy present", -1000),
|
59
|
+
Ledger.CreateEntry("2015-01-01", "Get present", 1000)
|
60
|
+
};
|
61
|
+
var expected =
|
62
|
+
"Date | Description | Change \n" +
|
63
|
+
"01/01/2015 | Buy present | ($10.00)\n" +
|
64
|
+
"01/01/2015 | Get present | $10.00 ";
|
65
|
+
|
66
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
67
|
+
}
|
68
|
+
|
69
|
+
[Test]
|
70
|
+
public void Final_order_tie_breaker_is_change()
|
71
|
+
{
|
72
|
+
var currency = "USD";
|
73
|
+
var locale = "en-US";
|
74
|
+
var entries = new[]
|
75
|
+
{
|
76
|
+
Ledger.CreateEntry("2015-01-01", "Something", 0),
|
77
|
+
Ledger.CreateEntry("2015-01-01", "Something", -1),
|
78
|
+
Ledger.CreateEntry("2015-01-01", "Something", 1)
|
79
|
+
};
|
80
|
+
var expected =
|
81
|
+
"Date | Description | Change \n" +
|
82
|
+
"01/01/2015 | Something | ($0.01)\n" +
|
83
|
+
"01/01/2015 | Something | $0.00 \n" +
|
84
|
+
"01/01/2015 | Something | $0.01 ";
|
85
|
+
|
86
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
87
|
+
}
|
88
|
+
|
89
|
+
[Test]
|
90
|
+
public void Overlong_descriptions()
|
91
|
+
{
|
92
|
+
var currency = "USD";
|
93
|
+
var locale = "en-US";
|
94
|
+
var entries = new[]
|
95
|
+
{
|
96
|
+
Ledger.CreateEntry("2015-01-01", "Freude schoner Gotterfunken", -123456)
|
97
|
+
};
|
98
|
+
var expected =
|
99
|
+
"Date | Description | Change \n" +
|
100
|
+
"01/01/2015 | Freude schoner Gotterf... | ($1,234.56)";
|
101
|
+
|
102
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
103
|
+
}
|
104
|
+
|
105
|
+
[Test]
|
106
|
+
public void Euros()
|
107
|
+
{
|
108
|
+
var currency = "EUR";
|
109
|
+
var locale = "en-US";
|
110
|
+
var entries = new[]
|
111
|
+
{
|
112
|
+
Ledger.CreateEntry("2015-01-01", "Buy present", -1000)
|
113
|
+
};
|
114
|
+
var expected =
|
115
|
+
"Date | Description | Change \n" +
|
116
|
+
"01/01/2015 | Buy present | (€10.00)";
|
117
|
+
|
118
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
119
|
+
}
|
120
|
+
|
121
|
+
[Test]
|
122
|
+
public void Dutch_locale()
|
123
|
+
{
|
124
|
+
var currency = "USD";
|
125
|
+
var locale = "nl-NL";
|
126
|
+
var entries = new[]
|
127
|
+
{
|
128
|
+
Ledger.CreateEntry("2015-03-12", "Buy present", 123456)
|
129
|
+
};
|
130
|
+
var expected =
|
131
|
+
"Datum | Omschrijving | Verandering \n" +
|
132
|
+
"12-03-2015 | Buy present | $ 1.234,56 ";
|
133
|
+
|
134
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
135
|
+
}
|
136
|
+
|
137
|
+
[Test]
|
138
|
+
public void Dutch_negative_number_with_3_digits_before_decimal_point()
|
139
|
+
{
|
140
|
+
var currency = "USD";
|
141
|
+
var locale = "nl-NL";
|
142
|
+
var entries = new[]
|
143
|
+
{
|
144
|
+
Ledger.CreateEntry("2015-03-12", "Buy present", -12345)
|
145
|
+
};
|
146
|
+
var expected =
|
147
|
+
"Datum | Omschrijving | Verandering \n" +
|
148
|
+
"12-03-2015 | Buy present | $ -123,45";
|
149
|
+
|
150
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
151
|
+
}
|
152
|
+
|
153
|
+
[Test]
|
154
|
+
public void American_negative_number_with_3_digits_before_decimal_point()
|
155
|
+
{
|
156
|
+
var currency = "USD";
|
157
|
+
var locale = "en-US";
|
158
|
+
var entries = new[]
|
159
|
+
{
|
160
|
+
Ledger.CreateEntry("2015-03-12", "Buy present", -12345)
|
161
|
+
};
|
162
|
+
var expected =
|
163
|
+
"Date | Description | Change \n" +
|
164
|
+
"03/12/2015 | Buy present | ($123.45)";
|
165
|
+
|
166
|
+
Assert.That(Ledger.Format(currency, locale, entries), Is.EqualTo(expected));
|
167
|
+
}
|
168
|
+
}
|
@@ -75,9 +75,9 @@ defmodule AllergiesTest do
|
|
75
75
|
set = Enum.into(list, MapSet.new)
|
76
76
|
same_contents = to_contain
|
77
77
|
|> Enum.into(MapSet.new)
|
78
|
-
|>
|
78
|
+
|> MapSet.equal?(set)
|
79
79
|
assert same_contents,
|
80
|
-
"Expected a set with: #{inspect to_contain} got #{inspect set |>
|
80
|
+
"Expected a set with: #{inspect to_contain} got #{inspect set |> MapSet.to_list}"
|
81
81
|
end
|
82
82
|
|
83
83
|
end
|
@@ -27,9 +27,9 @@ defmodule Markdown do
|
|
27
27
|
|
28
28
|
defp process_md(text_with_md) do
|
29
29
|
cond do
|
30
|
-
String.starts_with?(text_with_md,
|
31
|
-
String.starts_with?(text_with_md,
|
32
|
-
true
|
30
|
+
String.starts_with?(text_with_md, @header_md) -> parse_header_md_level(text_with_md) |> enclose_with_header_tag
|
31
|
+
String.starts_with?(text_with_md, @list_md) -> parse_list_md_level(text_with_md)
|
32
|
+
true -> String.split(text_with_md) |> enclose_with_paragraph_tag
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -19,7 +19,7 @@ defmodule Queens do
|
|
19
19
|
"""
|
20
20
|
@spec to_string(Queens.t()) :: String.t()
|
21
21
|
def to_string(%Queens{ white: white, black: black }) do
|
22
|
-
generate_board
|
22
|
+
generate_board()
|
23
23
|
|> insert_queen(white, "W")
|
24
24
|
|> insert_queen(black, "B")
|
25
25
|
|> Enum.map(&Enum.join(&1, " "))
|
@@ -16,7 +16,7 @@ defmodule Wordy do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
defp tokenize(sentence) do
|
19
|
-
Regex.scan(~r/(#{all_matchers})/, sentence)
|
19
|
+
Regex.scan(~r/(#{all_matchers()})/, sentence)
|
20
20
|
|> Enum.map(&(Enum.at(&1,0)))
|
21
21
|
end
|
22
22
|
|
@@ -53,7 +53,7 @@ defmodule Wordy do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def match?(token) do
|
56
|
-
String.match?(token,~r/#{matcher}/)
|
56
|
+
String.match?(token,~r/#{matcher()}/)
|
57
57
|
end
|
58
58
|
|
59
59
|
def parse(token) do
|
@@ -67,7 +67,7 @@ defmodule Wordy do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def match?(token) do
|
70
|
-
String.match?(token,~r/#{matcher}/)
|
70
|
+
String.match?(token,~r/#{matcher()}/)
|
71
71
|
end
|
72
72
|
|
73
73
|
def parse(_) do
|
@@ -85,7 +85,7 @@ defmodule Wordy do
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def match?(token) do
|
88
|
-
String.match?(token,~r/#{matcher}/)
|
88
|
+
String.match?(token,~r/#{matcher()}/)
|
89
89
|
end
|
90
90
|
|
91
91
|
def parse(_) do
|
@@ -103,7 +103,7 @@ defmodule Wordy do
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def match?(token) do
|
106
|
-
String.match?(token,~r/#{matcher}/)
|
106
|
+
String.match?(token,~r/#{matcher()}/)
|
107
107
|
end
|
108
108
|
|
109
109
|
def parse(_) do
|
@@ -121,7 +121,7 @@ defmodule Wordy do
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def match?(token) do
|
124
|
-
String.match?(token,~r/#{matcher}/)
|
124
|
+
String.match?(token,~r/#{matcher()}/)
|
125
125
|
end
|
126
126
|
|
127
127
|
def parse(_) do
|
@@ -23,61 +23,61 @@ defmodule ZipperTest do
|
|
23
23
|
|
24
24
|
# @tag :pending
|
25
25
|
test "data is retained" do
|
26
|
-
assert (t1 |> from_tree |> to_tree) == t1
|
26
|
+
assert (t1() |> from_tree |> to_tree) == t1()
|
27
27
|
end
|
28
28
|
|
29
29
|
@tag :pending
|
30
30
|
test "left, right and value" do
|
31
|
-
assert (t1 |> from_tree |> left |> right |> value) == 3
|
31
|
+
assert (t1() |> from_tree |> left |> right |> value) == 3
|
32
32
|
end
|
33
33
|
|
34
34
|
@tag :pending
|
35
35
|
test "dead end" do
|
36
|
-
assert (t1 |> from_tree |> left |> left) == nil
|
36
|
+
assert (t1() |> from_tree |> left |> left) == nil
|
37
37
|
end
|
38
38
|
|
39
39
|
@tag :pending
|
40
40
|
test "tree from deep focus" do
|
41
|
-
assert (t1 |> from_tree |> left |> right |> to_tree) == t1
|
41
|
+
assert (t1() |> from_tree |> left |> right |> to_tree) == t1()
|
42
42
|
end
|
43
43
|
|
44
44
|
@tag :pending
|
45
45
|
test "traversing up from top" do
|
46
|
-
assert (t1 |> from_tree |> up) == nil
|
46
|
+
assert (t1() |> from_tree |> up) == nil
|
47
47
|
end
|
48
48
|
|
49
49
|
@tag :pending
|
50
50
|
test "left, right, and up" do
|
51
|
-
assert (t1 |> from_tree |> left |> up |> right |> up |> left |> right |> value) == 3
|
51
|
+
assert (t1() |> from_tree |> left |> up |> right |> up |> left |> right |> value) == 3
|
52
52
|
end
|
53
53
|
|
54
54
|
@tag :pending
|
55
55
|
test "set_value" do
|
56
|
-
assert (t1 |> from_tree |> left |> set_value(5) |> to_tree) == t2
|
56
|
+
assert (t1() |> from_tree |> left |> set_value(5) |> to_tree) == t2()
|
57
57
|
end
|
58
58
|
|
59
59
|
@tag :pending
|
60
60
|
test "set_value after traversing up" do
|
61
|
-
assert (t1 |> from_tree |> left |> right |> up |> set_value(5) |> to_tree) == t2
|
61
|
+
assert (t1() |> from_tree |> left |> right |> up |> set_value(5) |> to_tree) == t2()
|
62
62
|
end
|
63
63
|
|
64
64
|
@tag :pending
|
65
65
|
test "set_left with leaf" do
|
66
|
-
assert (t1 |> from_tree |> left |> set_left(leaf(5)) |> to_tree) == t3
|
66
|
+
assert (t1() |> from_tree |> left |> set_left(leaf(5)) |> to_tree) == t3()
|
67
67
|
end
|
68
68
|
|
69
69
|
@tag :pending
|
70
70
|
test "set_right with nil" do
|
71
|
-
assert (t1 |> from_tree |> left |> set_right(nil) |> to_tree) == t4
|
71
|
+
assert (t1() |> from_tree |> left |> set_right(nil) |> to_tree) == t4()
|
72
72
|
end
|
73
73
|
|
74
74
|
@tag :pending
|
75
75
|
test "set_right with subtree" do
|
76
|
-
assert (t1 |> from_tree |> set_right(bt(6, leaf(7), leaf(8))) |> to_tree) == t5
|
76
|
+
assert (t1() |> from_tree |> set_right(bt(6, leaf(7), leaf(8))) |> to_tree) == t5()
|
77
77
|
end
|
78
78
|
|
79
79
|
@tag :pending
|
80
80
|
test "set_value on deep focus" do
|
81
|
-
assert (t1 |> from_tree |> left |> right |> set_value(5) |> to_tree) == t6
|
81
|
+
assert (t1() |> from_tree |> left |> right |> set_value(5) |> to_tree) == t6()
|
82
82
|
end
|
83
83
|
end
|
data/tracks/elixir/mix.exs
CHANGED
data/tracks/fsharp/config.json
CHANGED
@@ -803,6 +803,14 @@
|
|
803
803
|
"Transforming"
|
804
804
|
]
|
805
805
|
},
|
806
|
+
{
|
807
|
+
"slug": "alphametics",
|
808
|
+
"difficulty": 9,
|
809
|
+
"topics": [
|
810
|
+
"Parsing",
|
811
|
+
"Maps"
|
812
|
+
]
|
813
|
+
},
|
806
814
|
{
|
807
815
|
"slug": "zipper",
|
808
816
|
"difficulty": 10,
|
@@ -828,14 +836,6 @@
|
|
828
836
|
"Recursion",
|
829
837
|
"Searching"
|
830
838
|
]
|
831
|
-
},
|
832
|
-
{
|
833
|
-
"slug": "alphametics",
|
834
|
-
"difficulty": 10,
|
835
|
-
"topics": [
|
836
|
-
"Parsing",
|
837
|
-
"Maps"
|
838
|
-
]
|
839
839
|
}
|
840
840
|
],
|
841
841
|
"deprecated": [
|
data/tracks/fsharp/docs/ABOUT.md
CHANGED
@@ -1 +1,5 @@
|
|
1
1
|
[F#](http://www.tryfsharp.org/Explore) is a strongly-typed, functional language that is part of Microsoft's .NET language stack.
|
2
|
+
|
3
|
+
Although F# is great for data science problems, it can elegantly handle almost every problem you throw at it. As F# runs on the .NET runtime, you get access to the entire .NET ecosystem, including all packages on [nuget.org](https://www.nuget.org/). This integration is further simplified due to F# also allowing you to write object-oriented code.
|
4
|
+
|
5
|
+
The home page for F# is [fsharp.org](http://fsharp.org/). A great introduction to F# can be found at the [F# for fun and profit](http://fsharpforfunandprofit.com/) website.
|