-- --------------------------------------------------------------------------
--          Haskell programs for some sequences in connection with
--            Zorach additive triangle (https://oeis.org/A035312)
-- --------------------------------------------------------------------------

import Data.Set (Set, singleton, member, insert)
import Data.List (delete, elemIndex, findIndex)
import Data.Maybe (fromJust)
import OEISaux (bFile', bFileFun)

a035312 :: Int -> Int -> Integer
a035312 n k = a035312_row n !! k

a035311, a035313, a189713 :: Int -> Integer
a035311 = head . a035312_row 
a035313 = last . a035312_row 
a189713 n = a035312_row (2*n) !! n

a189714 :: Int -> Integer
a189714 = sum . a035312_row 

a035358, a072038, a072039 :: Integer -> Int
a035358 n = succ $ fromJust $ elemIndex n a035312_list
a072038 n = succ $ fromJust $ elemIndex n $ a035312_row $ a072039' n
a072039' n = fromJust $ findIndex (n `elem`) zorach
a072039 = succ . a072039'

a035312_row :: Int -> [Integer]
a035312_row n = zorach !! n

a035312_list :: [Integer]
a035312_list = concat zorach

zorach :: [[Integer]] 
zorach = [1] : (z [1] [2..] $ singleton 1) where 

  z :: [Integer] -> [Integer] -> Set Integer -> [[Integer]] 
  z row waiting obtained = 
    row' : z row' 
             (foldl (flip delete) waiting row') 
             (foldl (flip insert) obtained row') where 

      row' :: [Integer] 
      row' = next waiting 
         
      next :: [Integer] -> [Integer] 
      next (w:ws) 
         | (head row + w) `member` obtained = next ws 
         | otherwise                        = try row [w] 

           where try :: [Integer] -> [Integer] -> [Integer] 
                 try [] ys                 = reverse ys 
                 try (x:xs) (y:ys) 
                    | y' `member` obtained = next ws 
                    | otherwise            = try xs (y' : y : ys) 
                      where y' = x + y 
     
bFiles :: IO ()
bFiles = do
  b035312; b035311; b035313; b189713; b189714; b035358; b072038; b072039 

b035312, b035311, b035313, b189713, 
  b189714, b035358, b072038, b072039 :: IO ()
b035312 = bFile' "A035312" (concat $ take 151 zorach) 0  -- b035312.txt 274KB
b035311 = bFileFun "A035311" a035311 0 1000              -- b035311.txt  12KB
b035313 = bFileFun "A035313" a035313 0 1000              -- b035313.txt 160KB
b189713 = bFileFun "A189713" a189713 0 500               -- b189713.txt  45KB
b189714 = bFileFun "A189714" a189714 0 1000              -- b189714.txt 160KB
b035358 = bFileFun "A035358" a035358 1 1000              -- b035358.txt  12KB
b072038 = bFileFun "A072038" a072038 1 1000              -- b072038.txt   8KB
b072039 = bFileFun "A072039" a072039 1 1000              -- b072039.txt   8KB

--                     (117.52 secs), interpreted on GHCi, Mac OS X, 2.66 GHz
-- --------------------------------------------------------------------------
--                                            Reinhard Zumkeller, Apr 30 2011
--                                               reinhard.zumkeller@gmail.com