Skip to content

Instantly share code, notes, and snippets.

@veelenga
Last active June 15, 2022 22:44
Show Gist options
  • Save veelenga/43465e7ea8954b5ca373d8da2e930ee6 to your computer and use it in GitHub Desktop.
Save veelenga/43465e7ea8954b5ca373d8da2e930ee6 to your computer and use it in GitHub Desktop.
My solution for Chop guess exercise (Programming Elixir 1.3)
##############################
##Exercise: ModulesAndFunctions-6
defmodule Chop do
def guess(actual, lo..hi) when (lo <= hi) and (actual in lo..hi) do
current = guessing(lo, hi)
IO.puts "Is it #{current}"
guess(current, actual, lo..hi)
end
defp guess(value, actual, _) when value == actual, do: IO.puts value
defp guess(value, actual, lo.._) when actual < value, do: guess actual, lo..(value - 1)
defp guess(value, actual, _..hi) when actual > value, do: guess actual, (value + 1)..hi
defp guessing(lo, hi), do: lo + div(hi - lo, 2)
end
Chop.guess 273, 1..1000
# Is it 500
# Is it 250
# Is it 375
# Is it 312
# Is it 281
# Is it 265
# Is it 273
# 273
@veelenga
Copy link
Author

veelenga commented May 8, 2017

Yup, that's also a solution πŸ‘

@thenickcox
Copy link

I've been reading the book, and this solution was such an "a-ha!" moment for me when I looked at your pattern matching in the function signature: def guess(actual, lo..hi) when (lo <= hi) and (actual in lo..hi) do. I know that pattern matching instead of control flow is a central idea in Elixir, but coming from Ruby, it's been hard to understand. This example really showcased that language feature. Thanks!

@veelenga
Copy link
Author

Nicely said πŸ‘ . It is good to see more and more people coming to Elixir from Ruby

@pdbradley
Copy link

hey @veelenga, your solution really helped me. I'm coming from 15 years of ruby and it is hard to wrap my old brain around new ideas.

image

But what's up with this? Doesn't your solution do this? What am I misunderstanding? Or is it because your defp functions have 3 params so it is considered totally different?

@veelenga
Copy link
Author

@pdbradley yes, the signature of def and defp functions are different, so they are valid.

Keep in mind, that solution was written 3 years ago, when the language was slightly different :)

@andreyuhai
Copy link

andreyuhai commented Apr 30, 2021

I am a newbie in Elixir coming from Ruby. I'd written my solution for this but I felt like it could be better and then I came across your solution. Brilliant! I'd never thought about matching that range as lo..hi in the function head, I was still doing the matching in the function body. πŸ˜„ I was also doing the guessing in each of the functions separately, your code helped me learn a lot!

@rovshanguliyev
Copy link

Hello, @veelenga ! Although your solution works, I would like to make a couple of notes:

  1. An extra work for the given exercise;
  2. Both your solution and the book author's solution use private functions,
    which seems unfair to me, since this is the topic of the next section.

Thus, the solution can be rewritten as follows:

defmodule Chop do
  def guess(actual, low..high) do
    guessed = div(low + high, 2)
    IO.puts "Is it #{guessed}"
    processing_guessed =
      fn
        n when n == actual -> IO.puts n
        n when n > actual -> guess actual, low..(n - 1)
        n when n < actual -> guess actual, (n + 1)..high
      end
    processing_guessed.(guessed)
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment