init
This commit is contained in:
commit
105e38b22f
|
@ -0,0 +1,17 @@
|
|||
.DS_Store
|
||||
/.tags
|
||||
/.tags_sorted_by_file
|
||||
/.vagrant
|
||||
.crystal/
|
||||
coverage/
|
||||
/deps/
|
||||
/.build/
|
||||
.*.swp
|
||||
/Makefile.local
|
||||
all_spec
|
||||
/tmp
|
||||
/docs/
|
||||
/src/llvm/ext/llvm_ext.o
|
||||
/src/llvm/ext/llvm_ext.dwo
|
||||
/src/ext/*.o
|
||||
/src/ext/libcrystal.a
|
|
@ -0,0 +1,78 @@
|
|||
# Hello World
|
||||
|
||||
The classical introductory exercise. Just say "Hello, World!".
|
||||
|
||||
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is
|
||||
the traditional first program for beginning programming in a new language
|
||||
or environment.
|
||||
|
||||
The objectives are simple:
|
||||
|
||||
- Write a function that returns the string "Hello, World!".
|
||||
- Run the test suite and make sure that it succeeds.
|
||||
- Submit your solution and check it at the website.
|
||||
|
||||
If everything goes well, you will be ready to fetch your first real exercise.
|
||||
|
||||
## Project Structure
|
||||
|
||||
* `src` contains your solution to the exercise
|
||||
* `spec` contains the tests to run for the exercise
|
||||
|
||||
## Running Tests
|
||||
|
||||
If you're in the right directory (i.e. the one containing `src` and `spec`), you can run the tests for that exercise by running `crystal spec`:
|
||||
|
||||
```bash
|
||||
$ pwd
|
||||
/Users/johndoe/Code/exercism/crystal/hello-world
|
||||
|
||||
$ ls
|
||||
GETTING_STARTED.md README.md spec src
|
||||
|
||||
$ crystal spec
|
||||
```
|
||||
|
||||
This will run all of the test files in the `spec` directory.
|
||||
|
||||
In each test file, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by changing `pending` to `it`.
|
||||
|
||||
## Submitting Your Solution
|
||||
|
||||
Be sure to submit the source file in the `src` directory when submitting your solution:
|
||||
|
||||
```bash
|
||||
$ exercism submit src/hello_world.cr
|
||||
```
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
Follow the setup instructions for Crystal here:
|
||||
|
||||
http://exercism.io/languages/crystal
|
||||
|
||||
More help installing can be found here:
|
||||
|
||||
http://crystal-lang.org/docs/installation/index.html
|
||||
|
||||
## Making the Test Suit Pass
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ crystal spec
|
||||
```
|
||||
|
||||
In each test suite all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by changing `pending` to `it`.
|
||||
|
||||
## Source
|
||||
|
||||
This is an exercise to introduce users to using Exercism [http://en.wikipedia.org/wiki/%22Hello,_world!%22_program](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,8 @@
|
|||
require "spec"
|
||||
require "../src/*"
|
||||
|
||||
describe "HelloWorld" do
|
||||
it "Say Hi!" do
|
||||
HelloWorld.hello.should eq("Hello, World!")
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
# Please implement your solution to hello-world in this file
|
||||
puts "Hello, World!"
|
|
@ -0,0 +1,33 @@
|
|||
*.swp
|
||||
*.*~
|
||||
project.lock.json
|
||||
.DS_Store
|
||||
*.pyc
|
||||
nupkg/
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
msbuild.log
|
||||
msbuild.err
|
||||
msbuild.wrn
|
||||
|
||||
# Visual Studio 2015
|
||||
.vs/
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class AccumulateExtensions
|
||||
{
|
||||
public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
|
||||
{
|
||||
foreach (var elem in collection) yield return func(elem);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
public class AccumulateTest
|
||||
{
|
||||
[Fact]
|
||||
public void Empty_accumulation_produces_empty_accumulation()
|
||||
{
|
||||
Assert.Equal(new int[0], new int[0].Accumulate(x => x * x));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Accumulate_squares()
|
||||
{
|
||||
Assert.Equal(new[] { 1, 4, 9 }, new[] { 1, 2, 3 }.Accumulate(x => x * x));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Accumulate_upcases()
|
||||
{
|
||||
Assert.Equal(new List<string> { "HELLO", "WORLD" }, new List<string> { "hello", "world" }.Accumulate(x => x.ToUpper()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Accumulate_reversed_strings()
|
||||
{
|
||||
Assert.Equal("eht kciuq nworb xof cte".Split(' '), "the quick brown fox etc".Split(' ').Accumulate(Reverse));
|
||||
}
|
||||
|
||||
private static string Reverse(string value)
|
||||
{
|
||||
var array = value.ToCharArray();
|
||||
Array.Reverse(array);
|
||||
return new string(array);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Accumulate_within_accumulate()
|
||||
{
|
||||
var actual = new[] { "a", "b", "c" }.Accumulate(c =>
|
||||
string.Join(" ", new[] { "1", "2", "3" }.Accumulate(d => c + d)));
|
||||
Assert.Equal(new[] { "a1 a2 a3", "b1 b2 b3", "c1 c2 c3" }, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Accumulate_is_lazy()
|
||||
{
|
||||
var counter = 0;
|
||||
var accumulation = new[] { 1, 2, 3 }.Accumulate(x => x * counter++);
|
||||
|
||||
Assert.Equal(0, counter);
|
||||
accumulation.ToList();
|
||||
Assert.Equal(3, counter);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Accumulate_allows_different_return_type()
|
||||
{
|
||||
Assert.Equal(new[] { "1", "2", "3" }, new[] { 1, 2, 3 }.Accumulate(x => x.ToString()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
# Accumulate
|
||||
|
||||
Implement the `accumulate` operation, which, given a collection and an
|
||||
operation to perform on each element of the collection, returns a new
|
||||
collection containing the result of applying that operation to each element of
|
||||
the input collection.
|
||||
|
||||
Given the collection of numbers:
|
||||
|
||||
- 1, 2, 3, 4, 5
|
||||
|
||||
And the operation:
|
||||
|
||||
- square a number (`x => x * x`)
|
||||
|
||||
Your code should be able to produce the collection of squares:
|
||||
|
||||
- 1, 4, 9, 16, 25
|
||||
|
||||
Check out the test suite to see the expected function signature.
|
||||
|
||||
## Restrictions
|
||||
|
||||
Keep your hands off that collect/map/fmap/whatchamacallit functionality
|
||||
provided by your standard library!
|
||||
Solve this one yourself using other basic tools instead.
|
||||
|
||||
## Hints
|
||||
This exercise requires you to write an extension method. For more information, see [this page](https://msdn.microsoft.com/en-us//library/bb383977.aspx).
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
Conversation with James Edward Gray II [https://twitter.com/jeg2](https://twitter.com/jeg2)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
public static class Bob
|
||||
{
|
||||
public static string Response(string statement)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(statement))
|
||||
return "Fine. Be that way!";
|
||||
if (statement.Any(Char.IsLetter) && statement.Where(Char.IsLetter).All(Char.IsUpper))
|
||||
if (statement.Contains("?"))
|
||||
return "Calm down, I know what I'm doing!";
|
||||
else
|
||||
return "Whoa, chill out!";
|
||||
if (statement.Trim().EndsWith("?"))
|
||||
return "Sure.";
|
||||
|
||||
return "Whatever.";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,156 @@
|
|||
// This file was auto-generated based on version 1.1.0 of the canonical data.
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class BobTest
|
||||
{
|
||||
[Fact]
|
||||
public void Stating_something()
|
||||
{
|
||||
Assert.Equal("Whatever.", Bob.Response("Tom-ay-to, tom-aaaah-to."));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Shouting()
|
||||
{
|
||||
Assert.Equal("Whoa, chill out!", Bob.Response("WATCH OUT!"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Shouting_gibberish()
|
||||
{
|
||||
Assert.Equal("Whoa, chill out!", Bob.Response("FCECDFCAAB"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Asking_a_question()
|
||||
{
|
||||
Assert.Equal("Sure.", Bob.Response("Does this cryogenic chamber make me look fat?"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Asking_a_numeric_question()
|
||||
{
|
||||
Assert.Equal("Sure.", Bob.Response("You are, what, like 15?"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Asking_gibberish()
|
||||
{
|
||||
Assert.Equal("Sure.", Bob.Response("fffbbcbeab?"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Talking_forcefully()
|
||||
{
|
||||
Assert.Equal("Whatever.", Bob.Response("Let's go make out behind the gym!"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Using_acronyms_in_regular_speech()
|
||||
{
|
||||
Assert.Equal("Whatever.", Bob.Response("It's OK if you don't want to go to the DMV."));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Forceful_question()
|
||||
{
|
||||
Assert.Equal("Calm down, I know what I'm doing!", Bob.Response("WHAT THE HELL WERE YOU THINKING?"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Shouting_numbers()
|
||||
{
|
||||
Assert.Equal("Whoa, chill out!", Bob.Response("1, 2, 3 GO!"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Only_numbers()
|
||||
{
|
||||
Assert.Equal("Whatever.", Bob.Response("1, 2, 3"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Question_with_only_numbers()
|
||||
{
|
||||
Assert.Equal("Sure.", Bob.Response("4?"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Shouting_with_special_characters()
|
||||
{
|
||||
Assert.Equal("Whoa, chill out!", Bob.Response("ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Shouting_with_no_exclamation_mark()
|
||||
{
|
||||
Assert.Equal("Whoa, chill out!", Bob.Response("I HATE YOU"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Statement_containing_question_mark()
|
||||
{
|
||||
Assert.Equal("Whatever.", Bob.Response("Ending with ? means a question."));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Non_letters_with_question()
|
||||
{
|
||||
Assert.Equal("Sure.", Bob.Response(":) ?"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Prattling_on()
|
||||
{
|
||||
Assert.Equal("Sure.", Bob.Response("Wait! Hang on. Are you going to be OK?"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Silence()
|
||||
{
|
||||
Assert.Equal("Fine. Be that way!", Bob.Response(""));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Prolonged_silence()
|
||||
{
|
||||
Assert.Equal("Fine. Be that way!", Bob.Response(" "));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Alternate_silence()
|
||||
{
|
||||
Assert.Equal("Fine. Be that way!", Bob.Response("\t\t\t\t\t\t\t\t\t\t"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiple_line_question()
|
||||
{
|
||||
Assert.Equal("Whatever.", Bob.Response("\nDoes this cryogenic chamber make me look fat?\nno"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Starting_with_whitespace()
|
||||
{
|
||||
Assert.Equal("Whatever.", Bob.Response(" hmmmmmmm..."));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Ending_with_whitespace()
|
||||
{
|
||||
Assert.Equal("Sure.", Bob.Response("Okay if like my spacebar quite a bit? "));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Other_whitespace()
|
||||
{
|
||||
Assert.Equal("Fine. Be that way!", Bob.Response("\n\r \t"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Non_question_ending_with_whitespace()
|
||||
{
|
||||
Assert.Equal("Whatever.", Bob.Response("This is a statement ending with whitespace "));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
# Bob
|
||||
|
||||
Bob is a lackadaisical teenager. In conversation, his responses are very limited.
|
||||
|
||||
Bob answers 'Sure.' if you ask him a question.
|
||||
|
||||
He answers 'Whoa, chill out!' if you yell at him.
|
||||
|
||||
He answers 'Calm down, I know what I'm doing!' if you yell a question at him.
|
||||
|
||||
He says 'Fine. Be that way!' if you address him without actually saying
|
||||
anything.
|
||||
|
||||
He answers 'Whatever.' to anything else.
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=06](http://pine.fm/LearnToProgram/?Chapter=06)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class School
|
||||
{
|
||||
public void Add(string student, int grade)
|
||||
{
|
||||
throw new NotImplementedException("You need to implement this function.");
|
||||
}
|
||||
|
||||
public IEnumerable<string> Roster()
|
||||
{
|
||||
throw new NotImplementedException("You need to implement this function.");
|
||||
}
|
||||
|
||||
public IEnumerable<string> Grade(int grade)
|
||||
{
|
||||
throw new NotImplementedException("You need to implement this function.");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,85 @@
|
|||
using Xunit;
|
||||
|
||||
public class GradeSchoolTest
|
||||
{
|
||||
[Fact]
|
||||
public void Adding_a_student_adds_them_to_the_sorted_roster()
|
||||
{
|
||||
var school = new School();
|
||||
school.Add("Aimee", 2);
|
||||
|
||||
var actual = school.Roster();
|
||||
|
||||
var expected = new[] { "Aimee" };
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove to run test")]
|
||||
public void Adding_more_students_adds_them_to_the_sorted_roster()
|
||||
{
|
||||
var school = new School();
|
||||
school.Add("Blair", 2);
|
||||
school.Add("James", 2);
|
||||
school.Add("Paul", 2);
|
||||
|
||||
var actual = school.Roster();
|
||||
|
||||
var expected = new[] { "Blair", "James", "Paul" };
|
||||
Assert.Equal(expected, actual );
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove to run test")]
|
||||
public void Adding_students_to_different_grades_adds_them_to_the_same_sorted_roster()
|
||||
{
|
||||
var school = new School();
|
||||
school.Add("Chelsea", 3);
|
||||
school.Add("Logan", 7);
|
||||
|
||||
var actual = school.Roster();
|
||||
|
||||
var expected = new[] { "Chelsea", "Logan"};
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove to run test")]
|
||||
public void Grade_returns_the_students_in_that_grade_in_alphabetical_order()
|
||||
{
|
||||
var school = new School();
|
||||
school.Add("Franklin", 5);
|
||||
school.Add("Bradley", 5);
|
||||
school.Add("Jeff", 1);
|
||||
|
||||
var actual = school.Grade(5);
|
||||
|
||||
var expected = new[] { "Bradley", "Franklin" };
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove to run test")]
|
||||
public void Grade_returns_an_empty_list_if_there_are_no_students_in_that_grade()
|
||||
{
|
||||
var school = new School();
|
||||
|
||||
var actual = school.Grade(1);
|
||||
|
||||
Assert.Empty(actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove to run test")]
|
||||
public void Student_names_with_grades_are_displayed_in_the_same_sorted_roster()
|
||||
{
|
||||
var school = new School();
|
||||
school.Add("Peter", 2);
|
||||
school.Add("Anna", 1);
|
||||
school.Add("Barb", 1);
|
||||
school.Add("Zoe", 2);
|
||||
school.Add("Alex", 2);
|
||||
school.Add("Jim", 3);
|
||||
school.Add("Charlie", 1);
|
||||
|
||||
var actual = school.Roster();
|
||||
|
||||
var expected = new[] { "Anna", "Barb", "Charlie", "Alex", "Peter", "Zoe", "Jim" };
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
# Grade School
|
||||
|
||||
Given students' names along with the grade that they are in, create a roster
|
||||
for the school.
|
||||
|
||||
In the end, you should be able to:
|
||||
|
||||
- Add a student's name to the roster for a grade
|
||||
- "Add Jim to grade 2."
|
||||
- "OK."
|
||||
- Get a list of all students enrolled in a grade
|
||||
- "Which students are in grade 2?"
|
||||
- "We've only got Jim just now."
|
||||
- Get a sorted list of all students in all grades. Grades should sort
|
||||
as 1, 2, 3, etc., and students within a grade should be sorted
|
||||
alphabetically by name.
|
||||
- "Who all is enrolled in school right now?"
|
||||
- "Grade 1: Anna, Barb, and Charlie. Grade 2: Alex, Peter, and Zoe.
|
||||
Grade 3…"
|
||||
|
||||
Note that all our students only have one name. (It's a small town, what
|
||||
do you want?)
|
||||
|
||||
## For bonus points
|
||||
|
||||
Did you get the tests passing and the code clean? If you want to, these
|
||||
are some additional things you could try:
|
||||
|
||||
- If you're working in a language with mutable data structures and your
|
||||
implementation allows outside code to mutate the school's internal DB
|
||||
directly, see if you can prevent this. Feel free to introduce additional
|
||||
tests.
|
||||
|
||||
Then please share your thoughts in a comment on the submission. Did this
|
||||
experiment make the code better? Worse? Did you learn anything from it?
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
A pairing session with Phil Battos at gSchool [http://gschool.it](http://gschool.it)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,6 @@
|
|||
using System;
|
||||
|
||||
public static class HelloWorld
|
||||
{
|
||||
public static string Hello() => "Hello, World!";
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,12 @@
|
|||
// This file was auto-generated based on version 1.0.0 of the canonical data.
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class HelloWorldTest
|
||||
{
|
||||
[Fact]
|
||||
public void Say_hi_()
|
||||
{
|
||||
Assert.Equal("Hello, World!", HelloWorld.Hello());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
# Hello World
|
||||
|
||||
The classical introductory exercise. Just say "Hello, World!".
|
||||
|
||||
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is
|
||||
the traditional first program for beginning programming in a new language
|
||||
or environment.
|
||||
|
||||
The objectives are simple:
|
||||
|
||||
- Write a function that returns the string "Hello, World!".
|
||||
- Run the test suite and make sure that it succeeds.
|
||||
- Submit your solution and check it at the website.
|
||||
|
||||
If everything goes well, you will be ready to fetch your first real exercise.
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
This is an exercise to introduce users to using Exercism [http://en.wikipedia.org/wiki/%22Hello,_world!%22_program](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
public static class Leap
|
||||
{
|
||||
public static bool IsLeapYear(int year)
|
||||
{
|
||||
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,30 @@
|
|||
// This file was auto-generated based on version 1.2.0 of the canonical data.
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class LeapTest
|
||||
{
|
||||
[Fact]
|
||||
public void Year_not_divisible_by_4_is_common_year()
|
||||
{
|
||||
Assert.False(Leap.IsLeapYear(2015));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Year_divisible_by_4_not_divisible_by_100_is_leap_year()
|
||||
{
|
||||
Assert.True(Leap.IsLeapYear(1996));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Year_divisible_by_100_not_divisible_by_400_is_common_year()
|
||||
{
|
||||
Assert.False(Leap.IsLeapYear(2100));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Year_divisible_by_400_is_leap_year()
|
||||
{
|
||||
Assert.True(Leap.IsLeapYear(2000));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
# Leap
|
||||
|
||||
Given a year, report if it is a leap year.
|
||||
|
||||
The tricky thing here is that a leap year in the Gregorian calendar occurs:
|
||||
|
||||
```text
|
||||
on every year that is evenly divisible by 4
|
||||
except every year that is evenly divisible by 100
|
||||
unless the year is also evenly divisible by 400
|
||||
```
|
||||
|
||||
For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap
|
||||
year, but 2000 is.
|
||||
|
||||
If your language provides a method in the standard library that does
|
||||
this look-up, pretend it doesn't exist and implement it yourself.
|
||||
|
||||
## Notes
|
||||
|
||||
Though our exercise adopts some very simple rules, there is more to
|
||||
learn!
|
||||
|
||||
For a delightful, four minute explanation of the whole leap year
|
||||
phenomenon, go watch [this youtube video][video].
|
||||
|
||||
[video]: http://www.youtube.com/watch?v=xX96xng7sAE
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
JavaRanch Cattle Drive, exercise 3 [http://www.javaranch.com/leap.jsp](http://www.javaranch.com/leap.jsp)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public class NucleotideCount
|
||||
{
|
||||
private string _seq;
|
||||
private char[] keys = new[] {'A', 'C', 'G', 'T'};
|
||||
|
||||
public NucleotideCount(string sequence)
|
||||
{
|
||||
_seq = sequence;
|
||||
if (_seq.Any(c => !keys.Contains(c))) throw new InvalidNucleotideException();
|
||||
}
|
||||
|
||||
private int CountOne(char key)
|
||||
=> _seq.Count(c => c == key);
|
||||
|
||||
public IDictionary<char, int> NucleotideCounts
|
||||
{
|
||||
get
|
||||
{
|
||||
var c = new Dictionary<char, int>();
|
||||
foreach (var key in keys)
|
||||
c.Add(key, CountOne(key));
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class InvalidNucleotideException : Exception { }
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,69 @@
|
|||
// This file was auto-generated based on version 1.2.0 of the canonical data.
|
||||
|
||||
using Xunit;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class NucleotideCountTest
|
||||
{
|
||||
[Fact]
|
||||
public void Empty_strand()
|
||||
{
|
||||
var sut = new NucleotideCount("");
|
||||
var expected = new Dictionary<char, int>
|
||||
{
|
||||
['A'] = 0,
|
||||
['C'] = 0,
|
||||
['G'] = 0,
|
||||
['T'] = 0
|
||||
};
|
||||
Assert.Equal(expected, sut.NucleotideCounts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Can_count_one_nucleotide_in_single_character_input()
|
||||
{
|
||||
var sut = new NucleotideCount("G");
|
||||
var expected = new Dictionary<char, int>
|
||||
{
|
||||
['A'] = 0,
|
||||
['C'] = 0,
|
||||
['G'] = 1,
|
||||
['T'] = 0
|
||||
};
|
||||
Assert.Equal(expected, sut.NucleotideCounts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Strand_with_repeated_nucleotide()
|
||||
{
|
||||
var sut = new NucleotideCount("GGGGGGG");
|
||||
var expected = new Dictionary<char, int>
|
||||
{
|
||||
['A'] = 0,
|
||||
['C'] = 0,
|
||||
['G'] = 7,
|
||||
['T'] = 0
|
||||
};
|
||||
Assert.Equal(expected, sut.NucleotideCounts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Strand_with_multiple_nucleotides()
|
||||
{
|
||||
var sut = new NucleotideCount("AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC");
|
||||
var expected = new Dictionary<char, int>
|
||||
{
|
||||
['A'] = 20,
|
||||
['C'] = 12,
|
||||
['G'] = 17,
|
||||
['T'] = 21
|
||||
};
|
||||
Assert.Equal(expected, sut.NucleotideCounts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Strand_with_invalid_nucleotides()
|
||||
{
|
||||
Assert.Throws<InvalidNucleotideException>(() => new NucleotideCount("AGXXACT"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
# Nucleotide Count
|
||||
|
||||
Given a single stranded DNA string, compute how many times each nucleotide occurs in the string.
|
||||
|
||||
The genetic language of every living thing on the planet is DNA.
|
||||
DNA is a large molecule that is built from an extremely long sequence of individual elements called nucleotides.
|
||||
4 types exist in DNA and these differ only slightly and can be represented as the following symbols: 'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' thymine.
|
||||
|
||||
Here is an analogy:
|
||||
- twigs are to birds nests as
|
||||
- nucleotides are to DNA as
|
||||
- legos are to lego houses as
|
||||
- words are to sentences as...
|
||||
|
||||
## Hints
|
||||
This exercise requires the use of a Dictionary. For more information see
|
||||
[this page.](https://msdn.microsoft.com/en-us/library/s4ys34ea(v=vs.110).aspx)
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
The Calculating DNA Nucleotides_problem at Rosalind [http://rosalind.info/problems/dna/](http://rosalind.info/problems/dna/)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,26 @@
|
|||
# Raindrops
|
||||
|
||||
Convert a number to a string, the contents of which depend on the number's factors.
|
||||
|
||||
- If the number has 3 as a factor, output 'Pling'.
|
||||
- If the number has 5 as a factor, output 'Plang'.
|
||||
- If the number has 7 as a factor, output 'Plong'.
|
||||
- If the number does not have 3, 5, or 7 as a factor,
|
||||
just pass the number's digits straight through.
|
||||
|
||||
## Examples
|
||||
|
||||
- 28's factors are 1, 2, 4, **7**, 14, 28.
|
||||
- In raindrop-speak, this would be a simple "Plong".
|
||||
- 30's factors are 1, 2, **3**, **5**, 6, 10, 15, 30.
|
||||
- In raindrop-speak, this would be a "PlingPlang".
|
||||
- 34 has four factors: 1, 2, 17, and 34.
|
||||
- In raindrop-speak, this would be "34".
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
A variation on a famous interview question intended to weed out potential candidates. [http://jumpstartlab.com](http://jumpstartlab.com)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
public static class Raindrops
|
||||
{
|
||||
public static string Convert(int number)
|
||||
{
|
||||
var s = new StringBuilder();
|
||||
if (number % 3 == 0)
|
||||
s.Append("Pling");
|
||||
if (number % 5 == 0)
|
||||
s.Append("Plang");
|
||||
if (number % 7 == 0)
|
||||
s.Append("Plong");
|
||||
if (new [] {3, 5, 7}.All(n => number % n != 0))
|
||||
s.Append(number);
|
||||
return s.ToString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,114 @@
|
|||
// This file was auto-generated based on version 1.0.0 of the canonical data.
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class RaindropsTest
|
||||
{
|
||||
[Fact]
|
||||
public void The_sound_for_1_is_1()
|
||||
{
|
||||
Assert.Equal("1", Raindrops.Convert(1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_3_is_pling()
|
||||
{
|
||||
Assert.Equal("Pling", Raindrops.Convert(3));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_5_is_plang()
|
||||
{
|
||||
Assert.Equal("Plang", Raindrops.Convert(5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_7_is_plong()
|
||||
{
|
||||
Assert.Equal("Plong", Raindrops.Convert(7));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_6_is_pling_as_it_has_a_factor_3()
|
||||
{
|
||||
Assert.Equal("Pling", Raindrops.Convert(6));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Number_2_to_the_power_3_does_not_make_a_raindrop_sound_as_3_is_the_exponent_not_the_base()
|
||||
{
|
||||
Assert.Equal("8", Raindrops.Convert(8));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_9_is_pling_as_it_has_a_factor_3()
|
||||
{
|
||||
Assert.Equal("Pling", Raindrops.Convert(9));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_10_is_plang_as_it_has_a_factor_5()
|
||||
{
|
||||
Assert.Equal("Plang", Raindrops.Convert(10));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_14_is_plong_as_it_has_a_factor_of_7()
|
||||
{
|
||||
Assert.Equal("Plong", Raindrops.Convert(14));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_15_is_plingplang_as_it_has_factors_3_and_5()
|
||||
{
|
||||
Assert.Equal("PlingPlang", Raindrops.Convert(15));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_21_is_plingplong_as_it_has_factors_3_and_7()
|
||||
{
|
||||
Assert.Equal("PlingPlong", Raindrops.Convert(21));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_25_is_plang_as_it_has_a_factor_5()
|
||||
{
|
||||
Assert.Equal("Plang", Raindrops.Convert(25));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_27_is_pling_as_it_has_a_factor_3()
|
||||
{
|
||||
Assert.Equal("Pling", Raindrops.Convert(27));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_35_is_plangplong_as_it_has_factors_5_and_7()
|
||||
{
|
||||
Assert.Equal("PlangPlong", Raindrops.Convert(35));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_49_is_plong_as_it_has_a_factor_7()
|
||||
{
|
||||
Assert.Equal("Plong", Raindrops.Convert(49));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_52_is_52()
|
||||
{
|
||||
Assert.Equal("52", Raindrops.Convert(52));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_105_is_plingplangplong_as_it_has_factors_3_5_and_7()
|
||||
{
|
||||
Assert.Equal("PlingPlangPlong", Raindrops.Convert(105));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_sound_for_3125_is_plang_as_it_has_a_factor_5()
|
||||
{
|
||||
Assert.Equal("Plang", Raindrops.Convert(3125));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
# Reverse String
|
||||
|
||||
Reverse a string
|
||||
|
||||
For example:
|
||||
input: "cool"
|
||||
output: "looc"
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
Introductory challenge to reverse an input string [https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb](https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,7 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
public static class ReverseString
|
||||
{
|
||||
public static string Reverse(string input)=> string.Concat(input.ToCharArray().Reverse());
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
// This file was auto-generated based on version 1.0.1 of the canonical data.
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class ReverseStringTest
|
||||
{
|
||||
[Fact]
|
||||
public void An_empty_string()
|
||||
{
|
||||
Assert.Equal("", ReverseString.Reverse(""));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_word()
|
||||
{
|
||||
Assert.Equal("tobor", ReverseString.Reverse("robot"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_capitalized_word()
|
||||
{
|
||||
Assert.Equal("nemaR", ReverseString.Reverse("Ramen"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_sentence_with_punctuation()
|
||||
{
|
||||
Assert.Equal("!yrgnuh m'I", ReverseString.Reverse("I'm hungry!"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_palindrome()
|
||||
{
|
||||
Assert.Equal("racecar", ReverseString.Reverse("racecar"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
# Sum Of Multiples
|
||||
|
||||
Given a number, find the sum of all the unique multiples of particular numbers up to
|
||||
but not including that number.
|
||||
|
||||
If we list all the natural numbers below 20 that are multiples of 3 or 5,
|
||||
we get 3, 5, 6, 9, 10, 12, 15, and 18.
|
||||
|
||||
The sum of these multiples is 78.
|
||||
|
||||
## Hints
|
||||
This exercise requires you to process a collection of data. You can simplify your code by using LINQ (Language Integrated Query).
|
||||
For more information, see [this page](https://docs.microsoft.com/en-us/dotnet/articles/standard/using-linq).
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
A variation on Problem 1 at Project Euler [http://projecteuler.net/problem=1](http://projecteuler.net/problem=1)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public static class SumOfMultiples
|
||||
{
|
||||
public static int Sum(IEnumerable<int> multiples, int max)
|
||||
=> Enumerable.Range(0, max).Where(c => multiples.Any(m => c % m == 0)).Sum();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,84 @@
|
|||
// This file was auto-generated based on version 1.1.0 of the canonical data.
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class SumOfMultiplesTest
|
||||
{
|
||||
[Fact]
|
||||
public void Multiples_of_3_or_5_up_to_1()
|
||||
{
|
||||
Assert.Equal(0, SumOfMultiples.Sum(new[] { 3, 5 }, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_3_or_5_up_to_4()
|
||||
{
|
||||
Assert.Equal(3, SumOfMultiples.Sum(new[] { 3, 5 }, 4));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_3_up_to_7()
|
||||
{
|
||||
Assert.Equal(9, SumOfMultiples.Sum(new[] { 3 }, 7));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_3_or_5_up_to_10()
|
||||
{
|
||||
Assert.Equal(23, SumOfMultiples.Sum(new[] { 3, 5 }, 10));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_3_or_5_up_to_100()
|
||||
{
|
||||
Assert.Equal(2318, SumOfMultiples.Sum(new[] { 3, 5 }, 100));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_3_or_5_up_to_1000()
|
||||
{
|
||||
Assert.Equal(233168, SumOfMultiples.Sum(new[] { 3, 5 }, 1000));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_7_13_or_17_up_to_20()
|
||||
{
|
||||
Assert.Equal(51, SumOfMultiples.Sum(new[] { 7, 13, 17 }, 20));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_4_or_6_up_to_15()
|
||||
{
|
||||
Assert.Equal(30, SumOfMultiples.Sum(new[] { 4, 6 }, 15));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_5_6_or_8_up_to_150()
|
||||
{
|
||||
Assert.Equal(4419, SumOfMultiples.Sum(new[] { 5, 6, 8 }, 150));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_5_or_25_up_to_51()
|
||||
{
|
||||
Assert.Equal(275, SumOfMultiples.Sum(new[] { 5, 25 }, 51));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_43_or_47_up_to_10000()
|
||||
{
|
||||
Assert.Equal(2203160, SumOfMultiples.Sum(new[] { 43, 47 }, 10000));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_1_up_to_100()
|
||||
{
|
||||
Assert.Equal(4950, SumOfMultiples.Sum(new[] { 1 }, 100));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Multiples_of_an_empty_list_up_to_10000()
|
||||
{
|
||||
Assert.Equal(0, SumOfMultiples.Sum(new int[0], 10000));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
# Two Fer
|
||||
|
||||
`Two-fer` or `2-fer` is short for two for one. One for you and one for me.
|
||||
|
||||
```text
|
||||
"One for X, one for me."
|
||||
```
|
||||
|
||||
When X is a name or "you".
|
||||
|
||||
If the given name is "Alice", the result should be "One for Alice, one for me."
|
||||
If no name is given, the result should be "One for you, one for me."
|
||||
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
[https://en.wikipedia.org/wiki/Two-fer](https://en.wikipedia.org/wiki/Two-fer)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,7 @@
|
|||
using System;
|
||||
|
||||
public static class TwoFer
|
||||
{
|
||||
public static string Name(string input = null)
|
||||
=> $"One for {(input ?? "you")}, one for me.";
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Example.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,24 @@
|
|||
// This file was auto-generated based on version 1.1.0 of the canonical data.
|
||||
|
||||
using Xunit;
|
||||
|
||||
public class TwoFerTest
|
||||
{
|
||||
[Fact]
|
||||
public void No_name_given()
|
||||
{
|
||||
Assert.Equal("One for you, one for me.", TwoFer.Name());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_name_given()
|
||||
{
|
||||
Assert.Equal("One for Alice, one for me.", TwoFer.Name("Alice"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Another_name_given()
|
||||
{
|
||||
Assert.Equal("One for Bob, one for me.", TwoFer.Name("Bob"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
# Hello World
|
||||
|
||||
The classical introductory exercise. Just say "Hello, World!".
|
||||
|
||||
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is
|
||||
the traditional first program for beginning programming in a new language
|
||||
or environment.
|
||||
|
||||
The objectives are simple:
|
||||
|
||||
- Write a function that returns the string "Hello, World!".
|
||||
- Run the test suite and make sure that it succeeds.
|
||||
- Submit your solution and check it at the website.
|
||||
|
||||
If everything goes well, you will be ready to fetch your first real exercise.
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir hello_world_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Source
|
||||
|
||||
This is an exercise to introduce users to using Exercism [http://en.wikipedia.org/wiki/%22Hello,_world!%22_program](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,9 @@
|
|||
defmodule HelloWorld do
|
||||
@doc """
|
||||
Simply returns "Hello, World!"
|
||||
"""
|
||||
@spec hello :: String.t()
|
||||
def hello do
|
||||
"Hello, World!"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("hello_world.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(trace: true)
|
||||
|
||||
defmodule HelloWorldTest do
|
||||
use ExUnit.Case
|
||||
|
||||
test "says 'Hello, World!'" do
|
||||
assert HelloWorld.hello() == "Hello, World!"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,54 @@
|
|||
# Nucleotide Count
|
||||
|
||||
Given a single stranded DNA string, compute how many times each nucleotide occurs in the string.
|
||||
|
||||
The genetic language of every living thing on the planet is DNA.
|
||||
DNA is a large molecule that is built from an extremely long sequence of individual elements called nucleotides.
|
||||
4 types exist in DNA and these differ only slightly and can be represented as the following symbols: 'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' thymine.
|
||||
|
||||
Here is an analogy:
|
||||
- twigs are to birds nests as
|
||||
- nucleotides are to DNA as
|
||||
- legos are to lego houses as
|
||||
- words are to sentences as...
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir nucleotide_count_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Source
|
||||
|
||||
The Calculating DNA Nucleotides_problem at Rosalind [http://rosalind.info/problems/dna/](http://rosalind.info/problems/dna/)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,32 @@
|
|||
defmodule NucleotideCount do
|
||||
@nucleotides [?A, ?C, ?G, ?T]
|
||||
|
||||
@doc """
|
||||
Counts individual nucleotides in a NucleotideCount strand.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> NucleotideCount.count('AATAA', ?A)
|
||||
4
|
||||
|
||||
iex> NucleotideCount.count('AATAA', ?T)
|
||||
1
|
||||
"""
|
||||
@spec count([char], char) :: non_neg_integer
|
||||
def count(strand, nucleotide) do
|
||||
Enum.count(strand, &(&1 == nucleotide))
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns a summary of counts by nucleotide.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> NucleotideCount.histogram('AATAA')
|
||||
%{?A => 4, ?T => 1, ?C => 0, ?G => 0}
|
||||
"""
|
||||
@spec histogram([char]) :: map
|
||||
def histogram(strand) do
|
||||
Map.new(@nucleotides, &{&1, count(strand, &1)})
|
||||
end
|
||||
end
|
|
@ -0,0 +1,44 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("nucleotide_count.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(exclude: :pending, trace: true)
|
||||
|
||||
defmodule NucleotideCountTest do
|
||||
use ExUnit.Case
|
||||
|
||||
# @tag :pending
|
||||
test "empty dna string has no adenine" do
|
||||
assert NucleotideCount.count('', ?A) == 0
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "repetitive cytosine gets counted" do
|
||||
assert NucleotideCount.count('CCCCC', ?C) == 5
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "counts only thymine" do
|
||||
assert NucleotideCount.count('GGGGGTAACCCGG', ?T) == 1
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "empty dna string has no nucleotides" do
|
||||
expected = %{?A => 0, ?T => 0, ?C => 0, ?G => 0}
|
||||
assert NucleotideCount.histogram('') == expected
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "repetitive sequence has only guanine" do
|
||||
expected = %{?A => 0, ?T => 0, ?C => 0, ?G => 8}
|
||||
assert NucleotideCount.histogram('GGGGGGGG') == expected
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "counts all nucleotides" do
|
||||
s = 'AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC'
|
||||
expected = %{?A => 20, ?T => 21, ?C => 12, ?G => 17}
|
||||
assert NucleotideCount.histogram(s) == expected
|
||||
end
|
||||
end
|
|
@ -0,0 +1,83 @@
|
|||
# Protein Translation
|
||||
|
||||
Translate RNA sequences into proteins.
|
||||
|
||||
RNA can be broken into three nucleotide sequences called codons, and then translated to a polypeptide like so:
|
||||
|
||||
RNA: `"AUGUUUUCU"` => translates to
|
||||
|
||||
Codons: `"AUG", "UUU", "UCU"`
|
||||
=> which become a polypeptide with the following sequence =>
|
||||
|
||||
Protein: `"Methionine", "Phenylalanine", "Serine"`
|
||||
|
||||
There are 64 codons which in turn correspond to 20 amino acids; however, all of the codon sequences and resulting amino acids are not important in this exercise. If it works for one codon, the program should work for all of them.
|
||||
However, feel free to expand the list in the test suite to include them all.
|
||||
|
||||
There are also three terminating codons (also known as 'STOP' codons); if any of these codons are encountered (by the ribosome), all translation ends and the protein is terminated.
|
||||
|
||||
All subsequent codons after are ignored, like this:
|
||||
|
||||
RNA: `"AUGUUUUCUUAAAUG"` =>
|
||||
|
||||
Codons: `"AUG", "UUU", "UCU", "UAG", "AUG"` =>
|
||||
|
||||
Protein: `"Methionine", "Phenylalanine", "Serine"`
|
||||
|
||||
Note the stop codon terminates the translation and the final methionine is not translated into the protein sequence.
|
||||
|
||||
Below are the codons and resulting Amino Acids needed for the exercise.
|
||||
|
||||
Codon | Protein
|
||||
:--- | :---
|
||||
AUG | Methionine
|
||||
UUU, UUC | Phenylalanine
|
||||
UUA, UUG | Leucine
|
||||
UCU, UCC, UCA, UCG | Serine
|
||||
UAU, UAC | Tyrosine
|
||||
UGU, UGC | Cysteine
|
||||
UGG | Tryptophan
|
||||
UAA, UAG, UGA | STOP
|
||||
|
||||
Learn more about [protein translation on Wikipedia](http://en.wikipedia.org/wiki/Translation_(biology))
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir protein_translation_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Source
|
||||
|
||||
Tyler Long
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,33 @@
|
|||
defmodule ProteinTranslation do
|
||||
@doc """
|
||||
Given an RNA string, return a list of proteins specified by codons, in order.
|
||||
"""
|
||||
@spec of_rna(String.t()) :: {atom, list(String.t())}
|
||||
def of_rna(rna) do
|
||||
end
|
||||
|
||||
@doc """
|
||||
Given a codon, return the corresponding protein
|
||||
|
||||
UGU -> Cysteine
|
||||
UGC -> Cysteine
|
||||
UUA -> Leucine
|
||||
UUG -> Leucine
|
||||
AUG -> Methionine
|
||||
UUU -> Phenylalanine
|
||||
UUC -> Phenylalanine
|
||||
UCU -> Serine
|
||||
UCC -> Serine
|
||||
UCA -> Serine
|
||||
UCG -> Serine
|
||||
UGG -> Tryptophan
|
||||
UAU -> Tyrosine
|
||||
UAC -> Tyrosine
|
||||
UAA -> STOP
|
||||
UAG -> STOP
|
||||
UGA -> STOP
|
||||
"""
|
||||
@spec of_codon(String.t()) :: {atom, String.t()}
|
||||
def of_codon(codon) do
|
||||
end
|
||||
end
|
|
@ -0,0 +1,92 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("protein_translation.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(exclude: :pending, trace: true)
|
||||
|
||||
defmodule ProteinTranslationTest do
|
||||
use ExUnit.Case
|
||||
|
||||
# @tag :pending
|
||||
test "AUG translates to methionine" do
|
||||
assert ProteinTranslation.of_codon("AUG") == {:ok, "Methionine"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "identifies Phenylalanine codons" do
|
||||
assert ProteinTranslation.of_codon("UUU") == {:ok, "Phenylalanine"}
|
||||
assert ProteinTranslation.of_codon("UUC") == {:ok, "Phenylalanine"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "identifies Leucine codons" do
|
||||
assert ProteinTranslation.of_codon("UUA") == {:ok, "Leucine"}
|
||||
assert ProteinTranslation.of_codon("UUG") == {:ok, "Leucine"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "identifies Serine codons" do
|
||||
assert ProteinTranslation.of_codon("UCU") == {:ok, "Serine"}
|
||||
assert ProteinTranslation.of_codon("UCC") == {:ok, "Serine"}
|
||||
assert ProteinTranslation.of_codon("UCA") == {:ok, "Serine"}
|
||||
assert ProteinTranslation.of_codon("UCG") == {:ok, "Serine"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "identifies Tyrosine codons" do
|
||||
assert ProteinTranslation.of_codon("UAU") == {:ok, "Tyrosine"}
|
||||
assert ProteinTranslation.of_codon("UAC") == {:ok, "Tyrosine"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "identifies Cysteine codons" do
|
||||
assert ProteinTranslation.of_codon("UGU") == {:ok, "Cysteine"}
|
||||
assert ProteinTranslation.of_codon("UGC") == {:ok, "Cysteine"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "identifies Tryptophan codons" do
|
||||
assert ProteinTranslation.of_codon("UGG") == {:ok, "Tryptophan"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "identifies stop codons" do
|
||||
assert ProteinTranslation.of_codon("UAA") == {:ok, "STOP"}
|
||||
assert ProteinTranslation.of_codon("UAG") == {:ok, "STOP"}
|
||||
assert ProteinTranslation.of_codon("UGA") == {:ok, "STOP"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "translates rna strand into correct protein" do
|
||||
strand = "AUGUUUUGG"
|
||||
assert ProteinTranslation.of_rna(strand) == {:ok, ~w(Methionine Phenylalanine Tryptophan)}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "stops translation if stop codon present" do
|
||||
strand = "AUGUUUUAA"
|
||||
assert ProteinTranslation.of_rna(strand) == {:ok, ~w(Methionine Phenylalanine)}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "stops translation of longer strand" do
|
||||
strand = "UGGUGUUAUUAAUGGUUU"
|
||||
assert ProteinTranslation.of_rna(strand) == {:ok, ~w(Tryptophan Cysteine Tyrosine)}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "invalid RNA" do
|
||||
assert ProteinTranslation.of_rna("CARROT") == {:error, "invalid RNA"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "invalid codon at end of RNA" do
|
||||
assert ProteinTranslation.of_rna("UUUROT") == {:error, "invalid RNA"}
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "invalid codon" do
|
||||
assert ProteinTranslation.of_codon("INVALID") == {:error, "invalid codon"}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,72 @@
|
|||
# Rotational Cipher
|
||||
|
||||
Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.
|
||||
|
||||
The Caesar cipher is a simple shift cipher that relies on
|
||||
transposing all the letters in the alphabet using an integer key
|
||||
between `0` and `26`. Using a key of `0` or `26` will always yield
|
||||
the same output due to modular arithmetic. The letter is shifted
|
||||
for as many values as the value of the key.
|
||||
|
||||
The general notation for rotational ciphers is `ROT + <key>`.
|
||||
The most commonly used rotational cipher is `ROT13`.
|
||||
|
||||
A `ROT13` on the Latin alphabet would be as follows:
|
||||
|
||||
```text
|
||||
Plain: abcdefghijklmnopqrstuvwxyz
|
||||
Cipher: nopqrstuvwxyzabcdefghijklm
|
||||
```
|
||||
|
||||
It is stronger than the Atbash cipher because it has 27 possible keys, and 25 usable keys.
|
||||
|
||||
Ciphertext is written out in the same formatting as the input including spaces and punctuation.
|
||||
|
||||
## Examples
|
||||
|
||||
- ROT5 `omg` gives `trl`
|
||||
- ROT0 `c` gives `c`
|
||||
- ROT26 `Cool` gives `Cool`
|
||||
- ROT13 `The quick brown fox jumps over the lazy dog.` gives `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.`
|
||||
- ROT13 `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` gives `The quick brown fox jumps over the lazy dog.`
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir rotational_cipher_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Source
|
||||
|
||||
Wikipedia [https://en.wikipedia.org/wiki/Caesar_cipher](https://en.wikipedia.org/wiki/Caesar_cipher)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,19 @@
|
|||
defmodule RotationalCipher do
|
||||
@doc """
|
||||
Given a plaintext and amount to shift by, return a rotated string.
|
||||
|
||||
Example:
|
||||
iex> RotationalCipher.rotate("Attack at dawn", 13)
|
||||
"Nggnpx ng qnja"
|
||||
"""
|
||||
@spec rotate(text :: String.t(), shift :: integer) :: String.t()
|
||||
def rotate(text, shift) do
|
||||
for <<c <- text>>, into: "" do
|
||||
if Regex.match?(~r/[a-zA-Z]/, <<c>>) do
|
||||
<<rem(c + shift, 26) + ?z>>
|
||||
else
|
||||
<<c>>
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,82 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("rotational_cipher.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(exclude: :pending, trace: true)
|
||||
|
||||
defmodule RotationalCipherTest do
|
||||
use ExUnit.Case
|
||||
|
||||
# @tag :pending
|
||||
test "rotate a by 1" do
|
||||
plaintext = "a"
|
||||
shift = 1
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "b"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate a by 26, same output as input" do
|
||||
plaintext = "a"
|
||||
shift = 26
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "a"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate a by 0, same output as input" do
|
||||
plaintext = "a"
|
||||
shift = 0
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "a"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate m by 13" do
|
||||
plaintext = "m"
|
||||
shift = 13
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "z"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate n by 13 with wrap around alphabet" do
|
||||
plaintext = "n"
|
||||
shift = 13
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "a"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate capital letters" do
|
||||
plaintext = "OMG"
|
||||
shift = 5
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "TRL"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate spaces" do
|
||||
plaintext = "O M G"
|
||||
shift = 5
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "T R L"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate numbers" do
|
||||
plaintext = "Testing 1 2 3 testing"
|
||||
shift = 4
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "Xiwxmrk 1 2 3 xiwxmrk"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate punctuation" do
|
||||
plaintext = "Let's eat, Grandma!"
|
||||
shift = 21
|
||||
assert RotationalCipher.rotate(plaintext, shift) == "Gzo'n zvo, Bmviyhv!"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "rotate all letters" do
|
||||
plaintext = "The quick brown fox jumps over the lazy dog."
|
||||
shift = 13
|
||||
|
||||
assert RotationalCipher.rotate(plaintext, shift) ==
|
||||
"Gur dhvpx oebja sbk whzcf bire gur ynml qbt."
|
||||
end
|
||||
end
|
|
@ -0,0 +1,92 @@
|
|||
# Secret Handshake
|
||||
|
||||
> There are 10 types of people in the world: Those who understand
|
||||
> binary, and those who don't.
|
||||
|
||||
You and your fellow cohort of those in the "know" when it comes to
|
||||
binary decide to come up with a secret "handshake".
|
||||
|
||||
```text
|
||||
1 = wink
|
||||
10 = double blink
|
||||
100 = close your eyes
|
||||
1000 = jump
|
||||
|
||||
|
||||
10000 = Reverse the order of the operations in the secret handshake.
|
||||
```
|
||||
|
||||
Given a decimal number, convert it to the appropriate sequence of events for a secret handshake.
|
||||
|
||||
Here's a couple of examples:
|
||||
|
||||
Given the input 3, the function would return the array
|
||||
["wink", "double blink"] because 3 is 11 in binary.
|
||||
|
||||
Given the input 19, the function would return the array
|
||||
["double blink", "wink"] because 19 is 10011 in binary.
|
||||
Notice that the addition of 16 (10000 in binary)
|
||||
has caused the array to be reversed.
|
||||
|
||||
use Bitwise (or div/rem)
|
||||
|
||||
If you use Bitwise, an easy way to see if a particular bit is set is to compare
|
||||
the binary AND (`&&&`) of a set of bits with the particular bit pattern you
|
||||
want to check, and determine if the result is the same as the pattern you're
|
||||
checking.
|
||||
|
||||
Example:
|
||||
|
||||
Flags: 0b11011
|
||||
Check: 0b11010
|
||||
|
||||
Flags &&& Check: 0b11010 (All checked bits are set)
|
||||
|
||||
Another:
|
||||
|
||||
Flags: 0b11011
|
||||
Check: 0b10110
|
||||
|
||||
Flags &&& Check: 0b10010 (Third bit not set)
|
||||
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir secret_handshake_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Source
|
||||
|
||||
Bert, in Mary Poppins [http://www.imdb.com/title/tt0058331/quotes/qt0437047](http://www.imdb.com/title/tt0058331/quotes/qt0437047)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,27 @@
|
|||
defmodule SecretHandshake do
|
||||
import Bitwise
|
||||
|
||||
@doc """
|
||||
Determine the actions of a secret handshake based on the binary
|
||||
representation of the given `code`.
|
||||
|
||||
If the following bits are set, include the corresponding action in your list
|
||||
of commands, in order from lowest to highest.
|
||||
|
||||
1 = wink
|
||||
10 = double blink
|
||||
100 = close your eyes
|
||||
1000 = jump
|
||||
|
||||
10000 = Reverse the order of the operations in the secret handshake
|
||||
"""
|
||||
@spec commands(code :: integer) :: list(String.t())
|
||||
def commands(code) do
|
||||
[]
|
||||
|> (fn acc -> if (code &&& 1) == 1, do: ["wink" | acc], else: acc end).()
|
||||
|> (fn acc -> if (code &&& 2) == 2, do: ["double blink" | acc], else: acc end).()
|
||||
|> (fn acc -> if (code &&& 4) == 4, do: ["close your eyes" | acc], else: acc end).()
|
||||
|> (fn acc -> if (code &&& 8) == 8, do: ["jump" | acc], else: acc end).()
|
||||
|> (fn acc -> if (code &&& 16) == 16, do: acc, else: Enum.reverse(acc) end).()
|
||||
end
|
||||
end
|
|
@ -0,0 +1,72 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("secret_handshake.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(trace: true, exclude: :pending)
|
||||
|
||||
defmodule SecretHandshakeTest do
|
||||
use ExUnit.Case
|
||||
|
||||
describe "Create a handshake for a number" do
|
||||
# @tag :pending
|
||||
test "wink for 1" do
|
||||
assert SecretHandshake.commands(1) == ["wink"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "double blink for 10" do
|
||||
assert SecretHandshake.commands(2) == ["double blink"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "close your eyes for 100" do
|
||||
assert SecretHandshake.commands(4) == ["close your eyes"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "jump for 1000" do
|
||||
assert SecretHandshake.commands(8) == ["jump"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "combine two actions" do
|
||||
assert SecretHandshake.commands(3) == ["wink", "double blink"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "reverse two actions" do
|
||||
assert SecretHandshake.commands(19) == ["double blink", "wink"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "reversing one action gives the same action" do
|
||||
assert SecretHandshake.commands(24) == ["jump"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "reversing no actions still gives no actions" do
|
||||
assert SecretHandshake.commands(16) == []
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "all possible actions" do
|
||||
assert SecretHandshake.commands(15) == ["wink", "double blink", "close your eyes", "jump"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "reverse all possible actions" do
|
||||
assert SecretHandshake.commands(31) == ["jump", "close your eyes", "double blink", "wink"]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "do nothing for zero" do
|
||||
assert SecretHandshake.commands(0) == []
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "do nothing if lower 5 bits not set" do
|
||||
assert SecretHandshake.commands(32) == []
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,78 @@
|
|||
# Strain
|
||||
|
||||
Implement the `keep` and `discard` operation on collections. Given a collection
|
||||
and a predicate on the collection's elements, `keep` returns a new collection
|
||||
containing those elements where the predicate is true, while `discard` returns
|
||||
a new collection containing those elements where the predicate is false.
|
||||
|
||||
For example, given the collection of numbers:
|
||||
|
||||
- 1, 2, 3, 4, 5
|
||||
|
||||
And the predicate:
|
||||
|
||||
- is the number even?
|
||||
|
||||
Then your keep operation should produce:
|
||||
|
||||
- 2, 4
|
||||
|
||||
While your discard operation should produce:
|
||||
|
||||
- 1, 3, 5
|
||||
|
||||
Note that the union of keep and discard is all the elements.
|
||||
|
||||
The functions may be called `keep` and `discard`, or they may need different
|
||||
names in order to not clash with existing functions or concepts in your
|
||||
language.
|
||||
|
||||
## Restrictions
|
||||
|
||||
Keep your hands off that filter/reject/whatchamacallit functionality
|
||||
provided by your standard library! Solve this one yourself using other
|
||||
basic tools instead.
|
||||
|
||||
`apply` will let you pass arguments to a function, as will `fun.(args)`
|
||||
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir strain_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Source
|
||||
|
||||
Conversation with James Edward Gray II [https://twitter.com/jeg2](https://twitter.com/jeg2)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,27 @@
|
|||
defmodule Strain do
|
||||
@doc """
|
||||
Given a `list` of items and a function `fun`, return the list of items where
|
||||
`fun` returns true.
|
||||
|
||||
Do not use `Enum.filter`.
|
||||
"""
|
||||
@spec keep(list :: list(any), fun :: (any -> boolean)) :: list(any)
|
||||
def keep(list, fun) do
|
||||
for item <- list, fun.(item), into: [] do
|
||||
item
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Given a `list` of items and a function `fun`, return the list of items where
|
||||
`fun` returns false.
|
||||
|
||||
Do not use `Enum.reject`.
|
||||
"""
|
||||
@spec discard(list :: list(any), fun :: (any -> boolean)) :: list(any)
|
||||
def discard(list, fun) do
|
||||
for item <- list, not fun.(item), into: [] do
|
||||
item
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,101 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("strain.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(trace: true, exclude: :pending)
|
||||
|
||||
defmodule StrainTest do
|
||||
use ExUnit.Case
|
||||
|
||||
defp is_odd?(n), do: rem(n, 2) == 1
|
||||
defp is_even?(n), do: rem(n, 2) == 0
|
||||
defp noop(_), do: true
|
||||
|
||||
# @tag :pending
|
||||
test "empty keep" do
|
||||
assert Strain.keep([], &noop/1) == []
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "keep everything" do
|
||||
assert Strain.keep([1, 2, 3], fn e -> e < 10 end) == [1, 2, 3]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "keep first and last" do
|
||||
assert Strain.keep([1, 2, 3], &is_odd?/1) == [1, 3]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "keep neither first nor last" do
|
||||
assert Strain.keep([1, 2, 3, 4, 5], &is_even?/1) == [2, 4]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "keep strings" do
|
||||
words = ~w(apple zebra banana zombies cherimoya zelot)
|
||||
assert Strain.keep(words, &String.starts_with?(&1, "z")) == ~w(zebra zombies zelot)
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "keep arrays" do
|
||||
rows = [
|
||||
[1, 2, 3],
|
||||
[5, 5, 5],
|
||||
[5, 1, 2],
|
||||
[2, 1, 2],
|
||||
[1, 5, 2],
|
||||
[2, 2, 1],
|
||||
[1, 2, 5]
|
||||
]
|
||||
|
||||
assert Strain.keep(rows, fn row -> 5 in row end) == [
|
||||
[5, 5, 5],
|
||||
[5, 1, 2],
|
||||
[1, 5, 2],
|
||||
[1, 2, 5]
|
||||
]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "empty discard" do
|
||||
assert Strain.discard([], &noop/1) == []
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "discard nothing" do
|
||||
assert Strain.discard([1, 2, 3], fn e -> e > 10 end) == [1, 2, 3]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "discard first and last" do
|
||||
assert Strain.discard([1, 2, 3], &is_odd?/1) == [2]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "discard neither first nor last" do
|
||||
assert Strain.discard([1, 2, 3, 4, 5], &is_even?/1) == [1, 3, 5]
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "discard strings" do
|
||||
words = ~w(apple zebra banana zombies cherimoya zelot)
|
||||
assert Strain.discard(words, &String.starts_with?(&1, "z")) == ~w(apple banana cherimoya)
|
||||
end
|
||||
|
||||
# @tag :pending
|
||||
test "discard arrays" do
|
||||
rows = [
|
||||
[1, 2, 3],
|
||||
[5, 5, 5],
|
||||
[5, 1, 2],
|
||||
[2, 1, 2],
|
||||
[1, 5, 2],
|
||||
[2, 2, 1],
|
||||
[1, 2, 5]
|
||||
]
|
||||
|
||||
assert Strain.discard(rows, fn row -> 5 in row end) == [[1, 2, 3], [2, 1, 2], [2, 2, 1]]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,454 @@
|
|||
# Originally created by https://www.gitignore.io/api/windows,linux,visualstudio,visualstudiocode,osx,xamarinstudio,f#,monodevelop,vim,emacs,node,bower on 2016-03-19
|
||||
# Last updated: 2016-03-20
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
|
||||
### VisualStudio ###
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Bb]uild/
|
||||
_[Bb]uild/
|
||||
[Dd]eploy/
|
||||
_[Dd]eploy/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
TestResults.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
|
||||
|
||||
|
||||
### OSX ###
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
### XamarinStudio ###
|
||||
bin/
|
||||
obj/
|
||||
*.userprefs
|
||||
|
||||
|
||||
### F# ###
|
||||
lib/debug
|
||||
lib/release
|
||||
Debug
|
||||
*.suo
|
||||
*.user
|
||||
obj
|
||||
bin
|
||||
*.exe
|
||||
|
||||
|
||||
### MonoDevelop ###
|
||||
#User Specific
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
|
||||
#Mono Project Files
|
||||
*.pidb
|
||||
*.resources
|
||||
test-results/
|
||||
|
||||
|
||||
### Vim ###
|
||||
# swap
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
# session
|
||||
Session.vim
|
||||
# temporary
|
||||
.netrwhist
|
||||
*~
|
||||
# auto-generated tag files
|
||||
tags
|
||||
|
||||
|
||||
### Emacs ###
|
||||
# -*- mode: gitignore; -*-
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
*.elc
|
||||
auto-save-list
|
||||
tramp
|
||||
.\#*
|
||||
|
||||
# Org-mode
|
||||
.org-id-locations
|
||||
*_archive
|
||||
|
||||
# flymake-mode
|
||||
*_flymake.*
|
||||
|
||||
# eshell files
|
||||
/eshell/history
|
||||
/eshell/lastdir
|
||||
|
||||
# elpa packages
|
||||
/elpa/
|
||||
|
||||
# reftex files
|
||||
*.rel
|
||||
|
||||
# AUCTeX auto folder
|
||||
/auto/
|
||||
|
||||
# cask packages
|
||||
.cask/
|
||||
|
||||
# Flycheck
|
||||
flycheck_*.el
|
||||
|
||||
# server auth directory
|
||||
/server/
|
||||
|
||||
# projectiles files
|
||||
.projectile
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
jspm_packages
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
|
||||
### Bower ###
|
||||
bower_components
|
||||
.bower-cache
|
||||
.bower-registry
|
||||
.bower-tmp
|
||||
|
||||
|
||||
### WebSharper ###
|
||||
Scripts/
|
|
@ -0,0 +1,3 @@
|
|||
module Bob
|
||||
|
||||
let response (input: string): string = failwith "You need to implement this function."
|
|
@ -0,0 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Bob.fs" />
|
||||
<Compile Include="BobTest.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,109 @@
|
|||
// This file was auto-generated based on version 1.2.0 of the canonical data.
|
||||
|
||||
module BobTest
|
||||
|
||||
open FsUnit.Xunit
|
||||
open Xunit
|
||||
|
||||
open Bob
|
||||
|
||||
[<Fact>]
|
||||
let ``Stating something`` () =
|
||||
response "Tom-ay-to, tom-aaaah-to." |> should equal "Whatever."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Shouting`` () =
|
||||
response "WATCH OUT!" |> should equal "Whoa, chill out!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Shouting gibberish`` () =
|
||||
response "FCECDFCAAB" |> should equal "Whoa, chill out!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Asking a question`` () =
|
||||
response "Does this cryogenic chamber make me look fat?" |> should equal "Sure."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Asking a numeric question`` () =
|
||||
response "You are, what, like 15?" |> should equal "Sure."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Asking gibberish`` () =
|
||||
response "fffbbcbeab?" |> should equal "Sure."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Talking forcefully`` () =
|
||||
response "Let's go make out behind the gym!" |> should equal "Whatever."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Using acronyms in regular speech`` () =
|
||||
response "It's OK if you don't want to go to the DMV." |> should equal "Whatever."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Forceful question`` () =
|
||||
response "WHAT THE HELL WERE YOU THINKING?" |> should equal "Calm down, I know what I'm doing!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Shouting numbers`` () =
|
||||
response "1, 2, 3 GO!" |> should equal "Whoa, chill out!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Only numbers`` () =
|
||||
response "1, 2, 3" |> should equal "Whatever."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Question with only numbers`` () =
|
||||
response "4?" |> should equal "Sure."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Shouting with special characters`` () =
|
||||
response "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!" |> should equal "Whoa, chill out!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Shouting with no exclamation mark`` () =
|
||||
response "I HATE YOU" |> should equal "Whoa, chill out!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Statement containing question mark`` () =
|
||||
response "Ending with ? means a question." |> should equal "Whatever."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Non-letters with question`` () =
|
||||
response ":) ?" |> should equal "Sure."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Prattling on`` () =
|
||||
response "Wait! Hang on. Are you going to be OK?" |> should equal "Sure."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Silence`` () =
|
||||
response "" |> should equal "Fine. Be that way!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Prolonged silence`` () =
|
||||
response " " |> should equal "Fine. Be that way!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Alternate silence`` () =
|
||||
response "\t\t\t\t\t\t\t\t\t\t" |> should equal "Fine. Be that way!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Multiple line question`` () =
|
||||
response "\nDoes this cryogenic chamber make me look fat?\nno" |> should equal "Whatever."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Starting with whitespace`` () =
|
||||
response " hmmmmmmm..." |> should equal "Whatever."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Ending with whitespace`` () =
|
||||
response "Okay if like my spacebar quite a bit? " |> should equal "Sure."
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Other whitespace`` () =
|
||||
response "\n\r \t" |> should equal "Fine. Be that way!"
|
||||
|
||||
[<Fact(Skip = "Remove to run test")>]
|
||||
let ``Non-question ending with whitespace`` () =
|
||||
response "This is a statement ending with whitespace " |> should equal "Whatever."
|
||||
|
|
@ -0,0 +1 @@
|
|||
module Program = let [<EntryPoint>] main _ = 0
|
|
@ -0,0 +1,20 @@
|
|||
# Bob
|
||||
|
||||
Bob is a lackadaisical teenager. In conversation, his responses are very limited.
|
||||
|
||||
Bob answers 'Sure.' if you ask him a question.
|
||||
|
||||
He answers 'Whoa, chill out!' if you yell at him.
|
||||
|
||||
He answers 'Calm down, I know what I'm doing!' if you yell a question at him.
|
||||
|
||||
He says 'Fine. Be that way!' if you address him without actually saying anything.
|
||||
|
||||
He answers 'Whatever.' to anything else.
|
||||
|
||||
## Source
|
||||
|
||||
Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=06](http://pine.fm/LearnToProgram/?Chapter=06)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,3 @@
|
|||
module HelloWorld
|
||||
|
||||
let hello: string = "Hello, World!"
|
|
@ -0,0 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="HelloWorld.fs" />
|
||||
<Compile Include="HelloWorldTest.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,13 @@
|
|||
// This file was auto-generated based on version 1.1.0 of the canonical data.
|
||||
|
||||
module HelloWorldTest
|
||||
|
||||
open FsUnit.Xunit
|
||||
open Xunit
|
||||
|
||||
open HelloWorld
|
||||
|
||||
[<Fact>]
|
||||
let ``Say Hi!`` () =
|
||||
hello |> should equal "Hello, World!"
|
||||
|
|
@ -0,0 +1 @@
|
|||
module Program = let [<EntryPoint>] main _ = 0
|
|
@ -0,0 +1,21 @@
|
|||
# Hello World
|
||||
|
||||
The classical introductory exercise. Just say "Hello, World!".
|
||||
|
||||
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is
|
||||
the traditional first program for beginning programming in a new language
|
||||
or environment.
|
||||
|
||||
The objectives are simple:
|
||||
|
||||
- Write a function that returns the string "Hello, World!".
|
||||
- Run the test suite and make sure that it succeeds.
|
||||
- Submit your solution and check it at the website.
|
||||
|
||||
If everything goes well, you will be ready to fetch your first real exercise.
|
||||
## Source
|
||||
|
||||
This is an exercise to introduce users to using Exercism [http://en.wikipedia.org/wiki/%22Hello,_world!%22_program](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,3 @@
|
|||
module Leap
|
||||
|
||||
let leapYear (year: int): bool = year % 400 = 0 || (year % 4 = 0 && year % 100 <> 0)
|
|
@ -0,0 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Leap.fs" />
|
||||
<Compile Include="LeapTest.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,25 @@
|
|||
// This file was auto-generated based on version 1.3.0 of the canonical data.
|
||||
|
||||
module LeapTest
|
||||
|
||||
open FsUnit.Xunit
|
||||
open Xunit
|
||||
|
||||
open Leap
|
||||
|
||||
[<Fact>]
|
||||
let ``Year not divisible by 4: common year`` () =
|
||||
leapYear 2015 |> should equal false
|
||||
|
||||
[<Fact>]
|
||||
let ``Year divisible by 4, not divisible by 100: leap year`` () =
|
||||
leapYear 1996 |> should equal true
|
||||
|
||||
[<Fact>]
|
||||
let ``Year divisible by 100, not divisible by 400: common year`` () =
|
||||
leapYear 2100 |> should equal false
|
||||
|
||||
[<Fact>]
|
||||
let ``Year divisible by 400: leap year`` () =
|
||||
leapYear 2000 |> should equal true
|
||||
|
|
@ -0,0 +1 @@
|
|||
module Program = let [<EntryPoint>] main _ = 0
|
|
@ -0,0 +1,33 @@
|
|||
# Leap
|
||||
|
||||
Given a year, report if it is a leap year.
|
||||
|
||||
The tricky thing here is that a leap year in the Gregorian calendar occurs:
|
||||
|
||||
```plain
|
||||
on every year that is evenly divisible by 4
|
||||
except every year that is evenly divisible by 100
|
||||
unless the year is also evenly divisible by 400
|
||||
```
|
||||
|
||||
For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap
|
||||
year, but 2000 is.
|
||||
|
||||
If your language provides a method in the standard library that does
|
||||
this look-up, pretend it doesn't exist and implement it yourself.
|
||||
|
||||
## Notes
|
||||
|
||||
Though our exercise adopts some very simple rules, there is more to
|
||||
learn!
|
||||
|
||||
For a delightful, four minute explanation of the whole leap year
|
||||
phenomenon, go watch [this youtube video][video].
|
||||
|
||||
[video]: http://www.youtube.com/watch?v=xX96xng7sAE
|
||||
## Source
|
||||
|
||||
JavaRanch Cattle Drive, exercise 3 [http://www.javaranch.com/leap.jsp](http://www.javaranch.com/leap.jsp)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,50 @@
|
|||
*.gem
|
||||
*.rbc
|
||||
/.config
|
||||
/coverage/
|
||||
/InstalledFiles
|
||||
/pkg/
|
||||
/spec/reports/
|
||||
/spec/examples.txt
|
||||
/test/tmp/
|
||||
/test/version_tmp/
|
||||
/tmp/
|
||||
|
||||
# Used by dotenv library to load environment variables.
|
||||
# .env
|
||||
|
||||
## Specific to RubyMotion:
|
||||
.dat*
|
||||
.repl_history
|
||||
build/
|
||||
*.bridgesupport
|
||||
build-iPhoneOS/
|
||||
build-iPhoneSimulator/
|
||||
|
||||
## Specific to RubyMotion (use of CocoaPods):
|
||||
#
|
||||
# We recommend against adding the Pods directory to your .gitignore. However
|
||||
# you should judge for yourself, the pros and cons are mentioned at:
|
||||
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||
#
|
||||
# vendor/Pods/
|
||||
|
||||
## Documentation cache and generated files:
|
||||
/.yardoc/
|
||||
/_yardoc/
|
||||
/doc/
|
||||
/rdoc/
|
||||
|
||||
## Environment normalization:
|
||||
/.bundle/
|
||||
/vendor/bundle
|
||||
/lib/bundler/man/
|
||||
|
||||
# for a library or gem, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# Gemfile.lock
|
||||
# .ruby-version
|
||||
# .ruby-gemset
|
||||
|
||||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
||||
.rvmrc
|
|
@ -0,0 +1,43 @@
|
|||
# Difference Of Squares
|
||||
|
||||
Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.
|
||||
|
||||
The square of the sum of the first ten natural numbers is
|
||||
(1 + 2 + ... + 10)² = 55² = 3025.
|
||||
|
||||
The sum of the squares of the first ten natural numbers is
|
||||
1² + 2² + ... + 10² = 385.
|
||||
|
||||
Hence the difference between the square of the sum of the first
|
||||
ten natural numbers and the sum of the squares of the first ten
|
||||
natural numbers is 3025 - 385 = 2640.
|
||||
|
||||
* * * *
|
||||
|
||||
For installation and learning resources, refer to the
|
||||
[exercism help page](http://exercism.io/languages/ruby).
|
||||
|
||||
For running the tests provided, you will need the Minitest gem. Open a
|
||||
terminal window and run the following command to install minitest:
|
||||
|
||||
gem install minitest
|
||||
|
||||
If you would like color output, you can `require 'minitest/pride'` in
|
||||
the test file, or note the alternative instruction, below, for running
|
||||
the test file.
|
||||
|
||||
Run the tests from the exercise directory using the following command:
|
||||
|
||||
ruby difference_of_squares_test.rb
|
||||
|
||||
To include color from the command line:
|
||||
|
||||
ruby -r minitest/pride difference_of_squares_test.rb
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
Problem 6 at Project Euler [http://projecteuler.net/problem=6](http://projecteuler.net/problem=6)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,23 @@
|
|||
class Squares
|
||||
@num
|
||||
def initialize(num)
|
||||
@num = num
|
||||
end
|
||||
|
||||
def difference
|
||||
square_of_sum - sum_of_squares
|
||||
end
|
||||
|
||||
def sum_of_squares
|
||||
(1..@num).map{|n| n ** 2}.inject(&:+)
|
||||
end
|
||||
|
||||
def square_of_sum
|
||||
(1..@num).inject(&:+) ** 2
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module BookKeeping
|
||||
VERSION = 4
|
||||
end
|
|
@ -0,0 +1,62 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative 'difference_of_squares'
|
||||
|
||||
# Common test data version: 1.1.0 7a1108b
|
||||
class DifferenceOfSquaresTest < Minitest::Test
|
||||
def test_square_of_sum_1
|
||||
assert_equal 1, Squares.new(1).square_of_sum
|
||||
end
|
||||
|
||||
def test_square_of_sum_5
|
||||
assert_equal 225, Squares.new(5).square_of_sum
|
||||
end
|
||||
|
||||
def test_square_of_sum_100
|
||||
assert_equal 25_502_500, Squares.new(100).square_of_sum
|
||||
end
|
||||
|
||||
def test_sum_of_squares_1
|
||||
assert_equal 1, Squares.new(1).sum_of_squares
|
||||
end
|
||||
|
||||
def test_sum_of_squares_5
|
||||
assert_equal 55, Squares.new(5).sum_of_squares
|
||||
end
|
||||
|
||||
def test_sum_of_squares_100
|
||||
assert_equal 338_350, Squares.new(100).sum_of_squares
|
||||
end
|
||||
|
||||
def test_difference_of_squares_1
|
||||
assert_equal 0, Squares.new(1).difference
|
||||
end
|
||||
|
||||
def test_difference_of_squares_5
|
||||
assert_equal 170, Squares.new(5).difference
|
||||
end
|
||||
|
||||
def test_difference_of_squares_100
|
||||
assert_equal 25_164_150, Squares.new(100).difference
|
||||
end
|
||||
|
||||
# Problems in exercism evolve over time, as we find better ways to ask
|
||||
# questions.
|
||||
# The version number refers to the version of the problem you solved,
|
||||
# not your solution.
|
||||
#
|
||||
# Define a constant named VERSION inside of the top level BookKeeping
|
||||
# module, which may be placed near the end of your file.
|
||||
#
|
||||
# In your file, it will look like this:
|
||||
#
|
||||
# module BookKeeping
|
||||
# VERSION = 1 # Where the version number matches the one in the test.
|
||||
# end
|
||||
#
|
||||
# If you are curious, read more about constants on RubyDoc:
|
||||
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
|
||||
|
||||
def test_bookkeeping
|
||||
assert_equal 4, BookKeeping::VERSION
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
# Gigasecond
|
||||
|
||||
Calculate the moment when someone has lived for 10^9 seconds.
|
||||
|
||||
A gigasecond is 10^9 (1,000,000,000) seconds.
|
||||
|
||||
* * * *
|
||||
|
||||
For installation and learning resources, refer to the
|
||||
[exercism help page](http://exercism.io/languages/ruby).
|
||||
|
||||
For running the tests provided, you will need the Minitest gem. Open a
|
||||
terminal window and run the following command to install minitest:
|
||||
|
||||
gem install minitest
|
||||
|
||||
If you would like color output, you can `require 'minitest/pride'` in
|
||||
the test file, or note the alternative instruction, below, for running
|
||||
the test file.
|
||||
|
||||
Run the tests from the exercise directory using the following command:
|
||||
|
||||
ruby gigasecond_test.rb
|
||||
|
||||
To include color from the command line:
|
||||
|
||||
ruby -r minitest/pride gigasecond_test.rb
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
Chapter 9 in Chris Pine's online Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=09](http://pine.fm/LearnToProgram/?Chapter=09)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,9 @@
|
|||
class Gigasecond
|
||||
def self.from(time)
|
||||
time + 1_000_000_000
|
||||
end
|
||||
end
|
||||
|
||||
module BookKeeping
|
||||
VERSION = 6
|
||||
end
|
|
@ -0,0 +1,47 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative 'gigasecond'
|
||||
|
||||
# Common test data version: 1.0.0 61e7d70
|
||||
class GigasecondTest < Minitest::Test
|
||||
def test_date_only_specification_of_time
|
||||
# skip
|
||||
assert_equal Time.utc(2043, 1, 1, 1, 46, 40), Gigasecond.from(Time.utc(2011, 4, 25, 0, 0, 0))
|
||||
end
|
||||
|
||||
def test_second_test_for_date_only_specification_of_time
|
||||
assert_equal Time.utc(2009, 2, 19, 1, 46, 40), Gigasecond.from(Time.utc(1977, 6, 13, 0, 0, 0))
|
||||
end
|
||||
|
||||
def test_third_test_for_date_only_specification_of_time
|
||||
assert_equal Time.utc(1991, 3, 27, 1, 46, 40), Gigasecond.from(Time.utc(1959, 7, 19, 0, 0, 0))
|
||||
end
|
||||
|
||||
def test_full_time_specified
|
||||
assert_equal Time.utc(2046, 10, 2, 23, 46, 40), Gigasecond.from(Time.utc(2015, 1, 24, 22, 0, 0))
|
||||
end
|
||||
|
||||
def test_full_time_with_day_roll_over
|
||||
assert_equal Time.utc(2046, 10, 3, 1, 46, 39), Gigasecond.from(Time.utc(2015, 1, 24, 23, 59, 59))
|
||||
end
|
||||
|
||||
# Problems in exercism evolve over time, as we find better ways to ask
|
||||
# questions.
|
||||
# The version number refers to the version of the problem you solved,
|
||||
# not your solution.
|
||||
#
|
||||
# Define a constant named VERSION inside of the top level BookKeeping
|
||||
# module, which may be placed near the end of your file.
|
||||
#
|
||||
# In your file, it will look like this:
|
||||
#
|
||||
# module BookKeeping
|
||||
# VERSION = 1 # Where the version number matches the one in the test.
|
||||
# end
|
||||
#
|
||||
# If you are curious, read more about constants on RubyDoc:
|
||||
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
|
||||
|
||||
def test_bookkeeping
|
||||
assert_equal 6, BookKeeping::VERSION
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
# Grains
|
||||
|
||||
Calculate the number of grains of wheat on a chessboard given that the number
|
||||
on each square doubles.
|
||||
|
||||
There once was a wise servant who saved the life of a prince. The king
|
||||
promised to pay whatever the servant could dream up. Knowing that the
|
||||
king loved chess, the servant told the king he would like to have grains
|
||||
of wheat. One grain on the first square of a chess board. Two grains on
|
||||
the next. Four on the third, and so on.
|
||||
|
||||
There are 64 squares on a chessboard.
|
||||
|
||||
Write code that shows:
|
||||
- how many grains were on each square, and
|
||||
- the total number of grains
|
||||
|
||||
## For bonus points
|
||||
|
||||
Did you get the tests passing and the code clean? If you want to, these
|
||||
are some additional things you could try:
|
||||
|
||||
- Optimize for speed.
|
||||
- Optimize for readability.
|
||||
|
||||
Then please share your thoughts in a comment on the submission. Did this
|
||||
experiment make the code better? Worse? Did you learn anything from it?
|
||||
|
||||
* * * *
|
||||
|
||||
For installation and learning resources, refer to the
|
||||
[exercism help page](http://exercism.io/languages/ruby).
|
||||
|
||||
For running the tests provided, you will need the Minitest gem. Open a
|
||||
terminal window and run the following command to install minitest:
|
||||
|
||||
gem install minitest
|
||||
|
||||
If you would like color output, you can `require 'minitest/pride'` in
|
||||
the test file, or note the alternative instruction, below, for running
|
||||
the test file.
|
||||
|
||||
Run the tests from the exercise directory using the following command:
|
||||
|
||||
ruby grains_test.rb
|
||||
|
||||
To include color from the command line:
|
||||
|
||||
ruby -r minitest/pride grains_test.rb
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
JavaRanch Cattle Drive, exercise 6 [http://www.javaranch.com/grains.jsp](http://www.javaranch.com/grains.jsp)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,14 @@
|
|||
class Grains
|
||||
def self.square(n)
|
||||
raise ArgumentError if n < 1 || n > 64
|
||||
2 ** (n - 1)
|
||||
end
|
||||
|
||||
def self.total
|
||||
(0...64).map{|n| 2 ** n}.inject(&:+)
|
||||
end
|
||||
end
|
||||
|
||||
module BookKeeping
|
||||
VERSION = 1
|
||||
end
|
|
@ -0,0 +1,70 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative 'grains'
|
||||
|
||||
# Common test data version: 1.0.0 2e0e77e
|
||||
class GrainsTest < Minitest::Test
|
||||
def test_1
|
||||
assert_equal 1, Grains.square(1)
|
||||
end
|
||||
|
||||
def test_2
|
||||
assert_equal 2, Grains.square(2)
|
||||
end
|
||||
|
||||
def test_3
|
||||
assert_equal 4, Grains.square(3)
|
||||
end
|
||||
|
||||
def test_4
|
||||
assert_equal 8, Grains.square(4)
|
||||
end
|
||||
|
||||
def test_16
|
||||
assert_equal 32_768, Grains.square(16)
|
||||
end
|
||||
|
||||
def test_32
|
||||
assert_equal 2_147_483_648, Grains.square(32)
|
||||
end
|
||||
|
||||
def test_64
|
||||
assert_equal 9_223_372_036_854_775_808, Grains.square(64)
|
||||
end
|
||||
|
||||
def test_square_0_raises_an_exception
|
||||
assert_raises(ArgumentError) { Grains.square(0) }
|
||||
end
|
||||
|
||||
def test_negative_square_raises_an_exception
|
||||
assert_raises(ArgumentError) { Grains.square(-1) }
|
||||
end
|
||||
|
||||
def test_square_greater_than_64_raises_an_exception
|
||||
assert_raises(ArgumentError) { Grains.square(65) }
|
||||
end
|
||||
|
||||
def test_returns_the_total_number_of_grains_on_the_board
|
||||
assert_equal 18_446_744_073_709_551_615, Grains.total
|
||||
end
|
||||
|
||||
# Problems in exercism evolve over time, as we find better ways to ask
|
||||
# questions.
|
||||
# The version number refers to the version of the problem you solved,
|
||||
# not your solution.
|
||||
#
|
||||
# Define a constant named VERSION inside of the top level BookKeeping
|
||||
# module, which may be placed near the end of your file.
|
||||
#
|
||||
# In your file, it will look like this:
|
||||
#
|
||||
# module BookKeeping
|
||||
# VERSION = 1 # Where the version number matches the one in the test.
|
||||
# end
|
||||
#
|
||||
# If you are curious, read more about constants on RubyDoc:
|
||||
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
|
||||
|
||||
def test_bookkeeping
|
||||
assert_equal 1, BookKeeping::VERSION
|
||||
end
|
||||
end
|
|
@ -0,0 +1,66 @@
|
|||
# Hamming
|
||||
|
||||
Calculate the Hamming difference between two DNA strands.
|
||||
|
||||
A mutation is simply a mistake that occurs during the creation or
|
||||
copying of a nucleic acid, in particular DNA. Because nucleic acids are
|
||||
vital to cellular functions, mutations tend to cause a ripple effect
|
||||
throughout the cell. Although mutations are technically mistakes, a very
|
||||
rare mutation may equip the cell with a beneficial attribute. In fact,
|
||||
the macro effects of evolution are attributable by the accumulated
|
||||
result of beneficial microscopic mutations over many generations.
|
||||
|
||||
The simplest and most common type of nucleic acid mutation is a point
|
||||
mutation, which replaces one base with another at a single nucleotide.
|
||||
|
||||
By counting the number of differences between two homologous DNA strands
|
||||
taken from different genomes with a common ancestor, we get a measure of
|
||||
the minimum number of point mutations that could have occurred on the
|
||||
evolutionary path between the two strands.
|
||||
|
||||
This is called the 'Hamming distance'.
|
||||
|
||||
It is found by comparing two DNA strands and counting how many of the
|
||||
nucleotides are different from their equivalent in the other string.
|
||||
|
||||
GAGCCTACTAACGGGAT
|
||||
CATCGTAATGACGGCCT
|
||||
^ ^ ^ ^ ^ ^^
|
||||
|
||||
The Hamming distance between these two DNA strands is 7.
|
||||
|
||||
# Implementation notes
|
||||
|
||||
The Hamming distance is only defined for sequences of equal length. This means
|
||||
that based on the definition, each language could deal with getting sequences
|
||||
of equal length differently.
|
||||
|
||||
* * * *
|
||||
|
||||
For installation and learning resources, refer to the
|
||||
[exercism help page](http://exercism.io/languages/ruby).
|
||||
|
||||
For running the tests provided, you will need the Minitest gem. Open a
|
||||
terminal window and run the following command to install minitest:
|
||||
|
||||
gem install minitest
|
||||
|
||||
If you would like color output, you can `require 'minitest/pride'` in
|
||||
the test file, or note the alternative instruction, below, for running
|
||||
the test file.
|
||||
|
||||
Run the tests from the exercise directory using the following command:
|
||||
|
||||
ruby hamming_test.rb
|
||||
|
||||
To include color from the command line:
|
||||
|
||||
ruby -r minitest/pride hamming_test.rb
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
The Calculating Point Mutations problem at Rosalind [http://rosalind.info/problems/hamm/](http://rosalind.info/problems/hamm/)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,56 @@
|
|||
# Running Tests
|
||||
|
||||
In order to complete this exercise, and all of the subsequent exercises, you
|
||||
will need to pass multiple tests.
|
||||
|
||||
## Understanding Test Results
|
||||
|
||||
After you have created and saved `hamming.rb`, run the test suite. You should
|
||||
see output like the following:
|
||||
|
||||
# Running:
|
||||
|
||||
SSSSSSESSSSSSSSS
|
||||
|
||||
Finished in 0.002593s, 6170.4588 runs/s, 0.0000 assertions/s.
|
||||
|
||||
1) Error:
|
||||
HammingTest#test_identical_strands:
|
||||
NameError: uninitialized constant HammingTest::Hamming
|
||||
Did you mean? HammingTest
|
||||
../hamming/hamming_test.rb:9:in `test_identical_strands'
|
||||
|
||||
16 runs, 0 assertions, 0 failures, 1 errors, 15 skips
|
||||
|
||||
You have skipped tests. Run with --verbose for details.
|
||||
|
||||
|
||||
The letters `SSSSSSESSSSSSSSS` show that there are sixteen tests altogether,
|
||||
that one of them has an error (`E`), and that the rest of them are skipped (all
|
||||
the `S` letters).
|
||||
|
||||
The tests are run in randomized order, which will cause the letters to display
|
||||
in random order as well.
|
||||
|
||||
The goal is to have all passing tests, which will show in two places:
|
||||
|
||||
1. `SSSSSSESSSSSSSSS` will become a series dots: `................`,
|
||||
|
||||
2. The line at the bottom will read `16 runs, 0 assertions, 0 failures, 0
|
||||
errors, 0 skips`.
|
||||
|
||||
## Passing Tests
|
||||
|
||||
Write enough code to change the Error to Failure, and finally to Passing.
|
||||
|
||||
Open `hamming_test.rb`, and find the word "skip". All but the first test start
|
||||
with "skip", which tells Minitest to ignore the test. This is so that you don't
|
||||
have to deal with all the failures at once.
|
||||
|
||||
To activate the next test, delete the "skip", or comment it out, and run the
|
||||
test suite again.
|
||||
|
||||
## Wash, Rinse, Repeat
|
||||
|
||||
Delete one "skip" at a time, and make each test pass before you move to the
|
||||
next one.
|
|
@ -0,0 +1,6 @@
|
|||
class Hamming
|
||||
def self.compute(a, b)
|
||||
raise ArgumentError unless a.length == b.length
|
||||
(0..a.length).count {|i| a[i] != b[i]}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,88 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative 'hamming'
|
||||
|
||||
# Common test data version: 2.0.1 f79dfd7
|
||||
class HammingTest < Minitest::Test
|
||||
def test_empty_strands
|
||||
# skip
|
||||
assert_equal 0, Hamming.compute('', '')
|
||||
end
|
||||
|
||||
def test_identical_strands
|
||||
assert_equal 0, Hamming.compute('A', 'A')
|
||||
end
|
||||
|
||||
def test_long_identical_strands
|
||||
assert_equal 0, Hamming.compute('GGACTGA', 'GGACTGA')
|
||||
end
|
||||
|
||||
def test_complete_distance_in_single_nucleotide_strands
|
||||
assert_equal 1, Hamming.compute('A', 'G')
|
||||
end
|
||||
|
||||
def test_complete_distance_in_small_strands
|
||||
assert_equal 2, Hamming.compute('AG', 'CT')
|
||||
end
|
||||
|
||||
def test_small_distance_in_small_strands
|
||||
assert_equal 1, Hamming.compute('AT', 'CT')
|
||||
end
|
||||
|
||||
def test_small_distance
|
||||
assert_equal 1, Hamming.compute('GGACG', 'GGTCG')
|
||||
end
|
||||
|
||||
def test_small_distance_in_long_strands
|
||||
assert_equal 2, Hamming.compute('ACCAGGG', 'ACTATGG')
|
||||
end
|
||||
|
||||
def test_non_unique_character_in_first_strand
|
||||
assert_equal 1, Hamming.compute('AAG', 'AAA')
|
||||
end
|
||||
|
||||
def test_non_unique_character_in_second_strand
|
||||
assert_equal 1, Hamming.compute('AAA', 'AAG')
|
||||
end
|
||||
|
||||
def test_same_nucleotides_in_different_positions
|
||||
assert_equal 2, Hamming.compute('TAG', 'GAT')
|
||||
end
|
||||
|
||||
def test_large_distance
|
||||
assert_equal 4, Hamming.compute('GATACA', 'GCATAA')
|
||||
end
|
||||
|
||||
def test_large_distance_in_off_by_one_strand
|
||||
assert_equal 9, Hamming.compute('GGACGGATTCTG', 'AGGACGGATTCT')
|
||||
end
|
||||
|
||||
def test_disallow_first_strand_longer
|
||||
assert_raises(ArgumentError) { Hamming.compute('AATG', 'AAA') }
|
||||
end
|
||||
|
||||
def test_disallow_second_strand_longer
|
||||
assert_raises(ArgumentError) { Hamming.compute('ATA', 'AGTG') }
|
||||
end
|
||||
|
||||
# Problems in exercism evolve over time, as we find better ways to ask
|
||||
# questions.
|
||||
# The version number refers to the version of the problem you solved,
|
||||
# not your solution.
|
||||
#
|
||||
# Define a constant named VERSION inside of the top level BookKeeping
|
||||
# module, which may be placed near the end of your file.
|
||||
#
|
||||
# In your file, it will look like this:
|
||||
#
|
||||
# module BookKeeping
|
||||
# VERSION = 1 # Where the version number matches the one in the test.
|
||||
# end
|
||||
#
|
||||
# If you are curious, read more about constants on RubyDoc:
|
||||
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
|
||||
|
||||
def test_bookkeeping
|
||||
skip
|
||||
assert_equal 3, BookKeeping::VERSION
|
||||
end
|
||||
end
|
|
@ -0,0 +1,128 @@
|
|||
# Getting Started
|
||||
|
||||
These exercises lean on Test-Driven Development (TDD), but they're not an
|
||||
exact match. If you want a gentle introduction to TDD using minitest in
|
||||
Ruby, see the "Intro to TDD" over at JumpstartLab:
|
||||
http://tutorials.jumpstartlab.com/topics/testing/intro-to-tdd.html
|
||||
|
||||
The following steps assume that you are in the same directory as the test
|
||||
suite.
|
||||
|
||||
You must have the `minitest` gem installed:
|
||||
|
||||
$ gem install minitest
|
||||
|
||||
## Step 1
|
||||
|
||||
Run the test suite. It's written using the Minitest framework, and can be
|
||||
run with ruby:
|
||||
|
||||
$ ruby hello_world_test.rb
|
||||
|
||||
This will fail, complaining that there is no file called `hello_world`.
|
||||
|
||||
To fix the error create an empty file called `hello_world.rb` in the same
|
||||
directory as the `hello_world_test.rb` file.
|
||||
|
||||
## Step 2
|
||||
|
||||
Run the test again. It will give you a new error, since now the file exists,
|
||||
but is empty and does not contain the expected code.
|
||||
|
||||
Depending on what platform you are on, the error will look different, but
|
||||
the way to fix it will be the same.
|
||||
|
||||
On Windows, it will complain about:
|
||||
|
||||
syntax error, unexpected end-of-input, expecting '('
|
||||
|
||||
On OS X and Linux, the error will be something like:
|
||||
|
||||
|
||||
# Running:
|
||||
|
||||
E
|
||||
|
||||
Finished in 0.001328s, 753.0121 runs/s, 0.0000 assertions/s.
|
||||
|
||||
1) Error:
|
||||
HelloWorldTest#test_say_hi:
|
||||
NameError: uninitialized constant HelloWorldTest::HelloWorld
|
||||
Did you mean? HelloWorldTest
|
||||
hello_world_test.rb:19:in `test_say_hi'
|
||||
|
||||
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
|
||||
|
||||
|
||||
Within the first test, we are referencing a constant named `HelloWorld` when
|
||||
we say `HelloWorld.hello`. When Ruby sees a capitalized name like
|
||||
`HelloWorld`, it looks it up in a big huge list of all the constants it knows about,
|
||||
to see what it points to. It could point to anything, and often in Ruby we have
|
||||
constants that point to definitions of classes or modules.
|
||||
|
||||
When it looks `HelloWorld` up in its list, it doesn't find anything, so we need
|
||||
to make one.
|
||||
|
||||
### Fixing the Error
|
||||
|
||||
To fix it, open up the hello_world.rb file and add the following code:
|
||||
|
||||
class HelloWorld
|
||||
end
|
||||
|
||||
## Step 3
|
||||
|
||||
Run the test again.
|
||||
|
||||
1) Error:
|
||||
HelloWorldTest#test_no_name:
|
||||
NoMethodError: undefined method `hello' for HelloWorld:Class
|
||||
hello_world_test.rb:20:in `test_no_name'
|
||||
|
||||
This time we have a `HelloWorld`, but we're trying tell it to `hello`, and
|
||||
`HelloWorld` doesn't understand that message.
|
||||
|
||||
Open up hello_world.rb and add a method definition inside the class:
|
||||
|
||||
class HelloWorld
|
||||
def self.hello
|
||||
end
|
||||
end
|
||||
|
||||
## Step 4
|
||||
|
||||
Run the test again.
|
||||
|
||||
1) Failure:
|
||||
HelloWorldTest#test_no_name [hello_world_test.rb:11]:
|
||||
When given no name, we should greet the world.
|
||||
Expected: "Hello, World!"
|
||||
Actual: nil
|
||||
|
||||
Up until now we've been getting errors, this time we get a failure.
|
||||
|
||||
An error means that Ruby cannot even run properly because of things like missing
|
||||
files or syntax errors, or referring to things that don't exist.
|
||||
|
||||
A failure is different. A failure is when Ruby is running just fine
|
||||
and the test is expecting one outcome, but getting another.
|
||||
|
||||
The test is expecting the `hello` method to return the string `"Hello, World!"`. The easiest way
|
||||
to make it pass, is to simply stick the string `"Hello, World!"` inside the method definition.
|
||||
|
||||
## Step 5
|
||||
|
||||
Run the test again.
|
||||
|
||||
If it fails you're going to need to read the error message carefully to figure
|
||||
out what went wrong, and then try again.
|
||||
|
||||
If it passes, then you're ready to move to the next step.
|
||||
|
||||
## Submit
|
||||
|
||||
When everything is passing, you can submit your code with the following
|
||||
command:
|
||||
|
||||
$ exercism submit hello_world.rb
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# Hello World
|
||||
|
||||
The classical introductory exercise. Just say "Hello, World!".
|
||||
|
||||
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is
|
||||
the traditional first program for beginning programming in a new language
|
||||
or environment.
|
||||
|
||||
The objectives are simple:
|
||||
|
||||
- Write a function that returns the string "Hello, World!".
|
||||
- Run the test suite and make sure that it succeeds.
|
||||
- Submit your solution and check it at the website.
|
||||
|
||||
If everything goes well, you will be ready to fetch your first real exercise.
|
||||
|
||||
* * * *
|
||||
|
||||
For installation and learning resources, refer to the
|
||||
[exercism help page](http://exercism.io/languages/ruby).
|
||||
|
||||
For running the tests provided, you will need the Minitest gem. Open a
|
||||
terminal window and run the following command to install minitest:
|
||||
|
||||
gem install minitest
|
||||
|
||||
If you would like color output, you can `require 'minitest/pride'` in
|
||||
the test file, or note the alternative instruction, below, for running
|
||||
the test file.
|
||||
|
||||
Run the tests from the exercise directory using the following command:
|
||||
|
||||
ruby hello_world_test.rb
|
||||
|
||||
To include color from the command line:
|
||||
|
||||
ruby -r minitest/pride hello_world_test.rb
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
This is an exercise to introduce users to using Exercism [http://en.wikipedia.org/wiki/%22Hello,_world!%22_program](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,5 @@
|
|||
class HelloWorld
|
||||
def self.hello
|
||||
"Hello, World!"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
begin
|
||||
gem 'minitest', '>= 5.0.0'
|
||||
require 'minitest/autorun'
|
||||
require_relative 'hello_world'
|
||||
rescue Gem::LoadError => e
|
||||
puts "\nMissing Dependency:\n#{e.backtrace.first} #{e.message}"
|
||||
puts 'Minitest 5.0 gem must be installed for the Ruby track.'
|
||||
rescue LoadError => e
|
||||
puts "\nError:\n#{e.backtrace.first} #{e.message}"
|
||||
puts DATA.read
|
||||
exit 1
|
||||
end
|
||||
|
||||
# Common test data version: 1.0.0 4b9ae53
|
||||
class HelloWorldTest < Minitest::Test
|
||||
def test_say_hi
|
||||
# skip
|
||||
assert_equal "Hello, World!", HelloWorld.hello
|
||||
end
|
||||
end
|
||||
|
||||
__END__
|
||||
|
||||
*****************************************************
|
||||
You got an error, which is exactly as it should be.
|
||||
This is the first step in the Test-Driven Development
|
||||
(TDD) process.
|
||||
|
||||
The most important part of the error is
|
||||
|
||||
cannot load such file
|
||||
|
||||
It's looking for a file named hello_world.rb that doesn't
|
||||
exist yet.
|
||||
|
||||
To fix the error, create an empty file named hello_world.rb
|
||||
in the same directory as the hello_world_test.rb file.
|
||||
|
||||
Then run the test again.
|
||||
|
||||
For more guidance as you work on this exercise, see
|
||||
GETTING_STARTED.md.
|
||||
*****************************************************
|
|
@ -0,0 +1,57 @@
|
|||
# Leap
|
||||
|
||||
Given a year, report if it is a leap year.
|
||||
|
||||
The tricky thing here is that a leap year in the Gregorian calendar occurs:
|
||||
|
||||
```text
|
||||
on every year that is evenly divisible by 4
|
||||
except every year that is evenly divisible by 100
|
||||
unless the year is also evenly divisible by 400
|
||||
```
|
||||
|
||||
For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap
|
||||
year, but 2000 is.
|
||||
|
||||
If your language provides a method in the standard library that does
|
||||
this look-up, pretend it doesn't exist and implement it yourself.
|
||||
|
||||
## Notes
|
||||
|
||||
Though our exercise adopts some very simple rules, there is more to
|
||||
learn!
|
||||
|
||||
For a delightful, four minute explanation of the whole leap year
|
||||
phenomenon, go watch [this youtube video][video].
|
||||
|
||||
[video]: http://www.youtube.com/watch?v=xX96xng7sAE
|
||||
|
||||
* * * *
|
||||
|
||||
For installation and learning resources, refer to the
|
||||
[exercism help page](http://exercism.io/languages/ruby).
|
||||
|
||||
For running the tests provided, you will need the Minitest gem. Open a
|
||||
terminal window and run the following command to install minitest:
|
||||
|
||||
gem install minitest
|
||||
|
||||
If you would like color output, you can `require 'minitest/pride'` in
|
||||
the test file, or note the alternative instruction, below, for running
|
||||
the test file.
|
||||
|
||||
Run the tests from the exercise directory using the following command:
|
||||
|
||||
ruby leap_test.rb
|
||||
|
||||
To include color from the command line:
|
||||
|
||||
ruby -r minitest/pride leap_test.rb
|
||||
|
||||
|
||||
## Source
|
||||
|
||||
JavaRanch Cattle Drive, exercise 3 [http://www.javaranch.com/leap.jsp](http://www.javaranch.com/leap.jsp)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,9 @@
|
|||
class Year
|
||||
def self.leap?(yr)
|
||||
yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0)
|
||||
end
|
||||
end
|
||||
|
||||
module BookKeeping
|
||||
VERSION = 3
|
||||
end
|
|
@ -0,0 +1,51 @@
|
|||
require 'minitest/autorun'
|
||||
require_relative 'leap'
|
||||
|
||||
# Common test data version: 1.1.0 7f4d0d8
|
||||
class Date
|
||||
def leap?
|
||||
raise RuntimeError, "Implement this yourself instead of using Ruby's implementation."
|
||||
end
|
||||
|
||||
alias gregorian_leap? leap?
|
||||
alias julian_leap? leap?
|
||||
end
|
||||
|
||||
class YearTest < Minitest::Test
|
||||
def test_year_not_divisible_by_4_common_year
|
||||
refute Year.leap?(2015), "Expected 'false', 2015 is not a leap year."
|
||||
end
|
||||
|
||||
def test_year_divisible_by_4_not_divisible_by_100_leap_year
|
||||
assert Year.leap?(2020), "Expected 'true', 2020 is a leap year."
|
||||
end
|
||||
|
||||
def test_year_divisible_by_100_not_divisible_by_400_common_year
|
||||
refute Year.leap?(2100), "Expected 'false', 2100 is not a leap year."
|
||||
end
|
||||
|
||||
def test_year_divisible_by_400_leap_year
|
||||
assert Year.leap?(2000), "Expected 'true', 2000 is a leap year."
|
||||
end
|
||||
|
||||
# Problems in exercism evolve over time, as we find better ways to ask
|
||||
# questions.
|
||||
# The version number refers to the version of the problem you solved,
|
||||
# not your solution.
|
||||
#
|
||||
# Define a constant named VERSION inside of the top level BookKeeping
|
||||
# module, which may be placed near the end of your file.
|
||||
#
|
||||
# In your file, it will look like this:
|
||||
#
|
||||
# module BookKeeping
|
||||
# VERSION = 1 # Where the version number matches the one in the test.
|
||||
# end
|
||||
#
|
||||
# If you are curious, read more about constants on RubyDoc:
|
||||
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
|
||||
|
||||
def test_bookkeeping
|
||||
assert_equal 3, BookKeeping::VERSION
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue