~willvaughn/kata

65a90cc312ff11f51e8e89cde927ec9c84a74298 — William Vaughn 1 year, 5 months ago 346402b
add exercism bird-watcher
A exercism/clojure/bird-watcher/.exercism/config.json => exercism/clojure/bird-watcher/.exercism/config.json +20 -0
@@ 0,0 1,20 @@
{
  "authors": [
    "porkostomus"
  ],
  "files": {
    "solution": [
      "src/bird_watcher.clj"
    ],
    "test": [
      "test/bird_watcher_test.clj"
    ],
    "exemplar": [
      ".meta/exemplar.clj"
    ]
  },
  "forked_from": [
    "csharp/bird-watcher"
  ],
  "blurb": "Learn about vectors by counting the birds in your garden"
}

A exercism/clojure/bird-watcher/.exercism/metadata.json => exercism/clojure/bird-watcher/.exercism/metadata.json +1 -0
@@ 0,0 1,1 @@
{"track":"clojure","exercise":"bird-watcher","id":"deb683036538498f84aae05ef991f2f1","url":"https://exercism.org/tracks/clojure/exercises/bird-watcher","handle":"willvaughn","is_requester":true,"auto_approve":false}
\ No newline at end of file

A exercism/clojure/bird-watcher/HELP.md => exercism/clojure/bird-watcher/HELP.md +75 -0
@@ 0,0 1,75 @@
# Help

## Running the tests

## Clojure CLI

The Clojure exercises on Exercism ship with a `deps.edn` file with a `:test` alias to invoke the [cognitect-labs test-runner](https://github.com/cognitect-labs/test-runner):

``` bash
$ clj -X:test
```

## Leiningen

Leiningen can also be used to run the exercise's test by running the following command from the exercise's directory:

```bash
lein test
```

## REPL

To use the REPL to run the exercise's test, run the following command from the exercise's directory:

```bash
$ clj
```

-or-

```bash
$ lein repl
```

Then `require` the exercise's test namespace and the Clojure test namespace):

```clojure
;; replace <exercise> with the exercise's name
=> (require '<exercise>-test)
```

Then call `run-tests` on `<exercise>-test`:

```clojure
;; replace <exercise> with the exercise's name
=> (clojure.test/run-tests '<exercise>-test)
```

## Submitting your solution

You can submit your solution using the `exercism submit src/bird_watcher.clj` command.
This command will upload your solution to the Exercism website and print the solution page's URL.

It's possible to submit an incomplete solution which allows you to:

- See how others have completed the exercise
- Request help from a mentor

## Need to get help?

If you'd like help solving the exercise, check the following pages:

- The [Clojure track's documentation](https://exercism.org/docs/tracks/clojure)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)

Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.

To get help if you're having trouble, you can use one of the following resources:

- [Ask Clojure](https://ask.clojure.org/) Official forum for Clojure Q & A.
- [ClojureDocs](https://clojuredocs.org) A repository of language references and examples by function or keyword.
- [/r/clojure](https://www.reddit.com/r/clojure) is the Clojure subreddit.
- [StackOverflow](http://stackoverflow.com/questions/tagged/clojure) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.
- [Clojureverse](https://clojureverse.org/) Friendly and inclusive Clojure(Script) Community
\ No newline at end of file

A exercism/clojure/bird-watcher/HINTS.md => exercism/clojure/bird-watcher/HINTS.md +53 -0
@@ 0,0 1,53 @@
# Hints

## Check what the counts were last week

- [Vectors][vectors] are represented in Clojure using square brackets (`[ ]`)

## Check how many birds visited today

- The [`last`][last] function can be used to return the last item in a sequential collection.

## Increment today's count

- The [`update`][update] function can be used to return a new vector with a different element at a given index.

- The [`count`][count] function can be used to find the length of the vector.

- The [`inc`][inc] and [`dec`][dec] functions can be used to increment and decrement integer values.

## Check if there was a day with no visiting birds

- The [`every?`][every?] function can be used to check if all items in a collection satisfy a given predicate.

- The [`pos?`][pos?] predicate returns true if a number is greater than zero.

- The [`not`][not] function returns true if an expression evaluates to logical false.

## Calculate the number of visiting birds for the first number of days

- The [`take`][take] function can be used return a sequence of the first n items in a collection.

- The [`reduce`][reduce] function can be used to add a collection of values together.

## Calculate the number of busy days

- The [`filter`][filter] higher-order function can be used to return a sequence of items in a collection which satisfy a given predicate.

## Check for odd week

- The [`=`][equality] function can be used to test equality.

[count]: https://clojuredocs.org/clojure.core/count
[dec]: https://clojuredocs.org/clojure.core/dec
[equality]: https://clojuredocs.org/clojure.core/=
[every?]: https://clojuredocs.org/clojure.core/every_q
[filter]: https://clojuredocs.org/clojure.core/filter
[inc]: https://clojuredocs.org/clojure.core/inc
[last]: https://clojuredocs.org/clojure.core/last
[not]: https://clojuredocs.org/clojure.core/not
[pos?]: https://clojuredocs.org/clojure.core/pos_q
[reduce]: https://clojuredocs.org/clojure.core/reduce
[take]: https://clojuredocs.org/clojure.core/take
[update]: https://clojuredocs.org/clojure.core/update
[vectors]: https://clojure.org/guides/learn/sequential_colls#_vectors
\ No newline at end of file

A exercism/clojure/bird-watcher/README.md => exercism/clojure/bird-watcher/README.md +121 -0
@@ 0,0 1,121 @@
# Bird Watcher

Welcome to Bird Watcher on Exercism's Clojure Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)

## Introduction

A `vector` in Clojure is a sequential, indexed, immutable collection of zero or more values. This means that once a vector has been created, it cannot be modified. Functions for operating on vectors will return a new vector, while the original vector remains unchanged. The values in a vector may be of heterogenous types. Vectors can be defined as follows:

```clojure
(def empty [])
(def single-value [5])
(def single-value-alternative (vector 5))
(def three-values [a b c])
```

Elements can be retrieved from a vector using an index. Clojure vectors are zero-based, meaning that the first element's index is always zero:

```clojure
(def numbers [2 3 5])
;; Read value from vector
(get numbers 2)
;;=> 5
;; Update value in vector
(assoc numbers 2 9)
;;=> [2 3 9]
```

The original vector is unchanged:

```clojure
numbers
;;=> [2 3 5]
```

To remember the updated value, we need to pass it along or capture it in a var:

```clojure
(def updated-numbers
  (assoc numbers 2 9))
(get updated-numbers 2)
;;=> 9
```

## Instructions

You're an avid bird watcher that keeps track of how many birds have visited your garden in the last seven days.

You have six tasks, all dealing with the numbers of birds that visited your garden.

## 1. Check what the counts were last week

For comparison purposes, you always keep a copy of last week's counts nearby, which were: 0, 2, 5, 3, 7, 8 and 4. Create a vector containing last week's counts:

```clojure
last-week
;;=> [0 2 5 3 7 8 4]
```

## 2. Check how many birds visited today

Implement the `today` function to return how many birds visited your garden today. The bird counts are ordered by day, with the first element being the count of the oldest day, and the last element being today's count.

```clojure
(def birds-per-day [2 5 0 7 4 1])
(today birds-per-day)
;;=> 1
```

## 3. Increment today's count

Implement the `inc-bird` function to increment today's count:

```clojure
(inc-bird birds-per-day)
;;=> [2 5 0 7 4 2]
```

## 4. Check if there was a day with no visiting birds

Implement the `day-without-birds?` predicate function that returns `true` if there was a day at which zero birds visited the garden; otherwise, return `false`:

```clojure
(day-without-birds? birds-per-day)
;;=> true
```

## 5. Calculate the number of visiting birds for the first number of days

Implement the `n-days-count` function that returns the number of birds that have visited your garden from the start of the week, but limit the count to the specified number of days from the start of the week.

```clojure
(n-days-count birds-per-day 4)
;;=> 14
```

## 6. Calculate the number of busy days

Some days are busier than others. A busy day is one where five or more birds have visited your garden.
Implement the `busy-days` function to return the number of busy days:

```clojure
(busy-days birds-per-day)
;;=> 2
```

## 7. Check for odd week

Over the last year, you've found that some weeks for the same, odd pattern, where the counts alternate between one and zero birds visiting. Implement the `odd-week?` function that returns `true` if the bird count pattern of this week matches the odd pattern:

```clojure
(odd-week? [1 0 1 0 1 0 1])
;;=> true
```

## Source

### Created by

- @porkostomus
\ No newline at end of file

A exercism/clojure/bird-watcher/deps.edn => exercism/clojure/bird-watcher/deps.edn +6 -0
@@ 0,0 1,6 @@
{:aliases {:test {:extra-paths ["test"]
                  :extra-deps {io.github.cognitect-labs/test-runner
                               {:git/url "https://github.com/cognitect-labs/test-runner.git"
                                :sha "705ad25bbf0228b1c38d0244a36001c2987d7337"}}
                  :main-opts ["-m" "cognitect.test-runner"]
                  :exec-fn cognitect.test-runner.api/test}}}
\ No newline at end of file

A exercism/clojure/bird-watcher/project.clj => exercism/clojure/bird-watcher/project.clj +4 -0
@@ 0,0 1,4 @@
(defproject bird-watcher "0.1.0-SNAPSHOT"
  :description "bird-watcher exercise."
  :url "https://github.com/exercism/clojure/tree/main/exercises/concept/bird-watcher"
  :dependencies [[org.clojure/clojure "1.10.0"]])
\ No newline at end of file

A exercism/clojure/bird-watcher/src/bird_watcher.clj => exercism/clojure/bird-watcher/src/bird_watcher.clj +22 -0
@@ 0,0 1,22 @@
(ns bird-watcher)

(def last-week 
  )

(defn today [birds]
  )

(defn inc-bird [birds]
  )

(defn day-without-birds? [birds]
  )

(defn n-days-count [birds n]
  )

(defn busy-days [birds]
  )

(defn odd-week? [birds]
  )

A exercism/clojure/bird-watcher/test/bird_watcher_test.clj => exercism/clojure/bird-watcher/test/bird_watcher_test.clj +54 -0
@@ 0,0 1,54 @@
(ns bird-watcher-test
  (:require [clojure.test :refer [deftest testing is]]
            bird-watcher))

(deftest last-week-test
  (is (= [0 2 5 3 7 8 4] bird-watcher/last-week)))

(deftest today-disappointing-week-test
  (testing "Today's bird count of disappointing week"
    (is (= 0 (bird-watcher/today [0 0 2 0 0 1 0])))))

(deftest today-busy-week-test
  (testing "Today's bird count of busy week"
    (is (= 10 (bird-watcher/today [8 8 9 5 4 7 10])))))

(deftest increment-bird-no-visits-test
  (testing "Increment today's count with no previous visits"
    (is (= [6 5 5 11 2 5 1] (bird-watcher/inc-bird [6 5 5 11 2 5 0])))))

(deftest increment-bird-multiple-visits-test
  (testing "Increment today's count with multiple previous visits"
    (is (= [5 2 4 2 4 5 8] (bird-watcher/inc-bird [5 2 4 2 4 5 7])))))

(deftest day-without-birds-test
  (testing "Has day without birds with day without birds"
    (is (= true (bird-watcher/day-without-birds? [5 5 4 0 7 6 7])))))

(deftest no-day-without-birds-test
  (testing "Has day without birds with no day without birds"
    (is (= false (bird-watcher/day-without-birds? [5 5 4 1 7 6 7])))))

(deftest n-days-count-disappointing-week-test
  (testing "Count for first three days of disappointing week"
    (is (= 1 (bird-watcher/n-days-count [0, 0, 1, 0, 0, 1, 0] 3)))))

(deftest n-days-count-busy-week-test
  (testing "Count for first 6 days of busy week"
    (is (= 48 (bird-watcher/n-days-count [5, 9, 12, 6, 8, 8, 17] 6)))))

(deftest busy-days-disappointing-week-test
  (testing "Busy days for disappointing week"
    (is (= 0 (bird-watcher/busy-days [1 1 1 0 0 0 0])))))

(deftest busy-days-busy-week-test
  (testing "Busy days for busy week"
    (is (= 5 (bird-watcher/busy-days [4 9 5 7 8 8 2])))))

(deftest odd-week-matching-test
  (testing "Odd week for week matching odd pattern"
    (is (= true (bird-watcher/odd-week? [1 0 1 0 1 0 1])))))

(deftest odd-week-not-matching-test
  (testing "Odd week for week that does not match pattern"
    (is (= false (bird-watcher/odd-week? [2 2 1 0 1 1 1])))))
\ No newline at end of file