# What is the best way to do minimum_swaping in Elixir.

I am trying to do a minimum swap with the script below.

Script:
def minimum_swaps(list) when is_list(list) do
t = minimum_swaps_iter(list)
if t == list, do: t, else: minimum_swaps(t)
end

def minimum_swaps_iter([y, x | t]) when y <x, do: [x | minimum_swaps_iter([y | t])]
def minimum_swaps_iter([y, x | t]), do: [y | minimum_swaps_iter([x | t])]
def minimum_swaps_iter(list), do: list

Below is my sample test:

use ExUnit.Case
import Challenge, only: [minimum_swaps: 1]

test “should handle single swap” do
assert minimum_swaps([3, 1, 2]) == 1
end

test “should handle multiple swaps” do
assert minimum_swaps([3, 1, 2, 4]) == 2
end

Results: Failed: Test Results: MinimumSwaps
test should handle single swap

1. test should handle single swap (MinimumSwaps)
test/solution_test.exs:5
Assertion with == failed
code: assert minimum_swaps([3, 1, 2]) == 1
left: [3, 2, 1]
right: 1
stacktrace:
test/solution_test.exs:6: (test)
Completed in 2.9350ms
test should handle multiple swaps
2. test should handle multiple swaps (MinimumSwaps)
test/solution_test.exs:9
Assertion with == failed
code: assert minimum_swaps([3, 1, 2, 4]) == 2
left: [4, 3, 2, 1]
right: 2
stacktrace:
test/solution_test.exs:10: (test)
Completed in 0.0160ms Completed in 2.9510ms

Please , where / what exactly is wrong with my script.? You are returning a sorted list from `minimum_swaps` instead of the count of times it ran. This makes the test fail.

You can maintain a counter and increment it each time you call `minimum_swaps`:

``````def minimum_swaps(list) when is_list(list) do
minimum_swaps(list, 0)
end

defp minimum_swaps(list, counter) do
t = minimum_swaps_iter(list)
if t == list, do: counter, else: minimum_swaps(t, counter + 1)
end
``````

That would probably make the tests pass.

This is exactly what I was about to suggest, except when you run it one of the tests still fails.

``````  1) test should handle multiple swaps (ChallengeTest)
test/challenge_test.exs:9
Assertion with == failed
code:  assert minimum_swaps([3, 1, 2, 4]) == 2
left:  3
right: 2
stacktrace:
test/challenge_test.exs:10: (test)
``````

@millinkan you might need to explain exactly what you expect the code to do if this test is expected to pass

1 Like

I want the swapping to be done once/twice to give an output in the descending order.
`[3, 1, 2] → [3, 2, 1]` . —> 1 onces
`[3, 1, 2, 4] → [3, 4, 2, 1] → [4, 3, 2, 1]` . —> twice 2.

I don’t want to use Enum.reverse().

For the second list your algorithm produces:

``````         y  x               y  x               y  x
iter 1: [3, 1, 2, 4] -> [3, 2, 1, 4] -> [3, 2, 4, 1]
iter 2: [3, 2, 4, 1] -> [3, 2, 4, 1] -> [3, 4, 2, 1]
iter 3: [3, 4, 2, 1] -> [4, 3, 2, 1] -> [4, 3, 2, 1]
``````

So it takes three steps. It needs at least 3 steps to move `4` from right to left.

1 Like

Hmmm…
Thanks Ruslandoga, can you help with a solution that will use the minimum number of swaps.?
So for the second list, 2 steps will be ok, in order to pass the test and then 1 step for the first list.