LogoWCF

janka102's Solution

2024

This uses a state machine to parse the input.

import gleam/io
import gleam/int
import gleam/string
import gleam/list
import gleam/result
import gleam/string_builder.{type StringBuilder}

// State machine
// Encapsulates when something is being escaped with a backslash
type Parser {
  Normal(decoded: StringBuilder) // Not escaping
  Escape(decoded: StringBuilder) // Previous char was a backslash
  EscapeChar(decoded: StringBuilder, first: String) // Currently parsing a backslash escape sequence
}

fn try_decode(str: String) {
  use num <- result.try(result.map_error(int.parse(str), fn (_) { "Not a number" }))
  use codepoint_num <- result.try(case num {
    _ if num < 0 || num > 51 -> Error("Invalid escape code")
    n if num > 25 -> Ok(65 + n - 26)
    n -> Ok(97 + n)
  })

  use codepoint <- result.try(result.map_error(string.utf_codepoint(codepoint_num), fn (_) { "Not a codepoint" }))
  Ok(string.from_utf_codepoints([codepoint]))
}

pub fn main() {
  // Copy/paste the contents of the file into the string here
  let input = "..."

  let output = input
  |> string.split("")
  |> list.fold(Normal(string_builder.new()), fn (acc: Parser, c) {
    case c {
      "\\" -> case acc {
        Normal(prev) -> Escape(prev)
        Escape(prev) -> Normal(prev |> string_builder.append(c))
        EscapeChar(_, _) -> panic as "Invalid escape sequence"
      }
      _ -> case acc {
        Normal(prev) -> Normal(prev |> string_builder.append(c))
        Escape(prev) -> EscapeChar(prev, c)
        EscapeChar(prev, first) -> case try_decode(first <> c) {
          Ok(decoded) -> Normal(prev |> string_builder.append(decoded))
          Error(e) -> panic as e
         }
      }
    }
  })

  case output {
    Normal(decoded) -> io.println(decoded |> string_builder.to_string)
    Escape(_) -> panic as "Invalid escape sequence"
    EscapeChar(_, _) -> panic as "Invalid escape sequence"
  }
}

Day 2: Counting Santa's Letters

To help keep things efficient at the North Pole, Santa uses a text intercom system to pass messages. But right now that system is bugging out! It isn’t correctly decoding messages!

Problem: Create a decoder for the following encoding scheme:

There are two files: small_message_encoded.txt, which you can test on, and large_message_encoded.txt, which you should also decode and then share if you can hear “it” to prove you completed the challenge.

Example:
Input:

\33\04\11\11\14, \48\14\17\11\03!

Output:

Hello, World!