Skip to content

Commit

Permalink
feat: add gleam support to grep challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
ryan-gang committed May 30, 2024
1 parent 032f02b commit 6f96b5b
Show file tree
Hide file tree
Showing 27 changed files with 510 additions and 0 deletions.
1 change: 1 addition & 0 deletions compiled_starters/gleam/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
4 changes: 4 additions & 0 deletions compiled_starters/gleam/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.beam
*.ez
/build
erl_crash.dump
39 changes: 39 additions & 0 deletions compiled_starters/gleam/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/grep.png)

This is a starting point for Gleam solutions to the
["Build Your Own grep" Challenge](https://app.codecrafters.io/courses/grep/overview).

[Regular expressions](https://en.wikipedia.org/wiki/Regular_expression)
(Regexes, for short) are patterns used to match character combinations in
strings. [`grep`](https://en.wikipedia.org/wiki/Grep) is a CLI tool for
searching using Regexes.

In this challenge you'll build your own implementation of `grep`. Along the way
we'll learn about Regex syntax, how parsers/lexers work, and how regular
expressions are evaluated.

**Note**: If you're viewing this repo on GitHub, head over to
[codecrafters.io](https://codecrafters.io) to try the challenge.

# Passing the first stage

The entry point for your `grep` implementation is in `src/grep.gleam`. Study and
uncomment the relevant code, and push your changes to pass the first stage:

```sh
git add .
git commit -m "pass 1st stage" # any msg
git push origin master
```

Time to move on to the next stage!

# Stage 2 & beyond

Note: This section is for stages 2 and beyond.

1. Ensure you have `gleam (1.0)` installed locally
1. Run `./your_grep.sh` to run your program, which is implemented in
`src/grep.gleam`.
1. Commit your changes and run `git push origin master` to submit your solution
to CodeCrafters. Test output will be streamed to your terminal.
11 changes: 11 additions & 0 deletions compiled_starters/gleam/codecrafters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Set this to true if you want debug logs.
#
# These can be VERY verbose, so we suggest turning them off
# unless you really need them.
debug: false

# Use this to change the Gleam version used to run your code
# on Codecrafters.
#
# Available versions: gleam-1.0
language_pack: gleam-1.0
22 changes: 22 additions & 0 deletions compiled_starters/gleam/gleam.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name = "grep"
version = "1.0.0"

# Fill out these fields if you intend to generate HTML documentation or publish
# your project to the Hex package manager.
#
# description = ""
# licences = ["Apache-2.0"]
# repository = { type = "github", user = "username", repo = "project" }
# links = [{ title = "Website", href = "https://gleam.run" }]
#
# For a full reference of all the available options, you can have a look at
# https://gleam.run/writing-gleam/gleam-toml/.

[dependencies]
gleam_erlang = "~> 0.25"
gleam_stdlib = "~> 0.34 or ~> 1.0"
argv = ">= 1.0.2 and < 2.0.0"
file_streams = ">= 0.4.2 and < 1.0.0"

[dev-dependencies]
gleeunit = "~> 1.0"
17 changes: 17 additions & 0 deletions compiled_starters/gleam/manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# This file was generated by Gleam
# You typically do not need to edit this file

packages = [
{ name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" },
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
{ name = "file_streams", version = "0.4.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "file_streams", source = "hex", outer_checksum = "86775D2F36B74C54C64CA9080ACA9B9CF4655759E8D3E87E1A2EA9B0FA8D0804" },
{ name = "gleam_stdlib", version = "0.37.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5398BD6C2ABA17338F676F42F404B9B7BABE1C8DC7380031ACB05BBE1BCF3742" },
{ name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" },
]

[requirements]
argv = { version = ">= 1.0.2 and < 2.0.0" }
gleam_erlang = { version = "~> 0.25" }
file_streams = { version = ">= 0.4.2 and < 1.0.0" }
gleam_stdlib = { version = "~> 0.34 or ~> 1.0" }
gleeunit = { version = "~> 1.0" }
38 changes: 38 additions & 0 deletions compiled_starters/gleam/src/grep.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import argv
import gleam/io
import gleam/string
import gleam/erlang

pub fn main() {
// You can use print statements as follows for debugging, they'll be visible when running tests.
io.println("Logs from your program will appear here!")

// Uncomment this to pass the first stage
// let args = argv.load().arguments
// let assert Ok(input_line) = erlang.get_line("")
// case args {
// ["-E", pattern, ..] -> {
// case match_pattern(input_line, pattern) {
// True -> exit(0)
// False -> exit(1)
// }
// io.println("Success")
// }
// _ -> {
// io.println("Expected first argument to be '-E'")
// }
// }
}

fn match_pattern(input_line: String, pattern: String) -> Bool {
case string.length(pattern) {
1 -> string.contains(input_line, pattern)
_ -> {
io.println("Unhandled pattern: " <> pattern)
False
}
}
}

@external(erlang, "erlang", "halt")
pub fn exit(code: Int) -> Int
8 changes: 8 additions & 0 deletions compiled_starters/gleam/your_grep.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
#
# DON'T EDIT THIS!
#
# CodeCrafters uses this file to test your code. Don't make any changes here!
#
# DON'T EDIT THIS!
exec gleam run -- "$@"
5 changes: 5 additions & 0 deletions dockerfiles/gleam-1.0.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM ghcr.io/gleam-lang/gleam:v1.0.0-erlang-alpine

# Pre-compile steps
RUN printf "cd \${CODECRAFTERS_SUBMISSION_DIR} && gleam build" > /codecrafters-precompile.sh
RUN chmod +x /codecrafters-precompile.sh
1 change: 1 addition & 0 deletions solutions/gleam/01-cq2/code/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
4 changes: 4 additions & 0 deletions solutions/gleam/01-cq2/code/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.beam
*.ez
/build
erl_crash.dump
39 changes: 39 additions & 0 deletions solutions/gleam/01-cq2/code/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/grep.png)

This is a starting point for Gleam solutions to the
["Build Your Own grep" Challenge](https://app.codecrafters.io/courses/grep/overview).

[Regular expressions](https://en.wikipedia.org/wiki/Regular_expression)
(Regexes, for short) are patterns used to match character combinations in
strings. [`grep`](https://en.wikipedia.org/wiki/Grep) is a CLI tool for
searching using Regexes.

In this challenge you'll build your own implementation of `grep`. Along the way
we'll learn about Regex syntax, how parsers/lexers work, and how regular
expressions are evaluated.

**Note**: If you're viewing this repo on GitHub, head over to
[codecrafters.io](https://codecrafters.io) to try the challenge.

# Passing the first stage

The entry point for your `grep` implementation is in `src/grep.gleam`. Study and
uncomment the relevant code, and push your changes to pass the first stage:

```sh
git add .
git commit -m "pass 1st stage" # any msg
git push origin master
```

Time to move on to the next stage!

# Stage 2 & beyond

Note: This section is for stages 2 and beyond.

1. Ensure you have `gleam (1.0)` installed locally
1. Run `./your_grep.sh` to run your program, which is implemented in
`src/grep.gleam`.
1. Commit your changes and run `git push origin master` to submit your solution
to CodeCrafters. Test output will be streamed to your terminal.
11 changes: 11 additions & 0 deletions solutions/gleam/01-cq2/code/codecrafters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Set this to true if you want debug logs.
#
# These can be VERY verbose, so we suggest turning them off
# unless you really need them.
debug: false

# Use this to change the Gleam version used to run your code
# on Codecrafters.
#
# Available versions: gleam-1.0
language_pack: gleam-1.0
22 changes: 22 additions & 0 deletions solutions/gleam/01-cq2/code/gleam.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name = "grep"
version = "1.0.0"

# Fill out these fields if you intend to generate HTML documentation or publish
# your project to the Hex package manager.
#
# description = ""
# licences = ["Apache-2.0"]
# repository = { type = "github", user = "username", repo = "project" }
# links = [{ title = "Website", href = "https://gleam.run" }]
#
# For a full reference of all the available options, you can have a look at
# https://gleam.run/writing-gleam/gleam-toml/.

[dependencies]
gleam_erlang = "~> 0.25"
gleam_stdlib = "~> 0.34 or ~> 1.0"
argv = ">= 1.0.2 and < 2.0.0"
file_streams = ">= 0.4.2 and < 1.0.0"

[dev-dependencies]
gleeunit = "~> 1.0"
17 changes: 17 additions & 0 deletions solutions/gleam/01-cq2/code/manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# This file was generated by Gleam
# You typically do not need to edit this file

packages = [
{ name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" },
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
{ name = "file_streams", version = "0.4.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "file_streams", source = "hex", outer_checksum = "86775D2F36B74C54C64CA9080ACA9B9CF4655759E8D3E87E1A2EA9B0FA8D0804" },
{ name = "gleam_stdlib", version = "0.37.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5398BD6C2ABA17338F676F42F404B9B7BABE1C8DC7380031ACB05BBE1BCF3742" },
{ name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" },
]

[requirements]
argv = { version = ">= 1.0.2 and < 2.0.0" }
gleam_erlang = { version = "~> 0.25" }
file_streams = { version = ">= 0.4.2 and < 1.0.0" }
gleam_stdlib = { version = "~> 0.34 or ~> 1.0" }
gleeunit = { version = "~> 1.0" }
34 changes: 34 additions & 0 deletions solutions/gleam/01-cq2/code/src/grep.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import argv
import gleam/io
import gleam/string
import gleam/erlang

pub fn main() {
let args = argv.load().arguments
let assert Ok(input_line) = erlang.get_line("")
case args {
["-E", pattern, ..] -> {
case match_pattern(input_line, pattern) {
True -> exit(0)
False -> exit(1)
}
io.println("Success")
}
_ -> {
io.println("Expected first argument to be '-E'")
}
}
}

fn match_pattern(input_line: String, pattern: String) -> Bool {
case string.length(pattern) {
1 -> string.contains(input_line, pattern)
_ -> {
io.println("Unhandled pattern: " <> pattern)
False
}
}
}

@external(erlang, "erlang", "halt")
pub fn exit(code: Int) -> Int
8 changes: 8 additions & 0 deletions solutions/gleam/01-cq2/code/your_grep.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
#
# DON'T EDIT THIS!
#
# CodeCrafters uses this file to test your code. Don't make any changes here!
#
# DON'T EDIT THIS!
exec gleam run -- "$@"
53 changes: 53 additions & 0 deletions solutions/gleam/01-cq2/diff/src/grep.gleam.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@@ -1,38 +1,34 @@
import argv
import gleam/io
import gleam/string
import gleam/erlang

pub fn main() {
- // You can use print statements as follows for debugging, they'll be visible when running tests.
- io.println("Logs from your program will appear here!")
-
- // Uncomment this to pass the first stage
- // let args = argv.load().arguments
- // let assert Ok(input_line) = erlang.get_line("")
- // case args {
- // ["-E", pattern, ..] -> {
- // case match_pattern(input_line, pattern) {
- // True -> exit(0)
- // False -> exit(1)
- // }
- // io.println("Success")
- // }
- // _ -> {
- // io.println("Expected first argument to be '-E'")
- // }
- // }
+ let args = argv.load().arguments
+ let assert Ok(input_line) = erlang.get_line("")
+ case args {
+ ["-E", pattern, ..] -> {
+ case match_pattern(input_line, pattern) {
+ True -> exit(0)
+ False -> exit(1)
+ }
+ io.println("Success")
+ }
+ _ -> {
+ io.println("Expected first argument to be '-E'")
+ }
+ }
}

fn match_pattern(input_line: String, pattern: String) -> Bool {
case string.length(pattern) {
1 -> string.contains(input_line, pattern)
_ -> {
io.println("Unhandled pattern: " <> pattern)
False
}
}
}

@external(erlang, "erlang", "halt")
pub fn exit(code: Int) -> Int
29 changes: 29 additions & 0 deletions solutions/gleam/01-cq2/explanation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
The entry point for your grep implementation is in `src/grep.gleam`.

Study and uncomment the relevant code:

```gleam
// Uncomment this to pass the first stage
let args = argv.load().arguments
let assert Ok(input_line) = erlang.get_line("")
case args {
["-E", pattern, ..] -> {
case match_pattern(input_line, pattern) {
True -> exit(0)
False -> exit(1)
}
io.println("Success")
}
_ -> {
io.println("Expected first argument to be '-E'")
}
}
```

Push your changes to pass the first stage:

```
git add .
git commit -m "pass 1st stage" # any msg
git push origin master
```
Loading

0 comments on commit 6f96b5b

Please sign in to comment.