Can someone give me some hint/guide how to start this Elixir homework (I have to write a function)

Hi guys, I started to learn Elixir at University and I need to write a function (sit!) for homework. I have been struggling with this for days now.

The description of the task:

How many ways can ‘k’ people sit down in ‘n>2’ rows, but moving from the front to the back every row has ‘d’ less people.


@type variant :: { h :: integer, d :: integer }
@type seatings :: { n :: integer, vs :: [ variant ] }

@spec sit!( k :: integer ) :: r :: { m :: integer, ss :: [ seatings ] }

k: number of the people
m: maximum variation of the seating
ss: list of {n, vs} pairs
n: number of rows of the seating
h: the shortest row (back row/first row)
d: the difference between every neighboring rows

Here is an example:

10 - >

iex> Khf1.sit! 10
{1, [{4, [{1, 1}]}]}

In this case k=10, m=1 because there is only one variation, n=4 because there is 4 rows, h=1 because the shortest row is 1, d=1 because the difference between rows is 1.

I need to solve this problem with recursion and the output must look like the specification.

More examples:

iex> Khf1.sit! 101
{0, []}
iex> Khf1.sit! 15
{5, [{3, [{1, 4}, {2, 3}, {3, 2}, {4, 1}]}, {5, [{1, 1}]}]}
iex> Khf1.sit! 14
{1, [{4, [{2, 1}]}]}
iex> Khf1.sit! 10
{1, [{4, [{1, 1}]}]}
iex> Khf1.sit! 9
{2, [{3, [{1, 2}, {2, 1}]}]}
iex> Khf1.sit! 5
{0, []}

If someone could give me some tips how to do this that would be very helpful.
Thank you.

I’m learning Elixir too and when I look at your exercise, I had some ideas and wrote it down:

  • Firstly, I find what is max rows could be? So I assume that the max rows is when the different between 2 rows is 1 => So I can get the possible max rows.
  • Then I check with each row + people to find out its variants
    I tested and it could pass your requirements.
    Please refer to my code version, it might not good enough (the ranges I use in for is not the best) but I hope it could help you get some ideas.
    I’m looking forward to see your better version of this exercise.
defmodule Khf1 do
  def sit!(n) do
    max_row = :math.sqrt(n*2) |> floor()
    res =
      for row <- 3..max_row, into: [], do: sit_in_rows(n, row)

    res = res |> Enum.filter(&(&1 != nil))
    variants = Enum.reduce(res, 0, fn {v, _}, acc -> acc + v end )

    {variants, res}

  def sit_in_rows(n, row) do
    max_d = floor(n/row)      # max differences between 2 rows
    res =
      for f <- 1..(n-row), d <- 1..max_d, satisfy?(f, d, n, row), into: [], do: {f, d}

    res = res |> Enum.filter(&(&1 != nil))
    variants = Enum.count(res)
    if variants != 0, do: {variants, res}, else: nil

  def satisfy?(first, diff, n, row) do
    last = first + diff*(row - 1)
    sum = (first + last) * row/2

    sum == n
1 Like

If the question is “how many permuatations of seating arrangements are there?”
then the solution is:

  1. calculate number of seats, call it k (do this as a recursive function, it will accept “number of rows” and “diff d between number of seats per row” as its 2 arguments)
  2. Get the number of people, call it n
  3. calculate the “k-permutations of n” (see here: Permutation - Wikipedia), like this:
n! / (n - k)!

In elixir, it would look like this:

factorial(n) / factorial(n - k)

The recursion happens when you write a “factorial” function, to calculate n! and (n - k)!. That function will be nicest as a recursive function.

Here’s my take on this problem.

defmodule SeatingProblem do
  @doc """
  Gets the factorial of a non-negative number.

  Here's how factorials work:
  factorial(5) = 5! = 5 * 4! = 5 * 4 * 3! = ... = 5 * 4 * 3 * 2 * 1
  def factorial(n) when n < 0 do
    raise("Factorials don't work with negative numbers")

  def factorial(0), do: 1
  def factorial(1), do: 1

  def factorial(n) when is_integer(n) do
    n * factorial(n - 1)

  @doc """
  def k_permutations_of_n(k, n) do
    div(factorial(n), factorial(n - k))

  @doc """
  Why is this safe? Because we cannot get the factorial of a negative number.
  The number of ways of seating 35 people in 200 seats
  is the same as
  the number of ways of assigning 35 seats to 200 people.
  def safe_k_permutations_of_n(k, n) do
    if n > k do
      k_permutations_of_n(k, n)
      k_permutations_of_n(n, k)

  @doc """
  This is just to visualize what the rows of seats look like. Each "x" is a seat.
  def visualize_seats(number_of_rows, row_seat_increment, initial_row_seat_count) do
    |> row_index ->
      seat_count = initial_row_seat_count + row_seat_increment * (row_index - 1)

      |> _ -> "x" end)
      |> Enum.join()
      |> IO.puts()

  @doc """
  Gets the total number of seats
  def number_of_seats(number_of_rows, row_seat_increment, initial_row_seat_count) do
    last_row_seat_count = initial_row_seat_count + row_seat_increment * (number_of_rows - 1)
    div((last_row_seat_count + initial_row_seat_count) * number_of_rows, 2)

  @doc """
  Gets number of different permutations
  def permutations(number_of_people, number_of_rows, row_seat_increment, initial_row_seat_count) do
    IO.puts("There are #{number_of_people} people.")
    seats_count = number_of_seats(number_of_rows, row_seat_increment, initial_row_seat_count)
    IO.puts("There are #{seats_count} seats in total.")
    IO.puts("Here's how the seats are arranged:")
    visualize_seats(number_of_rows, row_seat_increment, initial_row_seat_count)
    result = safe_k_permutations_of_n(seats_count, number_of_people)

      "Assuming the order of people matters, there are #{result} different ways of seating these people."

number_of_people = 10
number_of_rows = 4
row_seat_increment = 1
initial_row_seat_count = 1


You can really push this.
See how many ways there are of seating 200 people in 5 rows incrementing 3 seats at a time.


You’ve got an Elixir course in your university? That’s awesome! Elixir becoming mainstream?… :wink:


Thank you for your solution! Now I am starting to understand Elixir more.

1 Like

Here is my email:
Could you contact me? I would happily receive some tips or educational material to have better knowledge in Elixir.

1 Like

Yeah! I’m sure we could help each other :grinning_face_with_smiling_eyes: