Initial Commit

This commit is contained in:
Brian Buller 2016-08-13 18:20:14 -05:00
commit 50f4a86fd8
408 changed files with 15301 additions and 0 deletions

35
clojure/bob/README.md Normal file
View File

@ -0,0 +1,35 @@
# 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 says 'Fine. Be that way!' if you address him without actually saying
anything.
He answers 'Whatever.' to anything else.
## Instructions
Run the test file, and fix each of the errors in turn. When you get the
first test to pass, go to the first pending or skipped test, and make
that pass as well. When all of the tests are passing, feel free to
submit.
Remember that passing code is just the first step. The goal is to work
towards a solution that is as readable and expressive as you can make
it.
Please make your solution as general as possible. Good code doesn't just
pass the test suite, it works with any input that fits the
specification.
Have fun!
## Source
Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)

48
clojure/bob/bob_test.clj Normal file
View File

@ -0,0 +1,48 @@
(ns bob-test
(:require [clojure.test :refer :all]))
(load-file "bob.clj")
(deftest responds-to-something
(is (= "Whatever." (bob/response-for "Tom-ay-to, tom-aaaah-to."))))
(deftest responds-to-shouts
(is (= "Whoa, chill out!" (bob/response-for "WATCH OUT!"))))
(deftest responds-to-questions
(is (= "Sure." (bob/response-for "Does this cryogenic chamber make me look fat?"))))
(deftest responds-to-forceful-talking
(is (= "Whatever." (bob/response-for "Let's go make out behind the gym!"))))
(deftest responds-to-acronyms
(is (= "Whatever." (bob/response-for "It's OK if you don't want to go to the DMV."))))
(deftest responds-to-forceful-questions
(is (= "Whoa, chill out!" (bob/response-for "WHAT THE HELL WERE YOU THINKING?"))))
(deftest responds-to-shouting-with-special-characters
(is (= "Whoa, chill out!" (bob/response-for "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!"))))
(deftest responds-to-shouting-numbers
(is (= "Whoa, chill out!" (bob/response-for "1, 2, 3 GO!"))))
(deftest responds-to-shouting-with-no-exclamation-mark
(is (= "Whoa, chill out!" (bob/response-for "I HATE YOU"))))
(deftest responds-to-statement-containing-question-mark
(is (= "Whatever." (bob/response-for "Ending with ? means a question."))))
(deftest responds-to-silence
(is (= "Fine. Be that way!" (bob/response-for ""))))
(deftest responds-to-prolonged-silence
(is (= "Fine. Be that way!" (bob/response-for " "))))
(deftest responds-to-only-numbers
(is (= "Whatever." (bob/response-for "1, 2, 3"))))
(deftest responds-to-number-question
(is (= "Sure." (bob/response-for "4?"))))
(run-tests)

6
clojure/bob/project.clj Normal file
View File

@ -0,0 +1,6 @@
(defproject bob "0.1.0-SNAPSHOT"
:description "bob exercise."
:url "https://github.com/exercism/xclojure/tree/master/bob"
:source-paths [""]
:test-paths [""]
:dependencies [[org.clojure/clojure "1.7.0"]])

1
clojure/current Symbolic link
View File

@ -0,0 +1 @@
hello-world

View File

@ -0,0 +1,82 @@
# Hello World
Write a program that greets the user by name, or by saying "Hello, World!" if no name is given.
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is the traditional first program for beginning programming in a new language.
**Note:** You can skip this exercise by running:
exercism skip $LANGUAGE hello-world
## Specification
The `Hello World!` program will greet me, the caller.
If I tell the program my name is Alice, it will greet me by saying "Hello, Alice!".
If I neglect to give it my name, it will greet me by saying "Hello, World!"
## Test-Driven Development
As programmers mature, they eventually want to test their code.
Here at Exercism we simulate [Test-Driven Development](http://en.wikipedia.org/wiki/Test-driven_development) (TDD), where you write your tests before writing any functionality. The simulation comes in the form of a pre-written test suite, which will signal that you have solved the problem.
It will also provide you with a safety net to explore other solutions without breaking the functionality.
### A typical TDD workflow on Exercism:
1. Run the test file and pick one test that's failing.
2. Write some code to fix the test you picked.
3. Re-run the tests to confirm the test is now passing.
4. Repeat from step 1.
5. [Submit your solution](http://help.exercism.io/submitting-exercises.html).
## Instructions
Submissions are encouraged to be general, within reason. Having said that, it's also important not to over-engineer a solution.
It's important to remember that the goal is to make code as expressive and readable as we can. However, solutions to the hello-world exercise will be not be reviewed by a person, but by rikki- the robot, who will offer an encouraging word.
* * * *
For learning resources and help with installation, refer to the
[Exercism help page][].
To run the tests provided, you will need to install [Leiningen][].
To install Leiningen on Mac OS X using [Homebrew][], run the following command:
brew install leiningen
For help installing on Linux, Windows or without Homebrew see:
[Leiningen installation][].
[Exercism help page]: http://exercism.io/languages/clojure
[Leiningen]: http://leiningen.org
[Homebrew]: http://brew.sh
[Leiningen installation]: https://github.com/technomancy/leiningen#installation
In an exercise directory, create a `src` directory and a file therein to hold
your solution. The name of the file should be the exercise name with dashes `-`
replaced by underscores `_`. For example, if the exercise is called
`hello-world`, name the solution file `hello_world.clj`.
Your resulting file tree should look something like this:
/path/to/hello-world
├── project.clj
├── src
│   └── hello_world.clj
└── test
└── hello_world_test.clj
To run the tests, navigate to the exercise directory and run the following
command:
lein test
## Source
This is a program to introduce users to using Exercism [view source](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)

View File

@ -0,0 +1,4 @@
(defproject hello-world "0.1.0-SNAPSHOT"
:description "hello-world exercise."
:url "https://github.com/exercism/xclojure/tree/master/hello-world"
:dependencies [[org.clojure/clojure "1.7.0"]])

View File

@ -0,0 +1,12 @@
(ns hello-world-test
(:require [clojure.test :refer [deftest is]]
hello-world))
(deftest hello-world-test
(is (= "Hello, World!" (hello-world/hello))))
(deftest hello-alice-test
(is (= "Hello, Alice!" (hello-world/hello "Alice"))))
(deftest hello-bob-test
(is (= "Hello, Bob!" (hello-world/hello "Bob"))))

1
coffeescript/current Symbolic link
View File

@ -0,0 +1 @@
hello-world

View File

@ -0,0 +1,48 @@
# Hello World
Write a program that greets the user by name, or by saying "Hello, World!" if no name is given.
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is the traditional first program for beginning programming in a new language.
**Note:** You can skip this exercise by running:
exercism skip $LANGUAGE hello-world
## Specification
The `Hello World!` program will greet me, the caller.
If I tell the program my name is Alice, it will greet me by saying "Hello, Alice!".
If I neglect to give it my name, it will greet me by saying "Hello, World!"
## Test-Driven Development
As programmers mature, they eventually want to test their code.
Here at Exercism we simulate [Test-Driven Development](http://en.wikipedia.org/wiki/Test-driven_development) (TDD), where you write your tests before writing any functionality. The simulation comes in the form of a pre-written test suite, which will signal that you have solved the problem.
It will also provide you with a safety net to explore other solutions without breaking the functionality.
### A typical TDD workflow on Exercism:
1. Run the test file and pick one test that's failing.
2. Write some code to fix the test you picked.
3. Re-run the tests to confirm the test is now passing.
4. Repeat from step 1.
5. [Submit your solution](http://help.exercism.io/submitting-exercises.html).
## Instructions
Submissions are encouraged to be general, within reason. Having said that, it's also important not to over-engineer a solution.
It's important to remember that the goal is to make code as expressive and readable as we can. However, solutions to the hello-world exercise will be not be reviewed by a person, but by rikki- the robot, who will offer an encouraging word.
Refer to the [Exercism help page](http://help.exercism.io/getting-started-with-coffeescript.html) for getting started with CoffeeScript.
In order to run the test, you can run the test file from the exercise directory. For example, if the test suite is called hello_world.spec.coffee, you can run the following command:
jasmine-node --coffee hello_world.spec.coffee
## Source
This is a program to introduce users to using Exercism [view source](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)

View File

@ -0,0 +1,16 @@
HelloWorld = require "./hello_world"
describe "HelloWorld", ->
hello_world = new HelloWorld()
it "given no name", ->
result = hello_world.hello()
expect(result).toEqual "Hello, World!"
it "given the name 'Alice'", ->
result = hello_world.hello 'Alice'
expect(result).toEqual "Hello, Alice!"
it "given the name 'Bob'", ->
result = hello_world.hello 'Bob'
expect(result).toEqual "Hello, Bob!"

52
cpp/bob/CMakeLists.txt Normal file
View File

@ -0,0 +1,52 @@
# Get the exercise name from the current directory
get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME)
# Basic CMake project
cmake_minimum_required(VERSION 2.8.11)
# Name the project after the exercise
project(${exercise} CXX)
# Locate Boost libraries: unit_test_framework, date_time and regex
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.55 REQUIRED COMPONENTS unit_test_framework date_time regex)
# Enable C++11 features on gcc/clang
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)")
set(CMAKE_CXX_FLAGS "-std=c++11")
endif()
# Configure to run all the tests?
if(${EXERCISM_RUN_ALL_TESTS})
add_definitions(-DEXERCISM_RUN_ALL_TESTS)
endif()
# Get a source filename from the exercise name by replacing -'s with _'s
string(REPLACE "-" "_" file ${exercise})
# Implementation could be only a header
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp)
set(exercise_cpp ${file}.cpp)
else()
set(exercise_cpp "")
endif()
# Build executable from sources and headers
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h)
# We need boost includes
target_include_directories(${exercise} PRIVATE ${Boost_INCLUDE_DIRS})
# We need boost libraries
target_link_libraries(${exercise} ${Boost_LIBRARIES})
# Tell MSVC not to warn us about unchecked iterators in debug builds
if(${MSVC})
set_target_properties(${exercise} PROPERTIES
COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS)
endif()
# Run the tests on every build
add_custom_command(TARGET ${exercise} POST_BUILD COMMAND ${exercise})

66
cpp/bob/README.md Normal file
View File

@ -0,0 +1,66 @@
# 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 says 'Fine. Be that way!' if you address him without actually saying
anything.
He answers 'Whatever.' to anything else.
## Instructions
Run the test file, and fix each of the errors in turn. When you get the
first test to pass, go to the first pending or skipped test, and make
that pass as well. When all of the tests are passing, feel free to
submit.
Remember that passing code is just the first step. The goal is to work
towards a solution that is as readable and expressive as you can make
it.
Please make your solution as general as possible. Good code doesn't just
pass the test suite, it works with any input that fits the
specification.
Have fun!
## Getting Started
Make sure you have read the [getting started with C++](http://help.exercism.io/getting-started-with-cpp.html)
page on the [exercism help site](http://help.exercism.io/). This covers
the basic information on setting up the development environment expected
by the exercises.
## Passing the Tests
Get the first test compiling, linking and passing by following the [three
rules of test-driven development](http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd).
Create just enough structure by declaring namespaces, functions, classes,
etc., to satisfy any compiler errors and get the test to fail. Then write
just enough code to get the test to pass. Once you've done that,
uncomment the next test by moving the following line past the next test.
```C++
#if defined(EXERCISM_RUN_ALL_TESTS)
```
This may result in compile errors as new constructs may be invoked that
you haven't yet declared or defined. Again, fix the compile errors minimally
to get a failing test, then change the code minimally to pass the test,
refactor your implementation for readability and expressiveness and then
go on to the next test.
Try to use standard C++11 facilities in preference to writing your own
low-level algorithms or facilities by hand. [CppReference](http://en.cppreference.com/)
is a wiki reference to the C++ language and standard library. If you
are new to C++, but have programmed in C, beware of
[C traps and pitfalls](http://www.slideshare.net/LegalizeAdulthood/c-traps-and-pitfalls-for-c-programmers).
## Source
Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)

90
cpp/bob/bob_test.cpp Normal file
View File

@ -0,0 +1,90 @@
#include "bob.h"
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(stating_something)
{
BOOST_REQUIRE_EQUAL("Whatever.", bob::hey("Tom-ay-to, tom-aaaah-to."));
}
#if defined(EXERCISM_RUN_ALL_TESTS)
BOOST_AUTO_TEST_CASE(shouting)
{
BOOST_REQUIRE_EQUAL("Whoa, chill out!", bob::hey("WATCH OUT!"));
}
BOOST_AUTO_TEST_CASE(asking_a_question)
{
BOOST_REQUIRE_EQUAL("Sure.", bob::hey("Does this cryogenic chamber make me look fat?"));
}
BOOST_AUTO_TEST_CASE(talking_forcefully)
{
BOOST_REQUIRE_EQUAL("Whatever.", bob::hey("Let's go make out behind the gym!"));
}
BOOST_AUTO_TEST_CASE(using_acronyms_in_regular_speech)
{
BOOST_REQUIRE_EQUAL("Whatever.", bob::hey("It's OK if you don't want to go to the DMV."));
}
BOOST_AUTO_TEST_CASE(forceful_questions)
{
BOOST_REQUIRE_EQUAL("Whoa, chill out!", bob::hey("WHAT THE HELL WERE YOU THINKING?"));
}
BOOST_AUTO_TEST_CASE(shouting_numbers)
{
BOOST_REQUIRE_EQUAL("Whoa, chill out!", bob::hey("1, 2, 3 GO!"));
}
BOOST_AUTO_TEST_CASE(only_numbers)
{
BOOST_REQUIRE_EQUAL("Whatever.", bob::hey("1, 2, 3"));
}
BOOST_AUTO_TEST_CASE(question_with_only_numbers)
{
BOOST_REQUIRE_EQUAL("Sure.", bob::hey("4?"));
}
BOOST_AUTO_TEST_CASE(shouting_with_special_characters)
{
BOOST_REQUIRE_EQUAL("Whoa, chill out!", bob::hey("ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!"));
}
BOOST_AUTO_TEST_CASE(shouting_with_no_exclamation_mark)
{
BOOST_REQUIRE_EQUAL("Whoa, chill out!", bob::hey("I HATE YOU"));
}
BOOST_AUTO_TEST_CASE(statement_containing_question_mark)
{
BOOST_REQUIRE_EQUAL("Whatever.", bob::hey("Ending with a ? means a question."));
}
BOOST_AUTO_TEST_CASE(prattling_on)
{
BOOST_REQUIRE_EQUAL("Sure.", bob::hey("Wait! Hang on. Are you going to be OK?"));
}
BOOST_AUTO_TEST_CASE(question_with_trailing_whitespace)
{
BOOST_REQUIRE_EQUAL("Sure.", bob::hey("Are you ok? "));
}
BOOST_AUTO_TEST_CASE(silence)
{
BOOST_REQUIRE_EQUAL("Fine. Be that way!", bob::hey(""));
}
BOOST_AUTO_TEST_CASE(prolonged_silence)
{
BOOST_REQUIRE_EQUAL("Fine. Be that way!", bob::hey(" "));
}
BOOST_AUTO_TEST_CASE(not_all_silence)
{
BOOST_REQUIRE_EQUAL("Whatever.", bob::hey(" A bit of silence can be nice. "));
}
#endif

1
cpp/current Symbolic link
View File

@ -0,0 +1 @@
bob

1
csharp/current Symbolic link
View File

@ -0,0 +1 @@
leap

32
csharp/leap/LeapTest.cs Normal file
View File

@ -0,0 +1,32 @@
using NUnit.Framework;
[TestFixture]
public class LeapTest
{
[Test]
public void Valid_leap_year()
{
Assert.That(Year.IsLeap(1996), Is.True);
}
[Ignore]
[Test]
public void Invalid_leap_year()
{
Assert.That(Year.IsLeap(1997), Is.False);
}
[Ignore]
[Test]
public void Turn_of_the_20th_century_is_not_a_leap_year()
{
Assert.That(Year.IsLeap(1900), Is.False);
}
[Ignore]
[Test]
public void Turn_of_the_25th_century_is_a_leap_year()
{
Assert.That(Year.IsLeap(2400), Is.True);
}
}

33
csharp/leap/README.md Normal file
View File

@ -0,0 +1,33 @@
# Leap
Write a program that will take a year and report if it is a leap year.
The tricky thing here is that a leap year 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
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
### Submitting Exercises
Note that, when trying to submit an exercise, make sure you're exercise file you're submitting is in the `exercism/csharp/<exerciseName>` directory.
For example, if you're submitting `bob.cs` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/csharp/bob/bob.cs`.
## Source
JavaRanch Cattle Drive, exercise 3 [view source](http://www.javaranch.com/leap.jsp)

1
ecmascript/current Symbolic link
View File

@ -0,0 +1 @@
hello-world

View File

@ -0,0 +1,82 @@
# Hello World
Write a program that greets the user by name, or by saying "Hello, World!" if no name is given.
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is the traditional first program for beginning programming in a new language.
**Note:** You can skip this exercise by running:
exercism skip $LANGUAGE hello-world
## Specification
The `Hello World!` program will greet me, the caller.
If I tell the program my name is Alice, it will greet me by saying "Hello, Alice!".
If I neglect to give it my name, it will greet me by saying "Hello, World!"
## Test-Driven Development
As programmers mature, they eventually want to test their code.
Here at Exercism we simulate [Test-Driven Development](http://en.wikipedia.org/wiki/Test-driven_development) (TDD), where you write your tests before writing any functionality. The simulation comes in the form of a pre-written test suite, which will signal that you have solved the problem.
It will also provide you with a safety net to explore other solutions without breaking the functionality.
### A typical TDD workflow on Exercism:
1. Run the test file and pick one test that's failing.
2. Write some code to fix the test you picked.
3. Re-run the tests to confirm the test is now passing.
4. Repeat from step 1.
5. [Submit your solution](http://help.exercism.io/submitting-exercises.html).
## Instructions
Submissions are encouraged to be general, within reason. Having said that, it's also important not to over-engineer a solution.
It's important to remember that the goal is to make code as expressive and readable as we can. However, solutions to the hello-world exercise will be not be reviewed by a person, but by rikki- the robot, who will offer an encouraging word.
## Setup
Go through the setup instructions for ECMAScript to
install the necessary dependencies:
http://help.exercism.io/getting-started-with-ecmascript.html
## Requirements
They are already described in the link above, but just as a
quick reference:
Install globally a tool to run [Gulp](http://gulpjs.com) if
it is not installed yet:
```bash
$ npm install -g gulp-cli
```
Install assignment dependencies:
```bash
$ npm install
```
## Making the test suite pass
Execute the tests with:
```bash
$ gulp test
```
In many test suites all but the first test have been skipped.
Once you get a test passing, you can unskip the next one by
changing `xit` to `it`.
## Source
This is a program to introduce users to using Exercism [view source](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)

View File

@ -0,0 +1,42 @@
function getInputDirectory(argv) {
if (argv.input) {
return argv.input;
}
return '.';
}
function getOutputDirectory(argv) {
if (argv.output) {
return argv.output;
}
return 'babel-output';
}
var gulp = require('gulp'),
jasmine = require('gulp-jasmine'),
babel = require('gulp-babel'),
polyfill = require('babel/polyfill'),
del = require('del'),
argv = require('yargs').argv,
inputDir = getInputDirectory(argv),
outputDir = getOutputDirectory(argv);
// Gulp tasks definition
gulp.task('default', [ 'test' ]);
gulp.task('test', [ 'babel' ], function () {
return gulp.src([ outputDir + '/*.spec.js' ])
.pipe(jasmine());
});
gulp.task('babel', function () {
return gulp.src([ inputDir + '/*.js' ])
.pipe(babel())
.pipe(gulp.dest(outputDir));
});
gulp.task('clean', function (cb) {
del([ outputDir ], cb);
});

View File

@ -0,0 +1,15 @@
//
// This is only a SKELETON file for the 'Hello World' exercise. It's been provided as a
// convenience to get you started writing code faster.
//
class HelloWorld {
hello(name) {
//
// YOUR CODE GOES HERE
//
}
}
export default HelloWorld;

View File

@ -0,0 +1,18 @@
import HelloWorld from './hello-world';
describe('Hello World', () => {
const helloWorld = new HelloWorld();
it('says hello world with no name', () => {
expect(helloWorld.hello('')).toEqual('Hello, World!');
});
xit('says hello to bob', () => {
expect(helloWorld.hello('Bob')).toEqual('Hello, Bob!');
});
xit('says hello to sally', () => {
expect(helloWorld.hello('Sally')).toEqual('Hello, Sally!');
});
});

View File

@ -0,0 +1,25 @@
{
"name": "assignment",
"version": "0.0.1",
"description": "Exercism ECMAScript assignment",
"scripts": {
"test": "gulp test"
},
"repository": {
"type": "git",
"url": "https://github.com/exercism/xecmascript"
},
"bugs": {
"url": "https://github.com/exercism/xecmascript/issues"
},
"homepage": "https://github.com/exercism/xecmascript",
"devDependencies": {
"gulp": "~3.9.0",
"gulp-jasmine": "~2.0.1",
"gulp-clean": "~0.3.1",
"del": "~2.0.2",
"yargs": "~3.27.0",
"gulp-babel": "~5.3.0",
"babel": "~5.8.29"
}
}

1
elisp/current Symbolic link
View File

@ -0,0 +1 @@
hello-world

View File

@ -0,0 +1,44 @@
# Hello World
Write a program that greets the user by name, or by saying "Hello, World!" if no name is given.
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is the traditional first program for beginning programming in a new language.
**Note:** You can skip this exercise by running:
exercism skip $LANGUAGE hello-world
## Specification
The `Hello World!` program will greet me, the caller.
If I tell the program my name is Alice, it will greet me by saying "Hello, Alice!".
If I neglect to give it my name, it will greet me by saying "Hello, World!"
## Test-Driven Development
As programmers mature, they eventually want to test their code.
Here at Exercism we simulate [Test-Driven Development](http://en.wikipedia.org/wiki/Test-driven_development) (TDD), where you write your tests before writing any functionality. The simulation comes in the form of a pre-written test suite, which will signal that you have solved the problem.
It will also provide you with a safety net to explore other solutions without breaking the functionality.
### A typical TDD workflow on Exercism:
1. Run the test file and pick one test that's failing.
2. Write some code to fix the test you picked.
3. Re-run the tests to confirm the test is now passing.
4. Repeat from step 1.
5. [Submit your solution](http://help.exercism.io/submitting-exercises.html).
## Instructions
Submissions are encouraged to be general, within reason. Having said that, it's also important not to over-engineer a solution.
It's important to remember that the goal is to make code as expressive and readable as we can. However, solutions to the hello-world exercise will be not be reviewed by a person, but by rikki- the robot, who will offer an encouraging word.
## Source
This is a program to introduce users to using Exercism [view source](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)

View File

@ -0,0 +1,18 @@
;;; hello-world-test.el --- Tests for Hello World (exercism)
;;; Commentary:
;;; Code:
(load-file "hello-world.el")
(ert-deftest no-args ()
(should (equal (hello) "Hello, World!")))
(ert-deftest with-args ()
(should (equal (hello "Emacs") "Hello, Emacs!"))
(should (equal (hello "Exercism") "Hello, Exercism!")))
(provide 'hello-world-test)
;;; hello-world-test.el ends here

View File

@ -0,0 +1,9 @@
;;; hello-world.el --- Hello World Exercise (exercism)
;;; Commentary:
;;; Code:
(provide 'hello-world)
;;; hello-world.el ends here

42
elixir/bob/README.md Normal file
View File

@ -0,0 +1,42 @@
# 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 says 'Fine. Be that way!' if you address him without actually saying
anything.
He answers 'Whatever.' to anything else.
## Instructions
Run the test file, and fix each of the errors in turn. When you get the
first test to pass, go to the first pending or skipped test, and make
that pass as well. When all of the tests are passing, feel free to
submit.
Remember that passing code is just the first step. The goal is to work
towards a solution that is as readable and expressive as you can make
it.
Please make your solution as general as possible. Good code doesn't just
pass the test suite, it works with any input that fits the
specification.
Have fun!
## Running tests
```bash
$ elixir bob_test.exs
```
(Replace `bob_test.exs` with the name of the test file.)
## Source
Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)

8
elixir/bob/bob.exs Normal file
View File

@ -0,0 +1,8 @@
defmodule Teenager do
def hey(input) do
cond do
true -> raise "Your implementation goes here"
end
end
end

82
elixir/bob/bob_test.exs Normal file
View File

@ -0,0 +1,82 @@
if System.get_env("EXERCISM_TEST_EXAMPLES") do
Code.load_file("example.exs")
else
Code.load_file("bob.exs")
end
ExUnit.start
ExUnit.configure(exclude: :pending)
defmodule TeenagerTest do
use ExUnit.Case, async: true
test "stating something" do
assert Teenager.hey("Tom-ay-to, tom-aaaah-to.") == "Whatever."
end
@tag :pending
test "shouting" do
assert Teenager.hey("WATCH OUT!") == "Whoa, chill out!"
end
@tag :pending
test "asking a question" do
assert Teenager.hey("Does this cryogenic chamber make me look fat?") == "Sure."
end
@tag :pending
test "talking forcefully" do
assert Teenager.hey("Let's go make out behind the gym!") == "Whatever."
end
@tag :pending
test "talking in capitals" do
assert Teenager.hey("This Isn't Shouting!") == "Whatever."
end
@tag :pending
test "shouting numbers" do
assert Teenager.hey("1, 2, 3 GO!") == "Whoa, chill out!"
end
@tag :pending
test "shouting with special characters" do
assert Teenager.hey("ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!") == "Whoa, chill out!"
end
@tag :pending
test "shouting with no exclamation mark" do
assert Teenager.hey("I HATE YOU") == "Whoa, chill out!"
end
@tag :pending
test "statement containing question mark" do
assert Teenager.hey("Ending with ? means a question.") == "Whatever."
end
@tag :pending
test "silence" do
assert Teenager.hey("") == "Fine. Be that way!"
end
@tag :pending
test "prolonged silence" do
assert Teenager.hey(" ") == "Fine. Be that way!"
end
@tag :pending
test "only numbers" do
assert Teenager.hey("1, 2, 3") == "Whatever."
end
@tag :pending
test "question with numbers" do
assert Teenager.hey("4?") == "Sure."
end
@tag :pending
test "shouting in Russian" do
# Hopefully this is Russian for "GET OUT"
assert Teenager.hey("УХОДИТЬ") == "Whoa, chill out!"
end
end

1
elixir/current Symbolic link
View File

@ -0,0 +1 @@
hello-world

View File

@ -0,0 +1,51 @@
# Hello World
Write a program that greets the user by name, or by saying "Hello, World!" if no name is given.
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is the traditional first program for beginning programming in a new language.
**Note:** You can skip this exercise by running:
exercism skip $LANGUAGE hello-world
## Specification
The `Hello World!` program will greet me, the caller.
If I tell the program my name is Alice, it will greet me by saying "Hello, Alice!".
If I neglect to give it my name, it will greet me by saying "Hello, World!"
## Test-Driven Development
As programmers mature, they eventually want to test their code.
Here at Exercism we simulate [Test-Driven Development](http://en.wikipedia.org/wiki/Test-driven_development) (TDD), where you write your tests before writing any functionality. The simulation comes in the form of a pre-written test suite, which will signal that you have solved the problem.
It will also provide you with a safety net to explore other solutions without breaking the functionality.
### A typical TDD workflow on Exercism:
1. Run the test file and pick one test that's failing.
2. Write some code to fix the test you picked.
3. Re-run the tests to confirm the test is now passing.
4. Repeat from step 1.
5. [Submit your solution](http://help.exercism.io/submitting-exercises.html).
## Instructions
Submissions are encouraged to be general, within reason. Having said that, it's also important not to over-engineer a solution.
It's important to remember that the goal is to make code as expressive and readable as we can. However, solutions to the hello-world exercise will be not be reviewed by a person, but by rikki- the robot, who will offer an encouraging word.
## Running tests
```bash
$ elixir bob_test.exs
```
(Replace `bob_test.exs` with the name of the test file.)
## Source
This is a program to introduce users to using Exercism [view source](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)

View File

@ -0,0 +1,7 @@
defmodule HelloWorld do
def hello(name) do
"Your implementation goes here"
end
end

View File

@ -0,0 +1,27 @@
if System.get_env("EXERCISM_TEST_EXAMPLES") do
Code.load_file("example.exs")
else
Code.load_file("hello_world.exs")
end
ExUnit.start
ExUnit.configure exclude: :pending, trace: true
defmodule HelloWorldTest do
use ExUnit.Case, async: true
test "says hello with no name" do
assert HelloWorld.hello() == "Hello, World!"
end
@tag :pending
test "says hello sample name" do
assert HelloWorld.hello("Alice") == "Hello, Alice!"
end
@tag :pending
test "says hello other sample name" do
assert HelloWorld.hello("Bob") == "Hello, Bob!"
end
end

1
erlang/current Symbolic link
View File

@ -0,0 +1 @@
hello-world

View File

@ -0,0 +1,44 @@
# Hello World
Write a program that greets the user by name, or by saying "Hello, World!" if no name is given.
["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is the traditional first program for beginning programming in a new language.
**Note:** You can skip this exercise by running:
exercism skip $LANGUAGE hello-world
## Specification
The `Hello World!` program will greet me, the caller.
If I tell the program my name is Alice, it will greet me by saying "Hello, Alice!".
If I neglect to give it my name, it will greet me by saying "Hello, World!"
## Test-Driven Development
As programmers mature, they eventually want to test their code.
Here at Exercism we simulate [Test-Driven Development](http://en.wikipedia.org/wiki/Test-driven_development) (TDD), where you write your tests before writing any functionality. The simulation comes in the form of a pre-written test suite, which will signal that you have solved the problem.
It will also provide you with a safety net to explore other solutions without breaking the functionality.
### A typical TDD workflow on Exercism:
1. Run the test file and pick one test that's failing.
2. Write some code to fix the test you picked.
3. Re-run the tests to confirm the test is now passing.
4. Repeat from step 1.
5. [Submit your solution](http://help.exercism.io/submitting-exercises.html).
## Instructions
Submissions are encouraged to be general, within reason. Having said that, it's also important not to over-engineer a solution.
It's important to remember that the goal is to make code as expressive and readable as we can. However, solutions to the hello-world exercise will be not be reviewed by a person, but by rikki- the robot, who will offer an encouraging word.
## Source
This is a program to introduce users to using Exercism [view source](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program)

View File

@ -0,0 +1,19 @@
% To run tests:
% erl -make
% erl -noshell -eval "eunit:test(hello_world, [verbose])" -s init stop
%
-module(hello_world_tests).
-include_lib("eunit/include/eunit.hrl").
no_name_test() ->
?assertEqual("Hello, World!", hello_world:greet()).
alice_test() ->
?assertEqual("Hello, Alice!", hello_world:greet("Alice")).
bob_test() ->
?assertEqual("Hello, Bob!", hello_world:greet("Bob")).
strange_test() ->
?assertEqual("Hello, !", hello_world:greet("")).

29
erlang/leap/README.md Normal file
View File

@ -0,0 +1,29 @@
# Leap
Write a program that will take a year and report if it is a leap year.
The tricky thing here is that a leap year 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
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 [view source](http://www.javaranch.com/leap.jsp)

View File

@ -0,0 +1,20 @@
% To run tests:
% erl -make
% erl -noshell -eval "eunit:test(leap, [verbose])" -s init stop
%
-module(leap_tests).
-include_lib("eunit/include/eunit.hrl").
leap_year_test() ->
?assert(leap:leap_year(1996)).
non_leap_year_test() ->
?assertNot(leap:leap_year(1997)).
century_test() ->
?assertNot(leap:leap_year(1900)).
fourth_century_test() ->
?assert(leap:leap_year(2400)).

1
fsharp/current Symbolic link
View File

@ -0,0 +1 @@
sum-of-multiples

View File

@ -0,0 +1,16 @@
# Sum Of Multiples
Write a program that, given a number, can find the sum of all the multiples of particular numbers up to but not including that number.
If we list all the natural numbers up to but not including 15 that are
multiples of either 3 or 5, we get 3, 5, 6 and 9, 10, and 12.
The sum of these multiples is 45.
Write a program that can find the sum of the multiples of a given set of
numbers.
## Source
A variation on Problem 1 at Project Euler [view source](http://projecteuler.net/problem=1)

View File

@ -0,0 +1,32 @@
module SumOfMultiplesTest
open NUnit.Framework
open SumOfMultiples
[<TestFixture>]
type SumOfMultiplesTest() =
let mutable sumOfMultiples = SumOfMultiples()
[<Test>]
member tc.Sum_to_1() =
Assert.That(sumOfMultiples.To(0), Is.EqualTo(0))
[<Test>]
[<Ignore>]
member tc.Sum_to_3() =
Assert.That(sumOfMultiples.To(3), Is.EqualTo(0))
[<Test>]
[<Ignore>]
member tc.Sum_to_10() =
Assert.That(sumOfMultiples.To(10), Is.EqualTo(23))
[<Test>]
[<Ignore>]
member tc.Configurable_7_13_17_to_20() =
Assert.That(SumOfMultiples([7; 13; 17]).To(20), Is.EqualTo(51))
[<Test>]
[<Ignore>]
member tc.Configurable_43_47_to_10000() =
Assert.That(SumOfMultiples([43; 47]).To(10000), Is.EqualTo(2203160))

39
go/allergies/README.md Normal file
View File

@ -0,0 +1,39 @@
# Allergies
Write a program that, given a person's allergy score, can tell them whether or not they're allergic to a given item, and their full list of allergies.
An allergy test produces a single numeric score which contains the
information about all the allergies the person has (that they were
tested for).
The list of items (and their value) that were tested are:
* eggs (1)
* peanuts (2)
* shellfish (4)
* strawberries (8)
* tomatoes (16)
* chocolate (32)
* pollen (64)
* cats (128)
So if Tom is allergic to peanuts and chocolate, he gets a score of 34.
Now, given just that score of 34, your program should be able to say:
- Whether Tom is allergic to any one of those allergens listed above.
- All the allergens Tom is allergic to.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://exercism.io/languages/go).
## Source
Jumpstart Lab Warm-up [view source](http://jumpstartlab.com)

44
go/allergies/allergies.go Normal file
View File

@ -0,0 +1,44 @@
package allergies
// Allergies takes a score and returns all of the
// things that the score is allergic to.
func Allergies(score int) []string {
var ret []string
for _, v := range getAllAllergens() {
if AllergicTo(score, v) {
ret = append(ret, v)
}
}
return ret
}
// AllergicTo takes a score and an allergen and returns if
// That score is allergic to that thing.
func AllergicTo(score int, tst string) bool {
return score&getScoreForAllergen(tst) == getScoreForAllergen(tst)
}
func getAllAllergens() []string {
return []string{
"eggs",
"peanuts",
"shellfish",
"strawberries",
"tomatoes",
"chocolate",
"pollen",
"cats",
}
}
func getScoreForAllergen(tst string) int {
ret := 1
for _, v := range getAllAllergens() {
if tst == v {
return ret
}
ret *= 2
}
return -1
}

View File

@ -0,0 +1,79 @@
package allergies
import (
"fmt"
"testing"
)
var allergiesTests = []struct {
expected []string
input int
}{
{[]string{}, 0},
{[]string{"eggs"}, 1},
{[]string{"peanuts"}, 2},
{[]string{"strawberries"}, 8},
{[]string{"eggs", "peanuts"}, 3},
{[]string{"eggs", "shellfish"}, 5},
{[]string{"strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 248},
{[]string{"eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 255},
{[]string{"eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 509},
}
func TestAllergies(t *testing.T) {
for _, test := range allergiesTests {
actual := Allergies(test.input)
if fmt.Sprintf("%s", actual) != fmt.Sprintf("%s", test.expected) {
t.Fatalf("FAIL: Allergies(%d): expected %s, actual %s", test.input, test.expected, actual)
} else {
t.Logf("PASS: Allergic to %v", test.expected)
}
}
}
func BenchmarkAllergies(b *testing.B) {
b.StopTimer()
for _, test := range allergicToTests {
b.StartTimer()
for i := 0; i < b.N; i++ {
Allergies(test.i)
}
b.StopTimer()
}
}
var allergicToTests = []struct {
expected bool
i int
allergen string
}{
{false, 0, "peanuts"},
{false, 0, "cats"},
{false, 0, "strawberries"},
{true, 1, "eggs"},
{true, 5, "eggs"},
}
func TestAllergicTo(t *testing.T) {
for _, test := range allergicToTests {
actual := AllergicTo(test.i, test.allergen)
if actual != test.expected {
t.Fatalf("FAIL: AllergicTo(%d, %s): expected %t, actual %t", test.i, test.allergen, test.expected, actual)
} else {
t.Logf("PASS: AllergicTo(%d, %s) %t", test.i, test.allergen, actual)
}
}
}
func BenchmarkAllergicTo(b *testing.B) {
b.StopTimer()
for _, test := range allergicToTests {
b.StartTimer()
for i := 0; i < b.N; i++ {
AllergicTo(test.i, test.allergen)
}
b.StopTimer()
}
}

21
go/anagram/README.md Normal file
View File

@ -0,0 +1,21 @@
# Anagram
Write a program that, given a word and a list of possible anagrams, selects the correct sublist.
Given `"listen"` and a list of candidates like `"enlists" "google"
"inlets" "banana"` the program should return a list containing
`"inlets"`.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://exercism.io/languages/go).
## Source
Inspired by the Extreme Startup game [view source](https://github.com/rchatley/extreme_startup)

28
go/anagram/anagram.go Normal file
View File

@ -0,0 +1,28 @@
package anagram
import "strings"
// Detect returns all candidates that are anagrams of subject
func Detect(subject string, candidates []string) []string {
var ret []string
for i := range candidates {
if isAnagram(subject, candidates[i]) {
ret = append(ret, strings.ToLower(candidates[i]))
}
}
return ret
}
func isAnagram(s, c string) bool {
s = strings.ToLower(s)
c = strings.ToLower(c)
if s == c || len(s) != len(c) {
return false
}
for _, v := range strings.Split(s, "") {
if strings.Count(s, v) != strings.Count(c, v) {
return false
}
}
return true
}

172
go/anagram/anagram_test.go Normal file
View File

@ -0,0 +1,172 @@
package anagram
import (
"fmt"
"sort"
"testing"
)
var testCases = []struct {
subject string
candidates []string
expected []string
description string
}{
{
subject: "diaper",
candidates: []string{
"hello",
"world",
"zombies",
"pants",
},
expected: []string{},
description: "no matches",
},
{
subject: "ant",
candidates: []string{
"tan",
"stand",
"at",
},
expected: []string{"tan"},
description: "simple anagram",
},
{
subject: "listen",
candidates: []string{
"enlists",
"google",
"inlets",
"banana",
},
expected: []string{"inlets"},
description: "another simple anagram",
},
{
subject: "master",
candidates: []string{
"stream",
"pigeon",
"maters",
},
expected: []string{"maters", "stream"},
description: "multiple anagrams",
},
{
subject: "allergy",
candidates: []string{
"gallery",
"ballerina",
"regally",
"clergy",
"largely",
"leading",
},
expected: []string{"gallery", "largely", "regally"},
description: "multiple anagrams (again)",
},
{
subject: "galea",
candidates: []string{
"eagle",
},
expected: []string{},
description: "does not confuse different duplicates",
},
{
subject: "corn",
candidates: []string{
"corn",
"dark",
"Corn",
"rank",
"CORN",
"cron",
"park",
},
expected: []string{"cron"},
description: "identical word is not anagram",
},
{
subject: "mass",
candidates: []string{
"last",
},
expected: []string{},
description: "eliminate anagrams with same checksum",
},
{
subject: "good",
candidates: []string{
"dog",
"goody",
},
expected: []string{},
description: "eliminate anagram subsets",
},
{
subject: "Orchestra",
candidates: []string{
"cashregiser",
"carthorse",
"radishes",
},
expected: []string{"carthorse"},
description: "subjects are case insensitive",
},
{
subject: "orchestra",
candidates: []string{
"cashregiser",
"Carthorse",
"radishes",
},
expected: []string{"carthorse"},
description: "candidates are case insensitive",
},
}
func equal(a []string, b []string) bool {
if len(b) != len(a) {
return false
}
sort.Strings(a)
sort.Strings(b)
return fmt.Sprintf("%v", a) == fmt.Sprintf("%v", b)
}
func TestDetectAnagrams(t *testing.T) {
for _, tt := range testCases {
actual := Detect(tt.subject, tt.candidates)
if !equal(tt.expected, actual) {
msg := `FAIL: %s
Subject %s
Candidates %v
Expected %v
Got %v
`
t.Fatalf(msg, tt.description, tt.subject, tt.candidates, tt.expected, actual)
} else {
t.Logf("PASS: %s", tt.description)
}
}
}
func BenchmarkDetectAnagrams(b *testing.B) {
b.StopTimer()
for _, tt := range testCases {
b.StartTimer()
for i := 0; i < b.N; i++ {
Detect(tt.subject, tt.candidates)
}
b.StopTimer()
}
}

40
go/bank-account/README.md Normal file
View File

@ -0,0 +1,40 @@
# Bank Account
Bank accounts can be accessed in different ways at the same time.
A bank account can be accessed in multiple ways. Clients can make
deposits and withdrawals using the internet, mobile phones, etc. Shops
can charge against the account.
Create an account that can be accessed from multiple threads/processes
(terminology depends on your programming language).
It should be possible to close an account; operations against a closed
account must fail.
## Instructions
Run the test file, and fix each of the errors in turn. When you get the
first test to pass, go to the first pending or skipped test, and make
that pass as well. When all of the tests are passing, feel free to
submit.
Remember that passing code is just the first step. The goal is to work
towards a solution that is as readable and expressive as you can make
it.
Have fun!
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
[view source]()

View File

@ -0,0 +1,58 @@
package account
import "sync"
// Account just represents a user's account
type Account struct {
sync.RWMutex
balance int
closed bool
}
// Open returns a new account
func Open(amt int) *Account {
a := new(Account)
_, ok := a.Deposit(amt)
if ok {
return a
}
return nil
}
// Close returns the payout amount and an 'ok' flag
func (a *Account) Close() (int, bool) {
a.Lock()
ret := a.balance
if a.closed {
a.Unlock()
return 0, false
}
a.closed = true
a.balance = 0
a.Unlock()
return ret, true
}
// Balance returns the current account balance
// and an 'ok' flag
func (a *Account) Balance() (int, bool) {
if a.closed {
return 0, false
}
return a.balance, true
}
// Deposit takes an amount (can be a withdrawal)
// and returns the new balance and an 'ok' flag
func (a *Account) Deposit(amount int) (int, bool) {
var ret int
var ok bool
a.Lock()
if !a.closed && a.balance+amount >= 0 {
a.balance += amount
ret = a.balance
ok = true
}
a.Unlock()
return ret, ok
}

View File

@ -0,0 +1,289 @@
// API:
//
// Open(initalDeposit int64) *Account
// (Account) Close() (payout int64, ok bool)
// (Account) Balance() (balance int64, ok bool)
// (Account) Deposit(amount uint64) (newBalance int64, ok bool)
//
// If Open is given a negative initial deposit, it must return nil.
// Deposit must handle a negative amount as a withdrawal.
// If any Account method is called on an closed account, it must not modify
// the account and must return ok = false.
package account
import (
"runtime"
"sync"
"sync/atomic"
"testing"
"time"
)
func TestSeqOpenBalanceClose(t *testing.T) {
// open account
const amt = 10
a := Open(amt)
if a == nil {
t.Fatalf("Open(%d) = nil, want non-nil *Account.", amt)
}
t.Logf("Account 'a' opened with initial balance of %d.", amt)
// verify balance after open
switch b, ok := a.Balance(); {
case !ok:
t.Fatal("a.Balance() returned !ok, want ok.")
case b != amt:
t.Fatalf("a.Balance() = %d, want %d", b, amt)
}
// close account
switch p, ok := a.Close(); {
case !ok:
t.Fatalf("a.Close() returned !ok, want ok.")
case p != amt:
t.Fatalf("a.Close() returned payout = %d, want %d.", p, amt)
}
t.Log("Account 'a' closed.")
// verify balance no longer accessible
if b, ok := a.Balance(); ok {
t.Log("Balance still available on closed account.")
t.Fatalf("a.Balance() = %d, %t. Want ok == false", b, ok)
}
}
func TestSeqOpenDepositClose(t *testing.T) {
// open account
const openAmt = 10
a := Open(openAmt)
if a == nil {
t.Fatalf("Open(%d) = nil, want non-nil *Account.", openAmt)
}
t.Logf("Account 'a' opened with initial balance of %d.", openAmt)
// deposit
const depAmt = 20
const newAmt = openAmt + depAmt
switch b, ok := a.Deposit(depAmt); {
case !ok:
t.Fatalf("a.Deposit(%d) returned !ok, want ok.", depAmt)
case b != openAmt+depAmt:
t.Fatalf("a.Deposit(%d) = %d, want new balance = %d", depAmt, b, newAmt)
}
t.Logf("Deposit of %d accepted to account 'a'", depAmt)
// close account
switch p, ok := a.Close(); {
case !ok:
t.Fatalf("a.Close() returned !ok, want ok.")
case p != newAmt:
t.Fatalf("a.Close() returned payout = %d, want %d.", p, newAmt)
}
t.Log("Account 'a' closed.")
// verify deposits no longer accepted
if b, ok := a.Deposit(1); ok {
t.Log("Deposit accepted on closed account.")
t.Fatalf("a.Deposit(1) = %d, %t. Want ok == false", b, ok)
}
}
func TestMoreSeqCases(t *testing.T) {
// open account 'a' as before
const openAmt = 10
a := Open(openAmt)
if a == nil {
t.Fatalf("Open(%d) = nil, want non-nil *Account.", openAmt)
}
t.Logf("Account 'a' opened with initial balance of %d.", openAmt)
// open account 'z' with zero balance
z := Open(0)
if z == nil {
t.Fatal("Open(0) = nil, want non-nil *Account.")
}
t.Log("Account 'z' opened with initial balance of 0.")
// attempt to open account with negative opening balance
if Open(-10) != nil {
t.Fatal("Open(-10) seemed to work, " +
"want nil result for negative opening balance.")
}
// verify both balances a and z still there
switch b, ok := a.Balance(); {
case !ok:
t.Fatal("a.Balance() returned !ok, want ok.")
case b != openAmt:
t.Fatalf("a.Balance() = %d, want %d", b, openAmt)
}
switch b, ok := z.Balance(); {
case !ok:
t.Fatal("z.Balance() returned !ok, want ok.")
case b != 0:
t.Fatalf("z.Balance() = %d, want 0", b)
}
// withdrawals
const wAmt = 3
const newAmt = openAmt - wAmt
switch b, ok := a.Deposit(-wAmt); {
case !ok:
t.Fatalf("a.Deposit(%d) returned !ok, want ok.", -wAmt)
case b != newAmt:
t.Fatalf("a.Deposit(%d) = %d, want new balance = %d", -wAmt, b, newAmt)
}
t.Logf("Withdrawal of %d accepted from account 'a'", wAmt)
if _, ok := z.Deposit(-1); ok {
t.Fatal("z.Deposit(-1) returned ok, want !ok.")
}
// verify both balances
switch b, ok := a.Balance(); {
case !ok:
t.Fatal("a.Balance() returned !ok, want ok.")
case b != newAmt:
t.Fatalf("a.Balance() = %d, want %d", b, newAmt)
}
switch b, ok := z.Balance(); {
case !ok:
t.Fatal("z.Balance() returned !ok, want ok.")
case b != 0:
t.Fatalf("z.Balance() = %d, want 0", b)
}
// close just z
switch p, ok := z.Close(); {
case !ok:
t.Fatalf("z.Close() returned !ok, want ok.")
case p != 0:
t.Fatalf("z.Close() returned payout = %d, want 0.", p)
}
t.Log("Account 'z' closed.")
// verify 'a' balance one more time
switch b, ok := a.Balance(); {
case !ok:
t.Fatal("a.Balance() returned !ok, want ok.")
case b != newAmt:
t.Fatalf("a.Balance() = %d, want %d", b, newAmt)
}
}
func TestConcClose(t *testing.T) {
if runtime.NumCPU() < 2 {
t.Skip("Multiple CPU cores required for concurrency tests.")
}
if runtime.GOMAXPROCS(0) < 2 {
runtime.GOMAXPROCS(2)
}
// test competing close attempts
for rep := 0; rep < 1000; rep++ {
const openAmt = 10
a := Open(openAmt)
if a == nil {
t.Fatalf("Open(%d) = nil, want non-nil *Account.", openAmt)
}
var start sync.WaitGroup
start.Add(1)
const closeAttempts = 10
res := make(chan string)
for i := 0; i < closeAttempts; i++ {
go func() { // on your mark,
start.Wait() // get set...
switch p, ok := a.Close(); {
case !ok:
if p != 0 {
t.Errorf("a.Close() = %d, %t. "+
"Want payout = 0 for unsuccessful close", p, ok)
res <- "fail"
} else {
res <- "already closed"
}
case p != openAmt:
t.Errorf("a.Close() = %d, %t. "+
"Want payout = %d for successful close", p, ok, openAmt)
res <- "fail"
default:
res <- "close" // exactly one goroutine should reach here
}
}()
}
start.Done() // ...go
var closes, fails int
for i := 0; i < closeAttempts; i++ {
switch <-res {
case "close":
closes++
case "fail":
fails++
}
}
switch {
case fails > 0:
t.FailNow() // error already logged by other goroutine
case closes == 0:
t.Fatal("Concurrent a.Close() attempts all failed. " +
"Want one to succeed.")
case closes > 1:
t.Fatalf("%d concurrent a.Close() attempts succeeded, "+
"each paying out %d!. Want just one to succeed.",
closes, openAmt)
}
}
}
func TestConcDeposit(t *testing.T) {
if runtime.NumCPU() < 2 {
t.Skip("Multiple CPU cores required for concurrency tests.")
}
if runtime.GOMAXPROCS(0) < 2 {
runtime.GOMAXPROCS(2)
}
a := Open(0)
if a == nil {
t.Fatal("Open(0) = nil, want non-nil *Account.")
}
const amt = 10
const c = 1000
var negBal int32
var start, g sync.WaitGroup
start.Add(1)
g.Add(3 * c)
for i := 0; i < c; i++ {
go func() { // deposit
start.Wait()
a.Deposit(amt) // ignore return values
g.Done()
}()
go func() { // withdraw
start.Wait()
for {
if _, ok := a.Deposit(-amt); ok {
break
}
time.Sleep(time.Microsecond) // retry
}
g.Done()
}()
go func() { // watch that balance stays >= 0
start.Wait()
if p, _ := a.Balance(); p < 0 {
atomic.StoreInt32(&negBal, 1)
}
g.Done()
}()
}
start.Done()
g.Wait()
if negBal == 1 {
t.Fatal("Balance went negative with concurrent deposits and " +
"withdrawals. Want balance always >= 0.")
}
if p, ok := a.Balance(); !ok || p != 0 {
t.Fatalf("After equal concurrent deposits and withdrawals, "+
"a.Balance = %d, %t. Want 0, true", p, ok)
}
}

43
go/binary/README.md Normal file
View File

@ -0,0 +1,43 @@
# Binary
Write a program that will convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles
Implement binary to decimal conversion. Given a binary input
string, your program should produce a decimal output. The
program should handle invalid inputs.
## Note
- Implement the conversion yourself.
Do not use something else to perform the conversion for you.
## About Binary (Base-2)
Decimal is a base-10 system.
A number 23 in base 10 notation can be understood
as a linear combination of powers of 10:
- The rightmost digit gets multiplied by 10^0 = 1
- The next number gets multiplied by 10^1 = 10
- ...
- The *n*th number gets multiplied by 10^*(n-1)*.
- All these values are summed.
So: `23 => 2*10^1 + 3*10^0 => 2*10 + 3*1 = 23 base 10`
Binary is similar, but uses powers of 2 rather than powers of 10.
So: `101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10`.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://exercism.io/languages/go).
## Source
All of Computer Science [view source](http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-)

22
go/binary/binary.go Normal file
View File

@ -0,0 +1,22 @@
package binary
import "fmt"
// ParseBinary takes a binary string and returns the
// integer representation of it.
func ParseBinary(bin string) (int, error) {
var ret int
currSpot := 1
for len(bin) > 0 {
v := bin[len(bin)-1]
if v != '0' && v != '1' {
return 0, fmt.Errorf("Invalid String")
}
if v == '1' {
ret = ret + currSpot
}
currSpot = currSpot * 2
bin = bin[:len(bin)-1]
}
return ret, nil
}

55
go/binary/binary_test.go Normal file
View File

@ -0,0 +1,55 @@
package binary
import (
"testing"
)
// You must implement the function,
//
// func ParseBinary(string) (int, error)
//
// It is standard for Go functions to return error values to report error conditions.
// The test cases below are all valid binary numbers however. For this exercise you
// may simply return nil for the error value in all cases.
//
// For bonus points though, what errors might be possible when parsing a number?
// Can you add code to detect error conditions and return appropriate error values?
var testCases = []struct {
binary string
expected int
}{
{"1", 1},
{"10", 2},
{"11", 3},
{"100", 4},
{"1001", 9},
{"11010", 26},
{"10001101000", 1128},
{"0", 0},
}
func TestParseBinary(t *testing.T) {
for _, tt := range testCases {
actual, err := ParseBinary(tt.binary)
// We don't expect errors for any of the test cases.
if err != nil {
t.Fatalf("ParseBinary(%v) returned error %q. Error not expected.",
tt.binary, err)
}
// Well, we don't expect wrong answers either.
if actual != tt.expected {
t.Fatalf("ParseBinary(%v): actual %d, expected %v",
tt.binary, actual, tt.expected)
}
}
}
// Benchmark combined time for all tests
func BenchmarkBinary(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tt := range testCases {
ParseBinary(tt.binary)
}
}
}

44
go/bob/README.md Normal file
View File

@ -0,0 +1,44 @@
# 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 says 'Fine. Be that way!' if you address him without actually saying
anything.
He answers 'Whatever.' to anything else.
## Instructions
Run the test file, and fix each of the errors in turn. When you get the
first test to pass, go to the first pending or skipped test, and make
that pass as well. When all of the tests are passing, feel free to
submit.
Remember that passing code is just the first step. The goal is to work
towards a solution that is as readable and expressive as you can make
it.
Please make your solution as general as possible. Good code doesn't just
pass the test suite, it works with any input that fits the
specification.
Have fun!
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://exercism.io/languages/go).
## Source
Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=06)

19
go/bob/bob.go Normal file
View File

@ -0,0 +1,19 @@
package bob
import "strings"
// TestVersion is an exercism thing
const TestVersion = 1
// Hey provokes a response from Bob
func Hey(inp string) string {
inp = strings.TrimSpace(inp)
if inp == "" {
return "Fine. Be that way!"
} else if inp == strings.ToUpper(inp) && inp != strings.ToLower(inp) {
return "Whoa, chill out!"
} else if strings.HasSuffix(inp, "?") {
return "Sure."
}
return "Whatever."
}

33
go/bob/bob_test.go Normal file
View File

@ -0,0 +1,33 @@
package bob
import "testing"
const testVersion = 1
// Retired testVersions
// (none) 4a9e144a3c5dc0d9773f4cf641ffe3efe48641d8
func TestHeyBob(t *testing.T) {
if TestVersion != testVersion {
t.Fatalf("Found TestVersion = %v, want %v", TestVersion, testVersion)
}
for _, tt := range testCases {
actual := Hey(tt.input)
if actual != tt.expected {
msg := `
ALICE (%s): %q
BOB: %s
Expected Bob to respond: %s`
t.Fatalf(msg, tt.description, tt.input, actual, tt.expected)
}
}
}
func BenchmarkBob(b *testing.B) {
for _, tt := range testCases {
for i := 0; i < b.N; i++ {
Hey(tt.input)
}
}
}

141
go/bob/cases_test.go Normal file
View File

@ -0,0 +1,141 @@
package bob
// Source: exercism/x-common
// Commit: 945d08e Merge pull request #50 from soniakeys/master
var testCases = []struct {
description string
input string
expected string
}{
{
"stating something",
"Tom-ay-to, tom-aaaah-to.",
"Whatever.",
},
{
"shouting",
"WATCH OUT!",
"Whoa, chill out!",
},
{
"shouting gibberish",
"FCECDFCAAB",
"Whoa, chill out!",
},
{
"asking a question",
"Does this cryogenic chamber make me look fat?",
"Sure.",
},
{
"asking a numeric question",
"You are, what, like 15?",
"Sure.",
},
{
"asking gibberish",
"fffbbcbeab?",
"Sure.",
},
{
"talking forcefully",
"Let's go make out behind the gym!",
"Whatever.",
},
{
"using acronyms in regular speech",
"It's OK if you don't want to go to the DMV.",
"Whatever.",
},
{
"forceful question",
"WHAT THE HELL WERE YOU THINKING?",
"Whoa, chill out!",
},
{
"shouting numbers",
"1, 2, 3 GO!",
"Whoa, chill out!",
},
{
"only numbers",
"1, 2, 3",
"Whatever.",
},
{
"question with only numbers",
"4?",
"Sure.",
},
{
"shouting with special characters",
"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!",
"Whoa, chill out!",
},
{
"shouting with umlauts",
"ÜMLÄÜTS!",
"Whoa, chill out!",
},
{
"calmly speaking with umlauts",
"ÜMLäÜTS!",
"Whatever.",
},
{
"shouting with no exclamation mark",
"I HATE YOU",
"Whoa, chill out!",
},
{
"statement containing question mark",
"Ending with ? means a question.",
"Whatever.",
},
{
"non-letters with question",
":) ?",
"Sure.",
},
{
"prattling on",
"Wait! Hang on. Are you going to be OK?",
"Sure.",
},
{
"silence",
"",
"Fine. Be that way!",
},
{
"prolonged silence",
" ",
"Fine. Be that way!",
},
{
"alternate silence",
"\t\t\t\t\t\t\t\t\t\t",
"Fine. Be that way!",
},
{
"multiple line question",
"\nDoes this cryogenic chamber make me look fat?\nno",
"Whatever.",
},
{
"starting with whitespace",
" hmmmmmmm...",
"Whatever.",
},
{
"ending with whitespace",
"Okay if like my spacebar quite a bit? ",
"Sure.",
},
{
"other whitespace",
"\n\r \t\v\u00a0\u2002",
"Fine. Be that way!",
},
}

20
go/bracket-push/README.md Normal file
View File

@ -0,0 +1,20 @@
# Bracket Push
Make sure the brackets and braces all match.
Ensure that all the brackets and braces are matched correctly,
and nested correctly.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
Ginna Baker [view source]()

View File

@ -0,0 +1,26 @@
package bracket_push
// Bracket makes sure that all brackets match
func Bracket(s string) (bool, error) {
// Set up a map of matches that we care about
matches := make(map[byte]byte)
matches['}'] = '{'
matches[')'] = '('
matches[']'] = '['
var pairs []byte
for i := range s {
if v, ok := matches[s[i]]; ok {
// Found a match, it's a closing bracket
if len(pairs) == 0 || pairs[len(pairs)-1] != v {
return false, nil
}
pairs = pairs[:len(pairs)-1]
} else {
pairs = append(pairs, s[i])
}
}
if len(pairs) > 0 {
return false, nil
}
return true, nil
}

View File

@ -0,0 +1,72 @@
package bracket_push
import (
"testing"
)
var testCases = []struct {
input string
expected bool
}{
{
input: "",
expected: true,
},
{
input: "{}",
expected: true,
},
{
input: "{{",
expected: false,
},
{
input: "}{",
expected: false,
},
{
input: "{}[]",
expected: true,
},
{
input: "{[]}",
expected: true,
},
{
input: "{[}]",
expected: false,
},
{
input: "{[)][]}",
expected: false,
},
{
input: "{[]([()])}",
expected: true,
},
}
func TestBracket(t *testing.T) {
for _, tt := range testCases {
actual, err := Bracket(tt.input)
// We don't expect errors for any of the test cases
if err != nil {
t.Fatalf("Bracket(%q) returned error %q. Error not expected.", tt.input, err)
}
if actual != tt.expected {
t.Fatalf("Bracket(%q) was expected to return %v but returned %v.",
tt.input, tt.expected, actual)
}
}
}
func BenchmarkBracket(b *testing.B) {
b.StopTimer()
for _, tt := range testCases {
b.StartTimer()
for i := 0; i < b.N; i++ {
Bracket(tt.input)
}
b.StopTimer()
}
}

View File

@ -0,0 +1,77 @@
package brackets
import (
"testing"
)
const testVersion = 2
var testCases = []struct {
input string
expected bool
}{
{
input: "",
expected: true,
},
{
input: "{}",
expected: true,
},
{
input: "{{",
expected: false,
},
{
input: "}{",
expected: false,
},
{
input: "{}[]",
expected: true,
},
{
input: "{[]}",
expected: true,
},
{
input: "{[}]",
expected: false,
},
{
input: "{[)][]}",
expected: false,
},
{
input: "{[]([()])}",
expected: true,
},
}
func TestBracket(t *testing.T) {
for _, tt := range testCases {
actual, err := Bracket(tt.input)
// We don't expect errors for any of the test cases
if err != nil {
t.Fatalf("Bracket(%q) returned error %q. Error not expected.", tt.input, err)
}
if actual != tt.expected {
t.Fatalf("Bracket(%q) was expected to return %v but returned %v.",
tt.input, tt.expected, actual)
}
}
if TestVersion != testVersion {
t.Fatalf("Found TestVersion = %v, want %v.", TestVersion, testVersion)
}
}
func BenchmarkBracket(b *testing.B) {
b.StopTimer()
for _, tt := range testCases {
b.StartTimer()
for i := 0; i < b.N; i++ {
Bracket(tt.input)
}
b.StopTimer()
}
}

23
go/clock/README.md Normal file
View File

@ -0,0 +1,23 @@
# Clock
Implement a clock that handles times without dates.
Create a clock that is independent of date.
You should be able to add and subtract minutes to it.
Two clocks that represent the same time should be equal to each other.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
Pairing session with Erin Drummond [view source](https://twitter.com/ebdrummond)

78
go/clock/cases_test.go Normal file
View File

@ -0,0 +1,78 @@
package clock
// Source: exercism/x-common
// Commit: 269f498 Merge pull request #48 from soniakeys/custom-set-json
// Test creating a new clock with an initial time.
var timeTests = []struct {
h, m int
want string
}{
{8, 0, "08:00"}, // on the hour
{9, 0, "09:00"}, // on the hour
{11, 9, "11:09"}, // past the hour
{11, 19, "11:19"}, // past the hour
{24, 0, "00:00"}, // midnight is zero hours
{25, 0, "01:00"}, // hour rolls over
{1, 60, "02:00"}, // sixty minutes is next hour
{0, 160, "02:40"}, // minutes roll over
{25, 160, "03:40"}, // hour and minutes roll over
{-1, 15, "23:15"}, // negative hour
{-25, 0, "23:00"}, // negative hour rolls over
{1, -40, "00:20"}, // negative minutes
{1, -160, "22:20"}, // negative minutes roll over
{-25, -160, "20:20"}, // negative hour and minutes both roll over
}
// Test adding and subtracting minutes.
var addTests = []struct {
h, m, a int
want string
}{
{10, 0, 3, "10:03"}, // add minutes
{0, 45, 40, "01:25"}, // add to next hour
{10, 0, 61, "11:01"}, // add more than one hour
{23, 59, 2, "00:01"}, // add across midnight
{5, 32, 1500, "06:32"}, // add more than one day (1500 min = 25 hrs)
{0, 45, 160, "03:25"}, // add more than two hours with carry
{10, 3, -3, "10:00"}, // subtract minutes
{10, 3, -30, "09:33"}, // subtract to previous hour
{10, 3, -70, "08:53"}, // subtract more than an hour
{0, 3, -4, "23:59"}, // subtract across midnight
{0, 0, -160, "21:20"}, // subtract more than two hours
{5, 32, -1500, "04:32"}, // subtract more than one day (1500 min = 25 hrs)
{6, 15, -160, "03:35"}, // subtract more than two hours with borrow
}
// Construct two separate clocks, set times, test if they are equal.
type hm struct{ h, m int }
var eqTests = []struct {
c1, c2 hm
want bool
}{
// clocks with same time
{
hm{15, 37},
hm{15, 37},
true,
},
// clocks a minute apart
{
hm{15, 36},
hm{15, 37},
false,
},
// clocks an hour apart
{
hm{14, 37},
hm{15, 37},
false,
},
// clocks set 24 hours apart
{
hm{10, 37},
hm{34, 37},
true,
},
}

34
go/clock/clock.go Normal file
View File

@ -0,0 +1,34 @@
package clock
import "fmt"
// TestVersion is for exercism
const TestVersion = 2
// Clock is an int representing the time of day
type Clock int
// Time returns a Clock representing the given hour & minute
func Time(hour, minute int) Clock {
return TimeFromMinutes(hour*60 + minute)
}
// String returns a string representation of Clock
func (c Clock) String() string {
return fmt.Sprintf("%02d:%02d", c/60, c%60)
}
// Add adds minutes to the clock
func (c Clock) Add(minutes int) Clock {
return TimeFromMinutes(int(c) + minutes)
}
// TimeFromMinutes takes a minutes integer value and returns a Clock
func TimeFromMinutes(minutes int) Clock {
for minutes < 0 {
// Keep adding 24 hours to the minutes value until it's positive
minutes = minutes + (24 * 60)
}
minutes = minutes % (24 * 60)
return Clock(minutes)
}

69
go/clock/clock_test.go Normal file
View File

@ -0,0 +1,69 @@
package clock
import (
"reflect"
"testing"
)
// Clock type API:
//
// Time(hour, minute int) Clock // a "constructor"
// (Clock) String() string // a "stringer"
// (Clock) Add(minutes int) Clock
//
// Add should also handle subtraction by accepting negative values.
// To satisfy the readme requirement about clocks being equal, values of
// your Clock type need to work with the == operator.
//
// It might help to study the time.Time type in the standard library
// (https://golang.org/pkg/time/#Time) as a model. See how constructors there
// (Date and Now) return Time values rather than pointers. Note also how
// most time.Time methods have value receivers rather that pointer recievers.
// For more background on this read
// https://github.com/golang/go/wiki/CodeReviewComments#receiver-type.
const testVersion = 2
// Retired testVersions
// (none) 79937f6d58e25ebafe12d1cb4a9f88f4de70cfd6
// 1 8d0cb8b617be2e36b2ca5ad2034e5f80f2372924
func TestCreateClock(t *testing.T) {
if TestVersion != testVersion {
t.Fatalf("Found TestVersion = %v, want %v", TestVersion, testVersion)
}
for _, n := range timeTests {
if got := Time(n.h, n.m); got.String() != n.want {
t.Fatalf("Time(%d, %d) = %q, want %q", n.h, n.m, got, n.want)
}
}
t.Log(len(timeTests), "test cases")
}
func TestAddMinutes(t *testing.T) {
for _, a := range addTests {
if got := Time(a.h, a.m).Add(a.a); got.String() != a.want {
t.Fatalf("Time(%d, %d).Add(%d) = %q, want %q",
a.h, a.m, a.a, got, a.want)
}
}
t.Log(len(addTests), "test cases")
}
func TestCompareClocks(t *testing.T) {
for _, e := range eqTests {
clock1 := Time(e.c1.h, e.c1.m)
clock2 := Time(e.c2.h, e.c2.m)
got := clock1 == clock2
if got != e.want {
t.Log("Clock1:", clock1)
t.Log("Clock2:", clock2)
t.Logf("Clock1 == Clock2 is %t, want %t", got, e.want)
if reflect.DeepEqual(clock1, clock2) {
t.Log("(Hint: see comments in clock_test.go.)")
}
t.FailNow()
}
}
t.Log(len(eqTests), "test cases")
}

View File

@ -0,0 +1,87 @@
# Crypto Square
Implement the classic method for composing secret messages called a square code.
The input is first normalized: The spaces and punctuation are removed
from the English text and the message is downcased.
Then, the normalized characters are broken into rows. These rows can be
regarded as forming a rectangle when printed with intervening newlines.
For example, the sentence
> If man was meant to stay on the ground god would have given us roots
is 54 characters long.
Broken into 8-character columns, it yields 7 rows.
Those 7 rows produce this rectangle when printed one per line:
```plain
ifmanwas
meanttos
tayonthe
groundgo
dwouldha
vegivenu
sroots
```
The coded message is obtained by reading down the columns going left to
right.
For example, the message above is coded as:
```plain
imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau
```
Write a program that, given an English text, outputs the encoded version
of that text.
The size of the square (number of columns) should be decided by the
length of the message.
If the message is a length that creates a perfect square (e.g. 4, 9, 16,
25, 36, etc), use that number of columns.
If the message doesn't fit neatly into a square, choose the number of
columns that corresponds to the smallest square that is larger than the
number of characters in the message.
For example, a message 4 characters long should use a 2 x 2 square. A
message that is 81 characters long would use a square that is 9 columns
wide.
A message between 5 and 8 characters long should use a rectangle 3
characters wide.
Output the encoded text grouped by column.
For example:
- "Have a nice day. Feed the dog & chill out!"
- Normalizes to: "haveanicedayfeedthedogchillout"
- Which has length: 30
- And splits into 5 6-character rows:
- "havean"
- "iceday"
- "feedth"
- "edogch"
- "illout"
- Which yields a ciphertext beginning: "hifei acedl v…"
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
J Dalbey's Programming Practice problems [view source](http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html)

View File

@ -0,0 +1,45 @@
package cryptosquare
import (
"math"
"regexp"
"strings"
)
// TestVersion is an exercism thing
const TestVersion = 1
// Encode implements the classic method for composing
// secret messages called a square code
func Encode(txt string) string {
r := regexp.MustCompile("[^a-zA-Z0-9]+")
nrm := strings.ToLower(r.ReplaceAllString(txt, ""))
// The string should be normalized now (alphanumeric, lower case)
sqrt := int(math.Ceil(math.Sqrt(float64(len(nrm)))))
var square, ret []string
var tmp string
// Build the initial square
for i := 0; i < len(nrm); i++ {
if i%sqrt == 0 && len(tmp) != 0 {
square = append(square, tmp)
tmp = ""
}
tmp += string(nrm[i])
}
square = append(square, tmp)
tmp = ""
// Now rebuild the string by columns
for i := 0; i < len(square[0]); i++ {
for j := 0; j < len(square); j++ {
if i < len(square[j]) {
tmp += string(square[j][i])
}
}
ret = append(ret, tmp)
tmp = ""
}
return strings.Join(ret, " ")
}

View File

@ -0,0 +1,111 @@
package cryptosquare
import "testing"
const testVersion = 1
// Retired testVersions
// (none) 71ad8ac57fe7d5b777cfa1afd116cd41e1af55ed
var tests = []struct {
pt string // plain text
ct string // cipher text
}{
{
"s#$%^&plunk",
"su pn lk",
},
{
"1, 2, 3 GO!",
"1g 2o 3",
},
{
"1234",
"13 24",
},
{
"123456789",
"147 258 369",
},
{
"123456789abc",
"159 26a 37b 48c",
},
{
"Never vex thine heart with idle woes",
"neewl exhie vtetw ehaho ririe vntds",
},
{
"ZOMG! ZOMBIES!!!",
"zzi ooe mms gb",
},
{
"Time is an illusion. Lunchtime doubly so.",
"tasney inicds miohoo elntu illib suuml",
},
{
"We all know interspecies romance is weird.",
"wneiaw eorene awssci liprer lneoid ktcms",
},
{
"Madness, and then illumination.",
"msemo aanin dnin ndla etlt shui",
},
{
"Vampires are people too!",
"vrel aepe mset paoo irpo",
},
{
"",
"",
},
{
"1",
"1",
},
{
"12",
"1 2",
},
{
"12 3",
"13 2",
},
{
"12345678",
"147 258 36",
},
{
"123456789a",
"159 26a 37 48",
},
{
"If man was meant to stay on the ground god would have given us roots",
"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau",
},
{
"Have a nice day. Feed the dog & chill out!",
"hifei acedl veeol eddgo aatcu nyhht",
},
}
func TestEncode(t *testing.T) {
if TestVersion != testVersion {
t.Errorf("Found TestVersion = %v, want %v.", TestVersion, testVersion)
}
for _, test := range tests {
if ct := Encode(test.pt); ct != test.ct {
t.Fatalf(`Encode(%q):
got %q
want %q`, test.pt, ct, test.ct)
}
}
}
func BenchmarkEncode(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, test := range tests {
Encode(test.pt)
}
}
}

1
go/current Symbolic link
View File

@ -0,0 +1 @@
react

View File

@ -0,0 +1,30 @@
# Difference Of Squares
Find the difference between the sum of the squares and the square of the sums of the first N natural numbers.
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)**2 = 55**2 = 3025
The sum of the squares of the first ten natural numbers is,
1**2 + 2**2 + ... + 10**2 = 385
Hence the difference between the square of the sum of the first
ten natural numbers and the sum of the squares is 2640:
3025 - 385 = 2640
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
Problem 6 at Project Euler [view source](http://projecteuler.net/problem=6)

View File

@ -0,0 +1,32 @@
package diffsquares
import "math"
// SquareOfSums calculates the Square of the sums
// of the first 'num' natural numbers
func SquareOfSums(num int) int {
ret := 0
for num > 0 {
ret += num
num--
}
return int(math.Pow(float64(ret), 2))
}
// SumOfSquares calculates the Sum of the Squares
// of the first 'num' natural numbers
func SumOfSquares(num int) int {
ret := 0
for num > 0 {
ret += int(math.Pow(float64(num), 2))
num--
}
return ret
}
// Difference calculates the difference between
// The SquareOfSums and the SumOfSquares for the
// first 'num' natural numbers
func Difference(num int) int {
return SquareOfSums(num) - SumOfSquares(num)
}

View File

@ -0,0 +1,54 @@
package diffsquares
import "testing"
var tests = []struct{ n, sqOfSums, sumOfSq int }{
{5, 225, 55},
{10, 3025, 385},
{100, 25502500, 338350},
}
func TestSquareOfSums(t *testing.T) {
for _, test := range tests {
if s := SquareOfSums(test.n); s != test.sqOfSums {
t.Fatalf("SquareOfSums(%d) = %d, want %d", test.n, s, test.sqOfSums)
}
}
}
func TestSumOfSquares(t *testing.T) {
for _, test := range tests {
if s := SumOfSquares(test.n); s != test.sumOfSq {
t.Fatalf("SumOfSquares(%d) = %d, want %d", test.n, s, test.sumOfSq)
}
}
}
func TestDifference(t *testing.T) {
for _, test := range tests {
want := test.sqOfSums - test.sumOfSq
if s := Difference(test.n); s != want {
t.Fatalf("Difference(%d) = %d, want %d", test.n, s, want)
}
}
}
// Benchmark functions on just a single number (100, from the original PE problem)
// to avoid overhead of iterating over tests.
func BenchmarkSquareOfSums(b *testing.B) {
for i := 0; i < b.N; i++ {
SquareOfSums(100)
}
}
func BenchmarkSumOfSquares(b *testing.B) {
for i := 0; i < b.N; i++ {
SumOfSquares(100)
}
}
func BenchmarkDifference(b *testing.B) {
for i := 0; i < b.N; i++ {
Difference(100)
}
}

62
go/etl/README.md Normal file
View File

@ -0,0 +1,62 @@
# Etl
We are going to do the `Transform` step of an Extract-Transform-Load.
### ETL
Extract-Transform-Load (ETL) is a fancy way of saying, "We have some crufty, legacy data over in this system, and now we need it in this shiny new system over here, so
we're going to migrate this."
(Typically, this is followed by, "We're only going to need to run this
once." That's then typically followed by much forehead slapping and
moaning about how stupid we could possibly be.)
### The goal
We're going to extract some scrabble scores from a legacy system.
The old system stored a list of letters per score:
- 1 point: "A", "E", "I", "O", "U", "L", "N", "R", "S", "T",
- 2 points: "D", "G",
- 3 points: "B", "C", "M", "P",
- 4 points: "F", "H", "V", "W", "Y",
- 5 points: "K",
- 8 points: "J", "X",
- 10 points: "Q", "Z",
The shiny new scrabble system instead stores the score per letter, which
makes it much faster and easier to calculate the score for a word. It
also stores the letters in lower-case regardless of the case of the
input letters:
- "a" is worth 1 point.
- "b" is worth 3 points.
- "c" is worth 3 points.
- "d" is worth 2 points.
- Etc.
Your mission, should you choose to accept it, is to write a program that
transforms the legacy data format to the shiny new format.
### Notes
Note that both the old and the new system use strings to represent
letters, even in languages that have a separate data type for
characters.
A final note about scoring, Scrabble is played around the world in a
variety of languages, each with its own unique scoring table. For
example, an "A" is scored at 14 in the Basque-language version of the
game while being scored at 9 in the Latin-language version.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
The Jumpstart Lab team [view source](http://jumpstartlab.com)

17
go/etl/etl.go Normal file
View File

@ -0,0 +1,17 @@
package etl
import "strings"
// Transform takes the legacy data structure
// and converts it into the new and improved
// data structure oh man this new system will
// make us so rich you guys.
func Transform(input map[int][]string) map[string]int {
ret := make(map[string]int)
for k, v := range input {
for _, let := range v {
ret[strings.ToLower(let)] = k
}
}
return ret
}

90
go/etl/etl_test.go Normal file
View File

@ -0,0 +1,90 @@
package etl
import "testing"
type given map[int][]string
type expectation map[string]int
var transformTests = []struct {
input given
output expectation
}{
{
given{1: {"A"}},
expectation{"a": 1},
},
{
given{1: {"A", "E", "I", "O", "U"}},
expectation{"a": 1, "e": 1, "i": 1, "o": 1, "u": 1},
},
{
given{
1: {"A", "E"},
2: {"D", "G"},
},
expectation{
"a": 1,
"e": 1,
"d": 2,
"g": 2,
},
},
{
given{
1: {"A", "E", "I", "O", "U", "L", "N", "R", "S", "T"},
2: {"D", "G"},
3: {"B", "C", "M", "P"},
4: {"F", "H", "V", "W", "Y"},
5: {"K"},
8: {"J", "X"},
10: {"Q", "Z"},
},
expectation{
"a": 1, "e": 1, "i": 1, "o": 1, "u": 1, "l": 1, "n": 1, "r": 1, "s": 1, "t": 1,
"d": 2, "g": 2,
"b": 3, "c": 3, "m": 3, "p": 3,
"f": 4, "h": 4, "v": 4, "w": 4, "y": 4,
"k": 5,
"j": 8, "x": 8,
"q": 10, "z": 10,
},
},
}
func equal(actual map[string]int, expectation map[string]int) bool {
if len(actual) != len(expectation) {
return false
}
for k, actualVal := range actual {
expectationVal, present := expectation[k]
if !present || actualVal != expectationVal {
return false
}
}
return true
}
func TestTranform(t *testing.T) {
for _, tt := range transformTests {
actual := Transform(map[int][]string(tt.input))
if !equal(actual, tt.output) {
t.Fatalf("Transform(%v). Expected [%v], Actual [%v]", tt.input, tt.output, actual)
}
}
}
func BenchmarkTranform(b *testing.B) {
b.StopTimer()
for _, tt := range transformTests {
b.StartTimer()
for i := 0; i < b.N; i++ {
Transform(map[int][]string(tt.input))
}
b.StopTimer()
}
}

80
go/food-chain/README.md Normal file
View File

@ -0,0 +1,80 @@
# Food Chain
Write a program that generates the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'
Write a program that generates the lyrics to the song
"I know an old lady who swallowed a fly". While you could
copy/paste the lyrics, or read them from a file, this
problem is much more interesting if you approach it
algorithmically.
This is a [cumulative song](http://en.wikipedia.org/wiki/Cumulative_song) of unknown origin.
This is one of many common variants.
```plain
I know an old lady who swallowed a fly.
I don't know why she swallowed the fly. Perhaps she'll die.
I know an old lady who swallowed a spider.
It wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.
I know an old lady who swallowed a bird.
How absurd to swallow a bird!
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.
I know an old lady who swallowed a cat.
Imagine that, to swallow a cat!
She swallowed the cat to catch the bird.
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.
I know an old lady who swallowed a dog.
What a hog, to swallow a dog!
She swallowed the dog to catch the cat.
She swallowed the cat to catch the bird.
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.
I know an old lady who swallowed a goat.
Just opened her throat and swallowed a goat!
She swallowed the goat to catch the dog.
She swallowed the dog to catch the cat.
She swallowed the cat to catch the bird.
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.
I know an old lady who swallowed a cow.
I don't know how she swallowed a cow!
She swallowed the cow to catch the goat.
She swallowed the goat to catch the dog.
She swallowed the dog to catch the cat.
She swallowed the cat to catch the bird.
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.
I know an old lady who swallowed a horse.
She's dead, of course!
```
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
Wikipedia [view source](http://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly)

100
go/food-chain/food_chain.go Normal file
View File

@ -0,0 +1,100 @@
package foodchain
import (
"fmt"
"strings"
)
// TestVersion is an exercism thing
const TestVersion = 1
// An Inedible is something that you probably shouldn't eat.
// At the least, you shouldn't eat it whole/live.
type Inedible struct {
// What it is
Name string
// A quick jab about it
FollowUp string
}
// DoNotEat is a non-exhaustive list of Inedibles. It's recommended
// that you don't eat them. Yet the old lady did.
var DoNotEat = []Inedible{
Inedible{
"fly", "I don't know why she swallowed the fly. Perhaps she'll die.",
},
Inedible{
"spider", "It wriggled and jiggled and tickled inside her.",
},
Inedible{
"bird", "How absurd to swallow a bird!",
},
Inedible{
"cat", "Imagine that, to swallow a cat!",
},
Inedible{
"dog", "What a hog, to swallow a dog!",
},
Inedible{
"goat", "Just opened her throat and swallowed a goat!",
},
Inedible{
"cow", "I don't know how she swallowed a cow!",
},
Inedible{
"horse", "She's dead, of course!",
},
}
// Verse generates the text for a specific verse
func Verse(verseNum int) string {
return strings.Trim(Swallow(verseNum-1, true), "\n")
}
// Verses generates the text for all verses from verse1 to verse2
func Verses(verse1, verse2 int) string {
var ret string
for verse1 <= verse2 {
ret += Verse(verse1) + "\n\n"
verse1++
}
return strings.Trim(ret, "\n")
}
// Song generates all verses
func Song() string {
var ret string
for verseNum := 1; verseNum <= len(DoNotEat); verseNum++ {
ret += Verse(verseNum) + "\n\n"
}
return strings.Trim(ret, "\n")
}
// Swallow generates the text for swallowing something
func Swallow(dneIdx int, first bool) string {
var ret string
if first || dneIdx == len(DoNotEat)-1 {
ret = fmt.Sprintf(
"I know an old lady who swallowed a %s.\n%s\n",
DoNotEat[dneIdx].Name,
DoNotEat[dneIdx].FollowUp,
)
if dneIdx == 0 || dneIdx == len(DoNotEat)-1 {
return ret
}
}
ret += fmt.Sprintf("She swallowed the %s to catch the %s",
DoNotEat[dneIdx].Name,
DoNotEat[dneIdx-1].Name,
)
if DoNotEat[dneIdx-1].Name == "spider" {
ret += " that wriggled and jiggled and tickled inside her.\n"
} else if DoNotEat[dneIdx-1].Name == "fly" {
ret += ".\nI don't know why she swallowed the fly. Perhaps she'll die.\n"
return ret
} else {
ret += ".\n"
}
return ret + Swallow(dneIdx-1, false)
}

View File

@ -0,0 +1,95 @@
package foodchain
import (
"strings"
"testing"
)
const testVersion = 1
func TestTestVersion(t *testing.T) {
if TestVersion != testVersion {
t.Errorf("Found TestVersion = %v, want %v.", TestVersion, testVersion)
}
}
var ref = []string{``,
`I know an old lady who swallowed a fly.
I don't know why she swallowed the fly. Perhaps she'll die.`,
`I know an old lady who swallowed a spider.
It wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.`,
`I know an old lady who swallowed a bird.
How absurd to swallow a bird!
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.`,
`I know an old lady who swallowed a cat.
Imagine that, to swallow a cat!
She swallowed the cat to catch the bird.
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.`,
`I know an old lady who swallowed a dog.
What a hog, to swallow a dog!
She swallowed the dog to catch the cat.
She swallowed the cat to catch the bird.
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.`,
`I know an old lady who swallowed a goat.
Just opened her throat and swallowed a goat!
She swallowed the goat to catch the dog.
She swallowed the dog to catch the cat.
She swallowed the cat to catch the bird.
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.`,
`I know an old lady who swallowed a cow.
I don't know how she swallowed a cow!
She swallowed the cow to catch the goat.
She swallowed the goat to catch the dog.
She swallowed the dog to catch the cat.
She swallowed the cat to catch the bird.
She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.
She swallowed the spider to catch the fly.
I don't know why she swallowed the fly. Perhaps she'll die.`,
`I know an old lady who swallowed a horse.
She's dead, of course!`,
}
func TestVerse(t *testing.T) {
for v := 1; v <= 8; v++ {
if ret := Verse(v); ret != ref[v] {
t.Fatalf("Verse(%d) =\n%s\n want:\n%s\n", v, ret, ref[v])
}
}
}
func TestVerses(t *testing.T) {
if ret, want := Verses(1, 2), ref[1]+"\n\n"+ref[2]; ret != want {
t.Fatalf("Verses(1, 2) =\n%s\n want:\n%s\n", ret, want)
}
}
func TestSong(t *testing.T) {
if ret, want := Song(), strings.Join(ref[1:], "\n\n"); ret != want {
t.Fatalf("Song() =\n%s\n want:\n%s\n", ret, want)
}
}
func BenchmarkSong(b *testing.B) {
for i := 0; i < b.N; i++ {
Song()
}
}

19
go/gigasecond/README.md Normal file
View File

@ -0,0 +1,19 @@
# Gigasecond
Write a program that will calculate the date that someone turned or will celebrate their 1 Gs anniversary.
A gigasecond is one billion (10**9) seconds.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
Chapter 9 in Chris Pine's online Learn to Program tutorial. [view source](http://pine.fm/LearnToProgram/?Chapter=09)

View File

@ -0,0 +1,31 @@
package gigasecond
// Source: exercism/x-common
// Commit: 1e9e232 Merge pull request #45 from soniakeys/gigasecond-tests
// Add one gigasecond to the input.
var addCases = []struct {
in string
want string
}{
{
"2011-04-25",
"2043-01-01T01:46:40",
},
{
"1977-06-13",
"2009-02-19T01:46:40",
},
{
"1959-07-19",
"1991-03-27T01:46:40",
},
{
"2015-01-24T22:00:00",
"2046-10-02T23:46:40",
},
{
"2015-01-24T23:59:59",
"2046-10-03T01:46:39",
},
}

View File

@ -0,0 +1,14 @@
package gigasecond
import "time"
// TestVersion
const TestVersion = 2 // find the value in gigasecond_test.go
// AddGigasecond Adds a gigasecond to the time t
func AddGigasecond(t time.Time) time.Time {
return t.Add(time.Second * 1000000000)
}
// Birthday is my fake birthday
var Birthday = time.Date(1979, 4, 23, 10, 2, 0, 0, time.UTC)

View File

@ -0,0 +1,73 @@
package gigasecond
// Write a function AddGigasecond that works with time.Time.
// Also define a variable Birthday set to your (or someone else's) birthday.
// Run go test -v to see your gigasecond anniversary.
import (
"os"
"testing"
"time"
)
const testVersion = 2
// Retired testVersions
// (none) 98807b314216ff27492378a00df60410cc971d32
// 1 ed0594b6fd6664928d17bbc70b543a56da05a5b8
// date formats used in test data
const (
fmtD = "2006-01-02"
fmtDT = "2006-01-02T15:04:05"
)
func TestAddGigasecond(t *testing.T) {
if TestVersion != testVersion {
t.Fatalf("Found TestVersion = %v, want %v.", TestVersion, testVersion)
}
for _, tc := range addCases {
in := parse(tc.in, t)
want := parse(tc.want, t)
got := AddGigasecond(in)
if !got.Equal(want) {
t.Fatalf(`AddGigasecond(%s)
= %s
want %s`, in, got, want)
}
}
t.Log("Tested", len(addCases), "cases.")
}
func TestYourAnniversary(t *testing.T) {
t.Logf(`
Your birthday: %s
Your gigasecond anniversary: %s`, Birthday, AddGigasecond(Birthday))
}
func parse(s string, t *testing.T) time.Time {
tt, err := time.Parse(fmtDT, s) // try full date time format first
if err != nil {
tt, err = time.Parse(fmtD, s) // also allow just date
}
if err != nil {
// can't run tests if input won't parse. if this seems to be a
// development or ci environment, raise an error. if this condition
// makes it to the solver though, ask for a bug report.
_, statErr := os.Stat("example_gen.go")
if statErr == nil || os.Getenv("TRAVIS_GO_VERSION") > "" {
t.Fatal(err)
} else {
t.Log(err)
t.Skip("(Not your problem. " +
"please file issue at https://github.com/exercism/xgo.)")
}
}
return tt
}
func BenchmarkAddGigasecond(b *testing.B) {
for i := 0; i < b.N; i++ {
AddGigasecond(time.Time{})
}
}

41
go/grains/README.md Normal file
View File

@ -0,0 +1,41 @@
# Grains
Write a program that calculates 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 a program 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?
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
JavaRanch Cattle Drive, exercise 6 [view source](http://www.javaranch.com/grains.jsp)

30
go/grains/grains.go Normal file
View File

@ -0,0 +1,30 @@
package grains
import "errors"
// Square just takes 1 * 2^sq
func Square(sq int) (uint64, error) {
if sq > 0 && sq < 65 {
return (1 << uint(sq-1)), nil
}
return 0, errors.New("Invalid Square Requested")
}
// TotalForSquare calculates the total number
// for all squares up to sq (cause why not)
func TotalForSquare(sq int) (uint64, error) {
if sq < 0 || sq > 64 {
return 0, errors.New("Invalid Square Requested")
}
var ret uint64
for i := 0; i <= sq; i++ {
ret = (ret << 1) | 1
}
return ret, nil
}
// Total calculates the total for the entire board
func Total() uint64 {
ret, _ := TotalForSquare(64)
return ret
}

61
go/grains/grains_test.go Normal file
View File

@ -0,0 +1,61 @@
package grains
import (
"testing"
)
var squareTests = []struct {
input int
expectedVal uint64
expectError bool
}{
{1, 1, false},
{2, 2, false},
{3, 4, false},
{4, 8, false},
{16, 32768, false},
{32, 2147483648, false},
{64, 9223372036854775808, false},
{65, 0, true},
{0, 0, true},
{-1, 0, true},
}
func TestSquare(t *testing.T) {
for _, test := range squareTests {
actualVal, actualErr := Square(test.input)
if actualVal != test.expectedVal {
t.Errorf("Square(%d) expected %d, Actual %d", test.input, test.expectedVal, actualVal)
}
// if we expect an error and there isn't one
if test.expectError && actualErr == nil {
t.Errorf("Square(%d) expected an error, but error is nil", test.input)
}
// if we don't expect an error and there is one
if !test.expectError && actualErr != nil {
t.Errorf("Square(%d) expected no error, but error is: %s", test.input, actualErr)
}
}
}
func TestTotal(t *testing.T) {
var expected uint64 = 18446744073709551615
if actual := Total(); actual != expected {
t.Errorf("Total() expected %d, Actual %d", expected, actual)
}
}
func BenchmarkSquare(b *testing.B) {
b.StopTimer()
for _, test := range squareTests {
b.StartTimer()
for i := 0; i < b.N; i++ {
Square(test.input)
}
b.StopTimer()
}
}

50
go/hamming/README.md Normal file
View File

@ -0,0 +1,50 @@
# Hamming
Write a program that can 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.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
The Calculating Point Mutations problem at Rosalind [view source](http://rosalind.info/problems/hamm/)

81
go/hamming/cases_test.go Normal file
View File

@ -0,0 +1,81 @@
package hamming
// Source: exercism/x-common
// Commit: c84e435 Merge pull request #51 from soniakeys/master
var testCases = []struct {
s1 string
s2 string
want int
}{
{ // identical strands
"A",
"A",
0,
},
{ // long identical strands
"GGACTGA",
"GGACTGA",
0,
},
{ // complete distance in single nucleotide strands
"A",
"G",
1,
},
{ // complete distance in small strands
"AG",
"CT",
2,
},
{ // small distance in small strands
"AT",
"CT",
1,
},
{ // small distance
"GGACG",
"GGTCG",
1,
},
{ // small distance in long strands
"ACCAGGG",
"ACTATGG",
2,
},
{ // non-unique character in first strand
"AGA",
"AGG",
1,
},
{ // non-unique character in second strand
"AGG",
"AGA",
1,
},
{ // large distance
"GATACA",
"GCATAA",
4,
},
{ // large distance in off-by-one strand
"GGACGGATTCTG",
"AGGACGGATTCT",
9,
},
{ // empty strands
"",
"",
0,
},
{ // disallow first strand longer
"AATG",
"AAA",
-1,
},
{ // disallow second strand longer
"ATA",
"AGTG",
-1,
},
}

21
go/hamming/hamming.go Normal file
View File

@ -0,0 +1,21 @@
package hamming
import "errors"
// TestVersion is an exercism thing
const TestVersion = 2
// Distance measures the hamming distance between two sequences
// and returns the number if different bytes and an error value
func Distance(seq1, seq2 string) (int, error) {
if len(seq1) != len(seq2) {
return -1, errors.New("Strands must be equal length")
}
var ret int
for i := 0; i < len(seq1); i++ {
if seq1[i] != seq2[i] {
ret++
}
}
return ret, nil
}

View File

@ -0,0 +1,39 @@
package hamming
import "testing"
const testVersion = 2
// Retired testVersions
// (none) df178dc24b57f7d4ccf54d47430192749d56898f
// 1 4f6fe21682f7f2a7845683cb26ff557208153ffe
func TestHamming(t *testing.T) {
if TestVersion != testVersion {
t.Errorf("Found TestVersion = %v, want %v.", TestVersion, testVersion)
}
for _, tc := range testCases {
switch got, err := Distance(tc.s1, tc.s2); {
case err != nil:
if tc.want >= 0 {
t.Fatalf("Distance(%q, %q) returned error: %v",
tc.s1, tc.s2, err)
}
case tc.want < 0:
t.Fatalf("Distance(%q, %q) = %d. Expected error.",
tc.s1, tc.s2, got)
case got != tc.want:
t.Fatalf("Distance(%q, %q) = %d, want %d.",
tc.s1, tc.s2, got, tc.want)
}
}
}
func BenchmarkHamming(b *testing.B) {
// bench combined time to run through all test cases
for i := 0; i < b.N; i++ {
for _, tc := range testCases {
Distance(tc.s1, tc.s2)
}
}
}

121
go/house/README.md Normal file
View File

@ -0,0 +1,121 @@
# House
Write a program that outputs the nursery rhyme 'This is the House that Jack Built'.
> [The] process of placing a phrase of clause within another phrase of
> clause is called embedding. It is through the processes of recursion
> and embedding that we are able to take a finite number of forms (words
> and phrases) and construct an infinite number of expressions.
> Furthermore, embedding also allows us to construct an infinitely long
> structure, in theory anyway.
- [papyr.com](http://papyr.com/hypertextbooks/grammar/ph_noun.htm)
The nursery rhyme reads as follows:
```plain
This is the house that Jack built.
This is the malt
that lay in the house that Jack built.
This is the rat
that ate the malt
that lay in the house that Jack built.
This is the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the priest all shaven and shorn
that married the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the rooster that crowed in the morn
that woke the priest all shaven and shorn
that married the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the farmer sowing his corn
that kept the rooster that crowed in the morn
that woke the priest all shaven and shorn
that married the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the horse and the hound and the horn
that belonged to the farmer sowing his corn
that kept the rooster that crowed in the morn
that woke the priest all shaven and shorn
that married the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
```
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
British nursery rhyme [view source](http://en.wikipedia.org/wiki/This_Is_The_House_That_Jack_Built)

50
go/house/house.go Normal file
View File

@ -0,0 +1,50 @@
package house
// ASong holds the data we need to generate a song
type ASong struct {
start string
clauses []string
end string
}
// Embed takes two strings and returns a string with the embedded
func Embed(l, p string) string {
return l + " " + p
}
// Verse takes three things and returns a verse
func Verse(start string, clause []string, end string) string {
ret := start + " "
for i := 0; i < len(clause); i++ {
ret += clause[i] + " "
}
ret += end
return ret
}
// Song generates the whole song
func Song() string {
jackSong := ASong{
start: "This is",
clauses: []string{
"the horse and the hound and the horn\nthat belonged to",
"the farmer sowing his corn\nthat kept",
"the rooster that crowed in the morn\nthat woke",
"the priest all shaven and shorn\nthat married",
"the man all tattered and torn\nthat kissed",
"the maiden all forlorn\nthat milked",
"the cow with the crumpled horn\nthat tossed",
"the dog\nthat worried",
"the cat\nthat killed",
"the rat\nthat ate",
"the malt\nthat lay in",
},
end: "the house that Jack built.",
}
var ret string
for i := len(jackSong.clauses); i >= 0; i-- {
ret += Verse(jackSong.start, jackSong.clauses[i:], jackSong.end) + "\n\n"
}
// Trim the trailing "\n\n"
return ret[:len(ret)-2]
}

171
go/house/house_test.go Normal file
View File

@ -0,0 +1,171 @@
// Embed embeds a noun phrase as the object of relative clause with a
// transitive verb.
//
// Argument relPhrase is a phrase with a relative clause, minus the object
// of the clause. That is, relPhrase consists of a subject, a relative
// pronoun, a transitive verb, possibly a preposition, but then no object.
//
// func Embed(relPhrase, nounPhrase string) string
// Verse generates a verse of a song with relative clauses that have
// a recursive structure.
//
// func Verse(subject string, relPhrases []string, nounPhrase string) string
//
// There are different ways to do this of course, but try using Embed as a
// subroutine and using programmatic recursion that reflects the grammatical
// recursion.
// Song generates the full text of "The House That Jack Built". Oh yes, you
// could just return a string literal, but humor us; use Verse as a subroutine.
//
// func Song() string
package house
import (
"fmt"
"strings"
"testing"
)
var (
s = "This is"
r = []string{
"the cat that broke",
"the vase that was on",
}
p = "the shelf."
last = len(r) - 1
// song copied from readme
song = `This is the house that Jack built.
This is the malt
that lay in the house that Jack built.
This is the rat
that ate the malt
that lay in the house that Jack built.
This is the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the priest all shaven and shorn
that married the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the rooster that crowed in the morn
that woke the priest all shaven and shorn
that married the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the farmer sowing his corn
that kept the rooster that crowed in the morn
that woke the priest all shaven and shorn
that married the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.
This is the horse and the hound and the horn
that belonged to the farmer sowing his corn
that kept the rooster that crowed in the morn
that woke the priest all shaven and shorn
that married the man all tattered and torn
that kissed the maiden all forlorn
that milked the cow with the crumpled horn
that tossed the dog
that worried the cat
that killed the rat
that ate the malt
that lay in the house that Jack built.`
)
func TestEmbed(t *testing.T) {
l := r[last]
want := l + " " + p
if e := Embed(l, p); e != want {
t.Fatalf("Embed(%q, %q) = %q, want %q.", l, p, e, want)
}
}
func TestVerse(t *testing.T) {
for i := len(r); i >= 0; i-- {
ri := r[i:]
want := s + " " + strings.Join(append(ri, p), " ")
if v := Verse(s, ri, p); v != want {
t.Fatalf("Verse(%q, %q, %q) = %q, want %q.", s, ri, p, v, want)
}
}
}
func TestSong(t *testing.T) {
s := Song()
if s == song {
return
}
fmt.Print(s)
// a little help in locating an error
got := strings.Split(s, "\n")
want := strings.Split(song, "\n")
var g, w string
var i int
for i, w = range want {
if len(got) <= i {
g = ""
break
}
if g = got[i]; g != w {
break
}
}
t.Fatalf("Song() line %d = %q, want %q", i+1, g, w)
}

View File

@ -0,0 +1,24 @@
# Largest Series Product
Write a program that, when given a string of digits, can calculate the largest product for a series of consecutive digits of length n.
For example, for the input `'0123456789'`, the largest product for a
series of 3 digits is 504 (7 * 8 * 9), and the largest product for a
series of 5 digits is 15120 (5 * 6 * 7 * 8 * 9).
For the input `'73167176531330624919225119674426574742355349194934'`,
the largest product for a series of 6 digits is 23520.
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
A variation on Problem 8 at Project Euler [view source](http://projecteuler.net/problem=8)

View File

@ -0,0 +1,29 @@
package lsproduct
// Source: exercism/x-common
// Commit: 3764abd Merge pull request #167 from petertseng/largest-series-product-json
var tests = []struct {
digits string
span int
product int64
ok bool
}{
{"0123456789", 2, 72, true},
{"576802143", 2, 48, true},
{"29", 2, 18, true},
{"0123456789", 3, 504, true},
{"1027839564", 3, 270, true},
{"0123456789", 5, 15120, true},
{"73167176531330624919225119674426574742355349194934", 6, 23520, true},
{"52677741234314237566414902593461595376319419139427", 6, 28350, true},
{"7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450", 13, 23514624000, true},
{"0000", 2, 0, true},
{"99099", 3, 0, true},
{"123", 4, -1, false},
{"", 0, 1, true},
{"123", 0, 1, true},
{"", 1, -1, false},
{"1234a5", 2, -1, false},
{"12345", -1, -1, false},
}

View File

@ -0,0 +1,45 @@
package lsproduct
import "fmt"
// TestVersion defines version testing.
const TestVersion = 1
// LargestSeriesProduct Takes an input string of digits
// and a length for the series. It returns the largest
// series product from that string of that length.
func LargestSeriesProduct(input string, size int) (int, error) {
if size == 0 {
return 1, nil
} else if size > len(input) {
return 0, fmt.Errorf("Invalid Span Size")
}
var high int
for i := 0; i < (len(input) - size + 1); i++ {
try := GetProduct(input[i : i+size])
if try < 0 {
return 0, fmt.Errorf("Invalid input")
}
if try > high {
high = try
}
}
return high, nil
}
// GetProduct takes a string of numbers, splits it up
// and returns the product of them
func GetProduct(input string) int {
if len(input) > 0 {
total := 1
for i := range input {
next := input[i] - 48
if next < 0 || next > 9 {
return -1
}
total = total * int(next)
}
return total
}
return 0
}

View File

@ -0,0 +1,92 @@
package lsproduct
import "testing"
const testVersion = 1
// Retired testVersions
// (none) ba7a22a355a32901caf46529c799fa53118ded0a
var tests = []struct {
digits string
span int
product int64
ok bool
}{
{"0123456789",
2, 72, true},
{"12",
2, 2, true},
{"19",
2, 9, true},
{"576802143",
2, 48, true},
{"0123456789",
3, 504, true},
{"1027839564",
3, 270, true},
{"0123456789",
5, 15120, true},
{"73167176531330624919225119674426574742355349194934",
6, 23520, true},
{"52677741234314237566414902593461595376319419139427",
6, 28350, true},
{"",
0, 1, true},
{"123",
4, 0, false},
{pe1k, 5, 40824, true}, // original PE problem
{pe1k, 13, 23514624000, true}, // new PE problem
}
const pe1k = "73167176531330624919225119674426574742355349194934" +
"96983520312774506326239578318016984801869478851843" +
"85861560789112949495459501737958331952853208805511" +
"12540698747158523863050715693290963295227443043557" +
"66896648950445244523161731856403098711121722383113" +
"62229893423380308135336276614282806444486645238749" +
"30358907296290491560440772390713810515859307960866" +
"70172427121883998797908792274921901699720888093776" +
"65727333001053367881220235421809751254540594752243" +
"52584907711670556013604839586446706324415722155397" +
"53697817977846174064955149290862569321978468622482" +
"83972241375657056057490261407972968652414535100474" +
"82166370484403199890008895243450658541227588666881" +
"16427171479924442928230863465674813919123162824586" +
"17866458359124566529476545682848912883142607690042" +
"24219022671055626321111109370544217506941658960408" +
"07198403850962455444362981230987879927244284909188" +
"84580156166097919133875499200524063689912560717606" +
"05886116467109405077541002256983155200055935729725" +
"71636269561882670428252483600823257530420752963450"
func TestLargestSeriesProduct(t *testing.T) {
if TestVersion != testVersion {
t.Fatalf("Found TestVersion = %v, want %v", TestVersion, testVersion)
}
for _, test := range tests {
p, err := LargestSeriesProduct(test.digits, test.span)
switch {
case err != nil:
if test.ok {
t.Fatalf("LargestSeriesProduct(%s, %d) returned error %q. "+
"Error not expected.",
test.digits, test.span, err)
}
case !test.ok:
t.Fatalf("LargestSeriesProduct(%s, %d) = %d, %v. Expected error",
test.digits, test.span, p, err)
case int64(p) != test.product:
t.Fatalf("LargestSeriesProduct(%s, %d) = %d, want %d",
test.digits, test.span, p, test.product)
}
}
}
func BenchmarkLargestSeriesProduct(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, test := range tests {
LargestSeriesProduct(test.digits, test.span)
}
}
}

38
go/leap/README.md Normal file
View File

@ -0,0 +1,38 @@
# Leap
Write a program that will take a year and report if it is a leap year.
The tricky thing here is that a leap year 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
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
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://help.exercism.io/getting-started-with-go.html).
## Source
JavaRanch Cattle Drive, exercise 3 [view source](http://www.javaranch.com/leap.jsp)

17
go/leap/cases_test.go Normal file
View File

@ -0,0 +1,17 @@
package leap
// Source: exercism/x-common
// Commit: 945d08e Merge pull request #50 from soniakeys/master
var testCases = []struct {
year int
expected bool
description string
}{
{1996, true, "leap year"},
{1997, false, "non-leap year"},
{1998, false, "non-leap even year"},
{1900, false, "century"},
{2400, true, "fourth century"},
{2000, true, "Y2K"},
}

15
go/leap/leap.go Normal file
View File

@ -0,0 +1,15 @@
package leap
// TestVersion is an exercism thing.
const TestVersion = 1
// IsLeapYear returns whether the given year is a leap year.
func IsLeapYear(year int) bool {
if year%4 != 0 {
return false
}
if year%400 == 0 {
return true
}
return year%100 != 0
}

Some files were not shown because too many files have changed in this diff Show More