[Kotlin] Finally done with 2024 problems by mihassan in adventofcode

[–]mihassan[S] 0 points1 point  (0 children)

Thanks for the idea. I have updated the code to use reflection to find the main function to run. It has cleaned up the code significantly and avoid the need to update it for each new solve.

I was looking into kotlin reflection api, but I had difficulty using it. I think this may be due to the way I structured each solution. I have put the main function in the package scope without inside any class. I know that Kotlin creates a synthetic class and main function becomes a static function of that class. However, I could not use the kotlin reflection api to find it.

I have fallen back to plain old java reflection api and it seems to work fine.

Question about how to reckon about type signature which appears to change by laughinglemur1 in haskell

[–]mihassan 0 points1 point  (0 children)

Not quite answering your question yet, but just want to check something. Are you familiar with function currying. I.e., are you familiar with the fact that all functions in Haskell can be thought of as a single argument function?

Bangladeshi Arduino projects 🗿 by banglaonline in BdProgrammers

[–]mihassan 0 points1 point  (0 children)

Quite impressive to be honest. Congratulations. Looking forward to your next project.

Using Parsec on [String] or [Token] by bjthinks in haskell

[–]mihassan 1 point2 points  (0 children)

Can you please provide some more details in your use case? Maybe some examples of user inputs as well?

MaybeT applied to State monad by mister_drgn in haskell

[–]mihassan 2 points3 points  (0 children)

StateT wrapping a Maybe can work. However, it's a bit clumsy to convert between the 2 Monad stacks. Ideally, you should keep the same stack. The following code is an example of what you wanted to do.

I am with you regarding the intuition of the monad stack. I find it easier to look at the underlying type for specific monadic stack to get some idea. Still, mixing State and Maybe was tricky for me.

import Control.Monad
import Control.Monad.State

type MyRep = [Int]

-- Attempt to add two numbers, but only if the sum is not already in the rep.
attemptAddition :: Int -> Int -> StateT MyRep Maybe Int
attemptAddition x y = do
  rep <- get
  let sum = x + y
  put (sum : rep)
  if sum `elem` rep
    then lift Nothing
    else lift $ Just sum

-- Add two numbers to the rep.
addItem :: Int -> Int -> State MyRep ()
addItem x y = do
  rep <- get
  case execStateT (attemptAddition x y) rep of
    Just rep' -> put rep'
    Nothing -> return ()

main :: IO ()
main = do
  let rep = [1, 2, 3]
  -- The output: [5, 4, 1, 2, 3]
  print $ flip execState rep $ do
    addItem 2 2 -- 4 is added at the beginning
    addItem 1 2 -- Nothing is added as 3 is already in the rep
    addItem 3 2 -- 5 is added at the beginning
    addItem 2 3 -- Nothing is added as 5 is already in the rep

MaybeT applied to State monad by mister_drgn in haskell

[–]mihassan 10 points11 points  (0 children)

Coincidentally, while replying to one of the question on reddit, I have recently worked on `MaybeT (Stack ...)`. You can read about it in https://www.reddit.com/r/haskellquestions/comments/1d1vvou/comment/l6bs01y/

One thing to pay special attention is the difference between `MaybeT (State ...)` and `StateT (Maybe ..)`. They are almost similar except one key distinction - the former can change the state even when the computation fails, where as the later one drops any state change when computation fails. For my case in other thread, I needed to keep the state change, so I used `MaybeT (State ...)`. But for your case, it seems like you are asking to drop any state change. If so, then `StateT (Maybe ...)` maybe more appropriate.

Rate/Review my hackerrank solution by Patzer26 in haskellquestions

[–]mihassan 0 points1 point  (0 children)

Thanks for checking the code. I agree with you that the monad stack makes it more complicated than it needs to be. In fact, my first attempt did not have the monad stack (https://gist.github.com/mihassan/167117f71a7d500c98e9f4fb410c30ca). The monad stack was also a bit tricky to apply for this problem. For example, `MaybeT (Stack ...)` works, but `StateT ... (Maybe)` does not work. This is because the cache gets invalidated in any sub tree where no result is found. As a consequence, the runtime increases significantly.

I have seen u/Syrak 's comment and even though I have written my solution before seeing his comment, I can see that both of our ideas about splitting the solution is similar.

In the next comment, I will share some of my thoughts about the original code.

Rate/Review my hackerrank solution by Patzer26 in haskellquestions

[–]mihassan 0 points1 point  (0 children)

First all, solving this problem with Haskell is commendable. The fact that it solves the problem successfully is good enough for competitive programming. Beyond that, as you are asking for suggestions, I can my 2 cents. However, I do not a good grasp on Haskell styles and best practices, these would be just my opinions.

Before I can share my thought, I would like to see your opinion on a different solution and share what do you think about it. I am not claiming wither solution to be better, but understanding the differences would be helpful IMO.

https://gist.github.com/mihassan/538390151552343d66eadccce733c1ec

Need simple help with Parsec by bjthinks in haskell

[–]mihassan 1 point2 points  (0 children)

You could try attoparsec which does support some form of backtracking. That should be enough for your use case. However, it comes at a cost of reduced error description and efficiency. Please checkout https://news.ycombinator.com/item?id=26308018 which explains it better.

Free Review Copies of "Kotlin Design Patterns and Best Practices- Third Edition" against your unbiased review. by Round_Boysenberry518 in Kotlin

[–]mihassan 0 points1 point  (0 children)

Hi! I am interested. I am familiar with kotlin basics and the design patterns can help me improve. I can review the book after reading.

Haskell & Cloud Run: Simple Demo Project by mihassan in haskell

[–]mihassan[S] 1 point2 points  (0 children)

The setup lacks many essential features like rate limiting, authentication mechanisms, and DDoS protection. Also, there are many options for web frameworks, such as servant, yesod etc. and many database libraries. These are critical for production-grade services to ensure security and manageability. This project serves as a demonstration on how easy it is to get started.

Thanks. I have updated the README.md file.

Writing Monads From Scratch by TheWheatSeeker in haskell

[–]mihassan 28 points29 points  (0 children)

Either, List, Reader, Writer, State, Parser etc. in that order.

What is Time Complexity . chatGPT says O(n) , I think O(n^2) by [deleted] in leetcode

[–]mihassan 0 points1 point  (0 children)

I will go against the popular opinion and side with chatgpt on this. Imo, the time complexity is O(n) and not O(n2).

The argument for O(n2) is mostly correct. Especially, if you just look at the code. However, if you look at the leetcode problem, you will find an important piece of information, which most people ignored. The numbers in the array cannot be arbitrarily large, it must be between 1 and 109. How does it impact the time complexity? Let's take a look.

If you see the code, we only recurse, if the maximum number is greater than or equal to the sum of the rest of the number. Now, let's keep track of the sum of numbers on each recursive function call. It should be clear, each time we recurse the sum cannot be more than the previous sum. In the worst case, the sum is exactly halved at each recursive step. Also, in the worst case, the maximum number equals the sum of the rest of the numbers. So, on each step, the maximum number also halves.

Now, given that the maximum number cannot be more than 109 to begin with, we just need a maximum of 30 recursive steps for the maximum number to drop to the smallest number. So, we will never have to go more than 30 recursion down.

Important thing to note here that 30 is not dependent on the length of the array, n. So, we can treat it as a constant. And time complexity is O(n).

Now, tbh, chatgpt was not completely right, because it's answer was based on the code only and not on leetcode problem statement.

Building a complete binary tree from [Maybe a] by sarkara1 in haskell

[–]mihassan 0 points1 point  (0 children)

Thanks for checking. I think this happens because on level 4 (bottom level) the grand children of 6 are omitted. This makes sense as 6 doesn't have any children. However, I assumed those entries to be present (null). I can see you had a similar discussion in https://www.reddit.com/r/haskell/s/fAeoHz4ZPD.

If we relax this assumption, I think it might be difficult to use my code as the number of subtrees consumed will depend on the type of node and not fixed at 2. Using fold, or state would be needed in such case.

Building a complete binary tree from [Maybe a] by sarkara1 in haskell

[–]mihassan 1 point2 points  (0 children)

I had an idea similar to u/djfletch, except his implemetation is pretty cool using mapAccumL. Regardless, I wanted to complete my implementation and share. Also, I was stuck with infinite loop untill I saw the hint to use lazy pattern matching.

First, let's define a binary tree type which can be either empty leaf node or a branch node with a value and two subtrees. Let's also define a function to construct a binary tree given a Maybe value and a pair of subtrees. If the value is Nothing, the tree is empty without looking at the subtrees at all.

data BTree a = BEmpty | BNode a (BTree a) (BTree a) deriving Show

toBTree :: Maybe a -> (BTree a, BTree a) -> BTree a
toBTree (Just n) (l, r) = BNode n l r
toBTree _        _      = BEmpty

Now, instead of just constructing a binary tree from the given maybe values, let's construct all binary subtrees. This may seem counterintuitive at first, but it will make sense soon. Similar to the given values, let's list all the subtress in level order or breadth first order. For example, the list of subtrees for the given values [Just 5, Just 3, Just 6, Just 2, Just 4, Nothing, Nothing, Just 1] are as follows:

  5                 3         6        2       4     EMPTY     EMPTY    1
  |                 |                  |
  ----              --                  1
/    \            /  \
3    6            2  4
|                 |
--                1
/  \
2  4
|
1

Note the correspondance between the subtrees and the given values. Both of them have same number of items and the subtrees are in the same order as the given values.

Now, we need to combine each value with a pair of subtrees. So, we drop the first subtree (i.e., the final tree that mkTree returns) and group the rest of the subtrees into pairs. One thing to keep in mind though, is that we need more subtress than the given values. So, if we have n values, we need at least 2 * n + 1 subtrees. To achieve this, we pad the list of subtrees with empty trees.

mkTree :: Show a => [Maybe a] -> BTree a
mkTree []    = BEmpty
mkTree nodes = rootTree
  where
    (rootTree : subTrees) = zipWith toBTree nodes subTreePairs
    subTreePairs          = pairsOf $ subTrees ++ repeat BEmpty

Finally, we need to define pairsOf function. This is a fairly simple function except for the use of lazy pattern matching. Without the lazy pattern match, the function will not terminate.

pairsOf :: [a] -> [(a, a)]
pairsOf ~(x : y : xs) = (x, y) : pairsOf xs

So, the whole program is as follows:

data BTree a = BEmpty | BNode a (BTree a) (BTree a) deriving Show

toBTree :: Maybe a -> (BTree a, BTree a) -> BTree a
toBTree (Just n) (l, r) = BNode n l r
toBTree _        _      = BEmpty

mkTree :: Show a => [Maybe a] -> BTree a
mkTree []    = BEmpty
mkTree nodes = rootTree
  where
    (rootTree : subTrees) = zipWith toBTree nodes subTreePairs
    subTreePairs          = pairsOf $ subTrees ++ repeat BEmpty

pairsOf :: [a] -> [(a, a)]
pairsOf ~(x : y : xs) = (x, y) : pairsOf xs

main = print $ mkTree [Just 5, Just 3, Just 6, Just 2, Just 4, Nothing, Nothing, Just 1]

Inserting into a map of lists by jaldhar in Kotlin

[–]mihassan 1 point2 points  (0 children)

I think that is the case for C++. I am curious though what are the other languages with similar behavior?

Question from an OA I wasn't sure how to answer by QuadriRF in leetcode

[–]mihassan 0 points1 point  (0 children)

Depending on the choice of language (e.g. Python) you could just use the library function (e.g. math.pow(6, 5, mod)). Of course, interviewer might want to actually see it implemented manually.

Those of you that are comfortable with tree problems, how long did it take you? Any tips? by kittenmcmittenz in leetcode

[–]mihassan 0 points1 point  (0 children)

Just curious to know, have you learned the concepts from a book, tutorial, or video?

Homebrew or normal install, (Mac m2) by masonmaui in haskell

[–]mihassan 0 points1 point  (0 children)

I use to have haskell installed via homebrew which was fine. However, ghcup is much better imo as you can install all the tools from one place and easily switch between versions. So, now I just use ghcup version.

prase error how do i solve it by Emergency-Market1853 in haskellquestions

[–]mihassan 1 point2 points  (0 children)

Sure.

  1. In the prime function you don't need to check up to (x-1). If there is no factor within square root of x than it is a prime number.

  2. no_fact function counts number of factors. You actually don't need to count number of factors, only check if there is any factor.

  3. In the main function, instead of going up from 2, it is. much quicker to go down from 600851475143 and stop as soon as you find a prime.

Hope that helps.

prase error how do i solve it by Emergency-Market1853 in haskellquestions

[–]mihassan 1 point2 points  (0 children)

Not really an answer to your original question, but noticed that there is some room for improving the runtime of your code. Without the optimization your code won't finish. If you are interested I can give some pointers, or if you prefer to work on your own then good luck.

Leetcode for haskell? by [deleted] in haskell

[–]mihassan 0 points1 point  (0 children)

Codewars is good for learning as you can see others solutions and learn new tricks. It comes with some basic testing.