Day 4: Printing Department

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • VegOwOtenks@lemmy.world
    link
    fedilink
    English
    arrow-up
    2
    ·
    edit-2
    19 days ago

    Futhark

    Only part 1 so far, I want to do part 2 later too.

    This is my first ever futhark program. I have not yet figured out whether string parsing is possible or intended with this language. I used a combination of sed and vim to bring the input into a form futhark can read.

    def neighbors (x: i32, y: i32): [8](i32, i32) = [(x+1, y+1), (x+1, y), (x+1, y-1), (x, y+1), (x, y-1), (x-1, y+1), (x-1, y), (x-1, y-1)]
    
    def count 't (p: t -> bool) (xs: []t) : i32 = reduce (+) 0 (map (\ x -> i32.bool (p x)) xs)
    def count2 't (p: t -> bool) (xs: [][]t) : i32 = reduce (+) 0 (map (count p) xs)
    
    def zipIndices [n] 't (xs: [n]t): [n](i32, t) = zip (map i32.i64 (indices xs)) xs
    def zipIndices2 [n][m] 't (xs: [m][n]t): [m][n]((i32, i32), t) = 
      let innerIndices = map zipIndices xs in
      let innerAndOuterIndices = zipIndices innerIndices in
      map (\ (r, a) -> map (\ (c, x) -> ((r, c), x)) a) innerAndOuterIndices
    
    def countIndexed2 't (p: (i32, i32) -> t -> bool) (xs: [][]t): i32 = 
      let withIndices = zipIndices2 xs in
      count2 (\ (i, x) -> p i x) withIndices
    
    type option 't
      = #single t
      | #empty
    
    def safeIndex 't (xs: []t) (i: i32): option t = if i32.i64 (length xs) > i && i >= 0
      then #single xs[i]
      else #empty
    
    def safeIndex2 't (xs: [][]t) ((r, c): (i32, i32)): option t = 
      match safeIndex xs r
        case #single a -> safeIndex a c
        case #empty -> #empty
    
    def orElse 't (o: option t) (d: t): t =
      match o
        case #single x -> x
        case #empty    -> d
    
    def isAccessible (grid: [][]bool) (p: (i32, i32)) (x:bool): bool =
      let neighborsOptions = map (safeIndex2 grid) (neighbors p) in
      let neighborsFilled = map (`orElse` false) neighborsOptions in
      x && count id neighborsFilled < 4
    
    def mapIndexed2 'a 'b (f: (i32, i32) -> a -> b) (xs: [][]a): [][]b =
      let withIndices = zipIndices2 xs in
      map (map (\ (i, x) -> f i x)) withIndices
    
    def removeAccessibles (grid: [][]bool): [][]bool = mapIndexed2 (\ p x -> x && not (isAccessible grid p x)) grid
    
    def part1 (grid: [][]bool): i32 = countIndexed2 (isAccessible grid) grid
    def part2 (grid: [][]bool): i32 =
      let (reducedGrid, _) = 
        loop (current, last) = (removeAccessibles grid, grid)
        while current != last
        do 
          let current' = removeAccessibles current in
          let last'    = copy current in
          (current', last')
      in count2 id grid - count2 id reducedGrid
    
    def main (grid: [][]bool) = (part1 grid, part2 grid)
    
    

    The highlighting is a bit off because I used ocaml as the language. There is no futhark highlighter (at least in Web UI) yet.
    Edit: Part2

    Also, it runs blazingly fast 🚀 :O, even in sequential C mode