1

I'm working on a program that receives as input a board game as follows:

#####
#_ ##
#  ##
#   #
#  .#
#####
1 4 (player initial position, marked with '_')

After receiving the input, the program transforms it to a [String].

This case, it would be: ["#####", "#_ ##", "# ##", "# #", "# .#", "#####", "1 4"]

How can I access position [1,4] and transform '_' to 'o'? Function must return initial list with that transformation.

Very important note: '_' is never displayed on input, I only used it to make clear where position [1,4] is (therefore, on input we only see a blank space, ' ')

4
  • Have you tried using splitAt? It is a function that splits lists by index, you can then transform an element and merge the result with ++. Commented Oct 31, 2015 at 17:07
  • 4
    if you really want to operate using coordinates/index then lists are the wrong data-structure to begin with - maybe you should have a look at the vector package instead Commented Oct 31, 2015 at 17:17
  • 2
    Aside from this the usual question: what have you tried and where are you stuck? Commented Oct 31, 2015 at 17:18
  • Hint: a String is a list of Char, so if you have a function updateAtPos :: Int -> (a -> a) -> [a] -> [a], then your desired function is \i j -> updateAsPos i (updateAtPos j (const 'o')) Commented Oct 31, 2015 at 21:39

1 Answer 1

1

Seems like one of those tasks you might have to solve for online coding games. As others pointed out, lists are not really suited for dealing with coordinates like this. However, if you are not able to use better libraries (like in coding games) you will have to do some more work.

Here is the code from my ghci session (transforming to a proper program is left as an exercise for the reader...):

let input =  ["#####", "#_ ##", "#  ##", "#   #", "#  .#", "#####", "1 4"]
let reverseInput = reverse input
let position = head reverseInput
let board = tail reverseInput
let posX = read $ takeWhile (/=' ') position :: Int
let posY = read $ takeWhile (/=' ') $ reverse position :: Int
let (unchangedBoard, changedBoard) = splitAt posY board
let (unchangedRow, changedRow) = splitAt posX $ head changedBoard
let newRow = unchangedRow ++ "o" ++ tail changedRow
let newBoard = unchangedBoard ++ [newRow] ++ tail changedBoard
let finalOutput = reverse newBoard
mapM_ putStrLn finalOutput

Also note this code is very brittle as it uses partial functions all over the place (tail, head, read). You could try to use pattern matching instead to make the code more robust.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.