Sort by

recency

|

8 Discussions

|

  • + 0 comments

    Here is my solution in java, javascript, python, C, C++, Csharp HackerRank Longest Mod Path Problem Solution

  • + 0 comments

    Here is Longest Mod Path problem solution - https://programs.programmingoneonone.com/2021/07/hackerrank-longest-mod-path-problem-solution.html

  • + 0 comments

    My solution, in Javascript: I've used a sorted list for the corridors, and then an "extract" method in order to get all the following corridors to a room using binary search. Then finding the distance from the first room (A) to all the other rooms in the maze. After that, a simple substraction to find all the queried distances: from-X-to-Y equals from-A-to-Y minus from-A-to-X. Since all the rooms are connected (by definition of the problem), any loop found will affect all the distances the same. And the sum of loops equals the GDP between them. Finally the closest you can be to the MOD value is the residue of the difference between your found distance and the MOD value minus one applying the GDP between the maze loop and the given MOD.

    function longestModPath(corridor, queries) {
        const loopSet = (val) => loop=GCD(loop, val)
        const roomSet = (x, val) => {if(room[x]!=null)loopSet(room[x]-val);else roomCount++;room[x]=val}
        const mapCorridor = (c,pos)=>({from:c[0],to:c[1],val:c[2],pos})
        const mapRodirroc = (c,pos)=>({from:c[1],to:c[0],val:-c[2],pos})
        const sortStack = (a,b)=>a.from-b.from||a.to-b.to||a.val-b.val
        const GCD = (A,B) => ((x,y)=>{const _gcd=(a,b)=>{let g;while(b){g=a%b;a=b;b=g;}return(a)};return((y>x)?_gcd(y,x):_gcd(x,y))})(Math.abs(A),Math.abs(B))
        let loop, nextPile
        let stack=corridor.map(mapCorridor).concat(corridor.map(mapRodirroc)).sort(sortStack)
        let pile=extract(1,0,1)
        let room=[null,0], roomCount=1
    // Here I solve all the maze
        do {
            nextPile=[]
            pile.forEach(({from, to, val})=> {
                if (from==to) loopSet(val)
                else {
                    roomSet(to, val + room[from])
                    nextPile = nextPile.concat(extract(to))
                }
            })
            pile = nextPile
        } while (nextPile.length>0)
    // Here I calculate all the queried results
        queries.forEach((q, i, a) =>{
            let m=q[0], n=q[1], mod=q[2], val, resp, looper = GCD(loop, mod)
            if (mod<=1) resp = 0
            else if (looper==1) resp = mod-1
            else {
                val = (m==n)?0:(room[n] - room[m])%looper
                resp = (mod - 1) - (mod - 1 - val) % looper
            }
            a[i] = resp
        })
        return queries
    //Binary search function to get all corridors starting at "where"
        function extract(where, start = 0, end = null) {
            if ((end == null) || (end >= stack.length)) end = stack.length - 1
            if (start < 0) start = 0
            while (start < end) {
                let mid = Math.floor((start + end) / 2)
                let test = stack[mid]
                if (test.from == where) {
                    let ini=mid, fin=mid, resp=[]
                    if(corridor[test.pos]){
                        resp.push(test)
                        corridor[test.pos]=null
                    }
                    while((--ini>=0)&&(test=stack[ini]).from==where){
                        if(corridor[test.pos]){
                            resp.push(test)
                            corridor[test.pos]=null
                        }
                    }
                    while((++fin<stack.length)&&(test=stack[fin]).from==where){
                        if(corridor[test.pos]){
                            resp.push(test)
                            corridor[test.pos]=null
                        }
                    }
                    return resp
                } else if (where < test.from) end = mid - 1
                else start = mid + 1
            }
            return []
        }
    }
    
  • + 0 comments

    Haskell Solution

    import Data.List
    import qualified Data.Set as Set
    import qualified Data.ByteString.Char8 as B
    import Data.IORef
    import Data.Maybe
    import qualified Data.Vector.Mutable as M
    import qualified Data.Vector as V
    import Control.Monad.ST
    import Control.Monad
    import Data.Function
    
    type Room = Int
    type Score = Int
    type Edge = (Room, Score)
    
    main :: IO ()
    main = do
      x <- readWords
      n <- readInt x
      triples <- sequence (replicate n (readInts x 3))
      q <- readInt x
      levels <- sequence (replicate q (readInts x 3))
      mapM_ print (run triples levels)
      
    run :: [[Int]] -> [[Int]] -> [Int]
    run triples levels = map (getScore scores k) levels
      where
        n = length triples
        cds :: V.Vector [Edge] -- corridors
        cds = runST $ do
          v <- M.replicate (succ n) []
          forM_ triples' $ \[a, b, x] -> do
            M.modify v ((b, x) :) a
            M.modify v ((a, -x) :) b
          V.freeze v
        (triples', k') = case getParallelEdge triples of
          Nothing -> (triples, undefined)
          Just (ix, z) -> let (x, (_:y)) = splitAt ix triples in (x ++ y, z)
        scores = runST $ do
          v <- M.new (succ n)
          mapM_ (uncurry $ M.write v) l0
          V.freeze v
        (e0, l0) = walk 0 (Left Set.empty, []) (1, 0)
        k = case e0 of 
          Right (_, x) -> x
          _ -> k'
        walk :: Room -> (Either (Set.Set Room) Edge, [Edge]) -> Edge -> (Either (Set.Set Room) Edge, [Edge])
        walk prev (e, l) (r, m)
          | visited = (e1, l)
          | r == bad = (e, l)
          | otherwise = g $ foldl' (walk r) (e1, (r, m) : l) (map (fmap (+ m)) . filter ((/= prev) . fst) $ cds V.! r)
          where
            (e1, visited, bad) = case e of
              Right (s, _) -> (e, False, s)
              Left set -> if r `Set.member` set
                then (Right (prev, m - fromJust (lookup r l)), True, undefined)
                else (Left (r `Set.insert` set), False, 0)
            g x@(Right _, _) = x
            g (_, l1) = (e, l1)
    
    getParallelEdge :: [[Int]] -> Maybe (Int, Int)
    getParallelEdge triples
      | null zs = Nothing
      | otherwise = Just (ix, k)
      where
        ys = map (\[x, y, z] -> if x < y then [x, y, z] else [y, x, -z]) triples
        xs = sortBy (compare `on` init) ys
        zs = filter (\(x, y) -> init x == init y) $ zip xs (tail xs)
        (a, b) = head zs
        k = last b - last a
        Just ix = findIndex (\[x, y, _] -> [min x y, max x y] == init a) triples
        
    getScore :: V.Vector Score -> Score -> [Int] -> Int
    getScore scores k [r, r1, md] = md - j + i
      where
        m = (scores V.! r1) - (scores V.! r)
        j = gcd k md
        i = m `mod` j
    getScore _ _ _ = undefined
    
    readWords :: IO (IORef [B.ByteString])
    readWords = fmap ((concatMap B.words) . B.lines) B.getContents >>= newIORef
    
    readInt :: IORef [B.ByteString] -> IO Int
    readInt ref = do
      x <- readIORef ref
      writeIORef ref (tail x)
      return (fst . fromJust . B.readInt . head $ x)
    
    readInts :: IORef [B.ByteString] -> Int -> IO [Int]
    readInts ref n = do
      x <- readIORef ref
      writeIORef ref (drop n x)
      return (take n . map (fst . fromJust . B.readInt) $ x)
    
  • + 1 comment

    若存在三个环的周长分别是A, B, C,对A、B、C求公约数P,在环A,B,C分别走了i、j、k圈的情况下,走的总距离为i*A + j * B + k * C = P * l 。这里面i, j, k, l都是变量,必定可以调整 i、j、k、 l 的值使 l = n * m + 1,这时 i*A + j * B + k * C = (p * l) % m = p ,每重复一次该(i, j, k, l)数值组合的循环,余数能得到最小的增长p。所以,从点 S 到点 R ,只需求找出其中一条路径的距离,然后让余数按p增长,终能达到最大的余数值。

    Find rings, get circumferences value of rings, than calculate common divisor for them.