1
1
Fork 0
exercism/jq/recursive-functions
Christina Sørensen a7087bbb67
feat(jq): recursive functions
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-12-09 19:34:58 +01:00
..
.exercism feat(jq): recursive functions 2024-12-09 19:34:58 +01:00
bats-extra.bash feat(jq): recursive functions 2024-12-09 19:34:58 +01:00
bats-jq.bash feat(jq): recursive functions 2024-12-09 19:34:58 +01:00
HELP.md feat(jq): recursive functions 2024-12-09 19:34:58 +01:00
HINTS.md feat(jq): recursive functions 2024-12-09 19:34:58 +01:00
README.md feat(jq): recursive functions 2024-12-09 19:34:58 +01:00
recursive-functions.jq feat(jq): recursive functions 2024-12-09 19:34:58 +01:00
test-recursive-functions.bats feat(jq): recursive functions 2024-12-09 19:34:58 +01:00

Recursive Functions

Welcome to Recursive Functions on Exercism's jq 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

Recursion

Recursive functions are functions that call themselves.

A recursive function needs to have at least one base case and at least one recursive case.

A base case returns a value without calling the function again. A recursive case calls the function again, modifying the input so that it will at some point match the base case.

Here is an example that counts the elements of an array.

def count:
  if length == 0 then
    0                       # base case
  else
    1 + (.[1:] | count)     # recursive case
  end;

([] | count),           # => 0
([11, 22, 33] | count)  # => 3

A recursive function can have many base cases and/or many recursive cases. For example the Fibonacci sequence is a recursive sequence with two base cases.

def fibonacci:
  if . == 0 then
    0
  elif . == 1 then
    1
  else
    (. - 1 | fibonacci) + (. - 2 | fibonacci)
  end;

10 | fibonacci          # => 55

Counting the number of occurrences of some given value x in a list has two recursive cases.

def count_occurrences(x):
  if length == 0 then
    0
  elif first == x then
    1 + (.[1:] | count_occurrences(x))
  else
    (.[1:] | count_occurrences(x))
  end;

[11, 22, 33, 22, 44] | count_occurrences(22)    # => 2

In practice, iterating over lists and other enumerable data structures is most often done using builtin functions, such as map and reduce, or by using streams like [.[] | select(...)]. Under the hood, some builtins are implemented using recursion.

Instructions

In this exercise you're going to implement some recursive functions.

1. Implement a function to add the numbers in an array

We'll re-implement the builtin add filter to practice recursion. The base case is that an empty array has a sum of zero.

Implement it yourself with a recursive function; don't use the builtin add.

[5, 4, 6, 10] | array_add     # => 25

2. Reverse an array

We'll re-implement the builtin reverse filter. The base case is that an empty array reversed is an empty array.

Implement it yourself with a recursive function; don't use the builtin reverse.

[5, 4, 6, 10] | array_reverse   # => [10, 6, 4, 5]

3. Map an array

We'll re-implement the builtin map filter. The function takes a filter as a parameter, run that filter for each element of the input array, and return the outputs in a new array. The base case is that an empty array maps to an empty array.

Implement it yourself with a recursive function; don't use the builtin map.

[5, 4, 6, 10] | array_map(. + 10)   # => [15, 14, 16, 20]

Source

Created by

  • @glennj