Reverse Factorization
Difficulty: Hard

At the time when Pythagoreanism was prevalent, people were also focused on different ways to factorize a number. In one class, Pythagoras asked his disciples to solve one such problem, _Reverse Factorization_. They were given a set of integer, $A = \{a_1, a_2, \cdots,  a_K\}$, and an integer $N$. They need to find the a way to reach $N$, starting from $1$, and at each step multiplying current value by any element of $A$. But soon they realised that there may exist more than one way to reach $N$. So they decided to find a way in which number of states are least. All of sudden they started on this new problem. People solved it and then started shouting their answer. CRAP!!!. There still exists multiple answers. So finally after much consideration, they settled on the lexicographically smallest series among those solutions which contains the least number of states.

For example, if $N = 12$ and $A = {2, 3, 4}$ then following ways exists  

```
(a) 1  ->  2  ->  4  ->  12
       x2     x2     x3

(b) 1  ->  4  ->  12
       x4     x3

(c) 1  ->  3  ->  12
       x3     x4
```

Here `(a)` is not the minimal state, as it has $4$ states in total. While `(b)` and `(c)` are contenders for answer, both having 3 states, `(c)` is lexicographically smaller than `(b)` so it is the answer. In this case you have to print `1 3 12`. If there exists no way to reach $N$ print `-1`.   


Input Format:
Input contains two lines where first line contains two space separated integer, $N$ and $K$, representing the final value to reach and the size of set $A$, respectively. Next line contains `K` space integers representing the set $A = \{a_1, a_2, \cdots,  a_K\}$.



Output Format:
Print the steps to reach $N$ if it exists. Otherwise print `-1`.



Sample Input:

Sample Output:

Python 3 starter code:

Editorial: Reverse Factorization, Functional Programming Contest - March'14
<style id="MathJax_SVG_styles">.MathJax_SVG_Display {text-align: center; margin: 1em 0em; position: relative; display: block!important; text-indent: 0; max-width: none; max-height: none; min-width: 0; min-height: 0; width: 100%}
.MathJax_SVG .MJX-monospace {font-family: monospace}
.MathJax_SVG .MJX-sans-serif {font-family: sans-serif}
.MathJax_SVG {display: inline; font-style: normal; font-weight: normal; line-height: normal; font-size: 100%; font-size-adjust: none; text-indent: 0; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0; min-height: 0; border: 0; padding: 0; margin: 0}
.MathJax_SVG * {transition: none; -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none}
.mjx-svg-href {fill: blue; stroke: blue}
</style><svg style="display: none;"><defs id="MathJax_SVG_glyphs"></defs></svg><p><a href="/contests/lambda-calculi-mar14/challenges/reverse-factorization">Problem Statement</a> <br>
<strong>Difficulty Level</strong> : Medium-Hard <br>
<strong>Required Knowledge</strong> : Breadth First Search, Simple Maths <br>
<strong>Problem Setter</strong> : <a href="/abhiranjan">Abhiranjan</a>  </p>

<p>It was a decoy problem from the author. Initially it appears to be a factorization problem, but when looking closely it became clear that even a simple BFS can be used to solved this problem. Following two properties should help in solving this problem via BFS.</p>

<ol>
<li>Find the solution with minimum number of steps. Elements of set <em>A = {a<sub>1</sub>, a<sub>2</sub>, ..., a<sub>K</sub>}</em> acts as the edge between an integer/node <em>P</em> and _{P*a<sub>1</sub>, P*a<sub>2</sub>, ..., P*a<sub>K</sub>}_</li>
<li>In order to find the lexicographically smallest solution, we need to enqueue smaller element earlier larger element, i.e., sort the elements of set <em>A</em> before multiplying it with the current number in BFS.</li>
</ol>

<p>PS: Implementing queue and BFS can be a tricky task in few languages.</p>

<p>We need to start from <em>1</em> and then multiplying current number with the elements of <em>A</em>. We need to store the parent node of the current node, as it is required to trace the path from <em>1</em> to <em>N</em>.</p>

<p><strong>Setter's Code</strong></p>

<p>*<em>Language : *</em></p>

<pre><code>import Data.List
import qualified Data.Map as Map

data Queue a = Queue {
      active    :: [a]
    , inactive  :: [a]
  } deriving (Show)

emptyQ :: Queue a
emptyQ = Queue [] []

swapQ :: Queue a -&gt; Queue a
swapQ q = Queue {active = inactive q, inactive = active q}

isEmptyQ :: Queue a -&gt; Bool
isEmptyQ q = null (active q) &amp;&amp; null (inactive q)

peekQ :: Queue a -&gt; (a, Queue a)
peekQ q
  | isEmptyQ q         = error "queue is empty, can't look"
  | null. inactive $ q = (head q1, Queue {active = [], inactive = q1})
  | otherwise          = (head. inactive $ q, q)
      where
        q1 = reverse. active $ q

popQ :: Queue a -&gt; (a, Queue a)
popQ q = (h, q1 {inactive = tail. inactive $ q1})
  where
    (h, q1) = peekQ q

enqueue :: a -&gt; Queue a -&gt; Queue a
enqueue x q = q {active = x: active q}

bfs :: Integer -&gt; [Integer] -&gt; Map.Map Integer Integer
bfs n arr1 =  snd. bfs1 $ (enqueue 1 emptyQ, Map.empty)
  where
    arr = sort arr1
    bfs1 :: (Queue Integer, Map.Map Integer Integer) -&gt; (Queue Integer, Map.Map Integer Integer)
    bfs1 (q, st)
      | isEmptyQ q = (q, st)
      | otherwise  = bfs1 nextState
        where
          (x, q1) = popQ q
          nextState = foldl' foldFunc (q1,st) arr
          foldFunc acc@(qq, sst) mul =
            let
              m = mul*x
            in
              if (m &gt; n) || Map.member m sst
                then acc
                else (enqueue m qq, Map.insert m  x sst)

tracePath :: Integer -&gt; Map.Map Integer Integer -&gt; Maybe [Integer]
tracePath n mp
  | not (Map.member n mp) = Nothing
  | otherwise             = Just. reverse. traverse $ n
    where
      traverse 1 = [1]
      traverse x = x : traverse (Map.findWithDefault (-1) x mp)

printPath :: Maybe [Integer] -&gt; String
printPath Nothing    = show (-1)
printPath (Just arr) = unwords. map show $ arr

main :: IO ()
main = getContents &gt;&gt;= putStrLn. printPath. (\[[n, k], arr] -&gt; tracePath n (bfs n arr)). map (map read. words). lines
</code></pre>

Reference solution (Python):
    import Data.List
    import qualified Data.Map as Map
    
    data Queue a = Queue {
          active    :: [a]
        , inactive  :: [a]
      } deriving (Show)
    
    emptyQ :: Queue a
    emptyQ = Queue [] []
    
    swapQ :: Queue a -> Queue a
    swapQ q = Queue {active = inactive q, inactive = active q}
    
    isEmptyQ :: Queue a -> Bool
    isEmptyQ q = null (active q) && null (inactive q)
    
    peekQ :: Queue a -> (a, Queue a)
    peekQ q
      | isEmptyQ q         = error "queue is empty, can't look"
      | null. inactive $ q = (head q1, Queue {active = [], inactive = q1})
      | otherwise          = (head. inactive $ q, q)
          where
            q1 = reverse. active $ q
    
    popQ :: Queue a -> (a, Queue a)
    popQ q = (h, q1 {inactive = tail. inactive $ q1})
      where
        (h, q1) = peekQ q
    
    enqueue :: a -> Queue a -> Queue a
    enqueue x q = q {active = x: active q}
    
    bfs :: Integer -> [Integer] -> Map.Map Integer Integer
    bfs n arr1 =  snd. bfs1 $ (enqueue 1 emptyQ, Map.empty)
      where
        arr = sort arr1
        bfs1 :: (Queue Integer, Map.Map Integer Integer) -> (Queue Integer, Map.Map Integer Integer)
        bfs1 (q, st)
          | isEmptyQ q = (q, st)
          | otherwise  = bfs1 nextState
            where
              (x, q1) = popQ q
              nextState = foldl' foldFunc (q1,st) arr
              foldFunc acc@(qq, sst) mul =
                let
                  m = mul*x
                in
                  if (m > n) || Map.member m sst
                    then acc
                    else (enqueue m qq, Map.insert m  x sst)
    
    tracePath :: Integer -> Map.Map Integer Integer -> Maybe [Integer]
    tracePath n mp
      | not (Map.member n mp) = Nothing
      | otherwise             = Just. reverse. traverse $ n
        where
          traverse 1 = [1]
          traverse x = x : traverse (Map.findWithDefault (-1) x mp)
    
    printPath :: Maybe [Integer] -> String
    printPath Nothing    = show (-1)
    printPath (Just arr) = unwords. map show $ arr
    
    main :: IO ()
    main = getContents >>= putStrLn. printPath. (\[[n, k], arr] -> tracePath n (bfs n arr)). map (map read. words). lines