caleb-bb
Below, the problem specs:
Given a sequence of integers as an array, determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element from the array.
Note: sequence
a0,a1, …,anis considered to be a strictly increasing ifa0 < a1 < ... < an. Sequence containing only one element is also considered to be strictly increasing.Example
- For
sequence = [1, 3, 2, 1], the output should be
solution(sequence) = false.There is no one element in this array that can be removed in order to get a strictly increasing sequence.- For
sequence = [1, 3, 2], the output should be
solution(sequence) = true.You can remove3from the array to get the strictly increasing sequence[1, 2]. Alternately, you can remove2to get the strictly increasing sequence[1, 3].Input/Output
- [execution time limit] 12 seconds (exs)
- [input] array.integer sequenceGuaranteed constraints:
2 ≤ sequence.length ≤ 105,
-105 ≤ sequence[i] ≤ 105.- [output] booleanReturn
trueif it is possible to remove one element from the array in order to get a strictly increasing sequence, otherwise returnfalse.
Okay, so I wrote this to solve it:
def solution(sequence) do
iterate(sequence, 0)
end
def strictly_increasing?(list) do
list == Enum.uniq(list) |> Enum.sort
end
def iterate(enumerable, index) do
altered = List.delete_at(enumerable, index)
cond do
strictly_increasing?(altered) -> true
index == length(altered) -> false
true -> iterate(enumerable, index+1)
end
end
The problem with my solution is that it works, but it times out on the “submit” tests. Is there any way to speed this up, or do I need to switch to a totally difference algorithm?
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
I’m trying to set up Emacs with elixir-ls via lsp-mode and credo via Flycheck. This should mostly be preconfigured as Flycheck picks up c...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 6 to 1- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
caleb-bb
Thanks! I had previously tried a solution that sets a flag when the first bad result is found, but I wrote it so clumsily it didn’t work. Thank you for explaining the underlying reasoning.
Eiji
oh, my bad then
Can you please check the updated version?
When removing
firstfrom unmatched check I have addedpreviousto list in order to perform check properly in that specific case.al2o3cr
Ya know what else has to iterate over the whole list?
List.delete_at, especially when called withlength(list). A quick benchmark:produces the output on my machine:
Even calling
lengthon the input is not desirable, since it has to traverse the list all the way to the end.Calling
List.delete_atas part of a recursion is a quick way to end up in theO(N^2)Bad Place.A different way to think about this problem is to ask the question: what are the outcomes of adding an element to the end of an already almost-increasing list?
To express this with functions, we can use
Enum.reduce_while/3because of the control flow it gives us:The trick with
reduceand friends is to pick the right shape for the “state” data.In this problem, we have two important parts of the state:
This suggests that “state” is a tuple of
{status, last_element}.Now we need an “initial” value. The empty list is almost-increasing, and we know the minimum value for elements is
-105so we can start with a value that will always be less than the first element of list:(Note: there’s nothing magical about
:all_increasing, it’s chosen solely for human readability)There are two factors that decide what to do next:
last_elementandelementso let’s use a
case:The first case is easy: if the list is almost-increasing and
elis bigger, then the list is still almost-increasing and we should next look atelement:The next-easiest case is when we’ve already found a “bad” element and we find another one. In that case, it’s time to give up:
Almost as easy: if we’ve seen one wrong element but the current one is increasing, keep going:
The tricky one is if the current element is “bad” but there are no previous errors. In that case, we continue noting that there’s been an error AND skip
el(since it’s bad):Without passing
last_elementin that case, sequences like[1,2,1,2]aren’t correctly detected.Finally, the result of
Enum.reduce_whileis the last accumulator so it needs to be cleaned up into the boolean result.Final code with some cleanup:
caleb-bb
Thanks to you and @cmo for your responses. There are a few test cases that defeat @Eiji’s solution (it incorrectly returns
truewhen given[1,2,1,2]) but it uses tail recursion, which is the right way to go, I think. Here’s what I wound up with:I think that, in cases where you’re dealing with very long lists, the
Enummodule is gonna be too slow much of the time because it always enumerates over the whole list. In cases like that, you want tail recursion instead.Eiji
How about this one?
cmo
Try doing it with recursion, checking each pair (or the one before if you’re skipping this one), rather than checking the entire array every iteration.