-
-
Notifications
You must be signed in to change notification settings - Fork 409
Add practice exercise prism
#1617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Instructions | ||
|
|
||
| Before activating the laser array, you must predict the exact order in which crystals will be hit, identified by their sample IDs. | ||
|
|
||
| ## Example Test Case | ||
|
|
||
| Consider this crystal array configuration: | ||
|
|
||
| ```json | ||
| { | ||
| "start": { "x": 0, "y": 0, "angle": 0 }, | ||
| "prisms": [ | ||
| { "id": 1, "x": 10, "y": 10, "angle": -90 }, | ||
| { "id": 2, "x": 10, "y": 0, "angle": 90 }, | ||
| { "id": 3, "x": 30, "y": 10, "angle": 45 }, | ||
| { "id": 4, "x": 20, "y": 0, "angle": 0 } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| ## What's Happening | ||
|
|
||
| The laser starts at the origin `(0, 0)` and fires horizontally to the right at angle 0°. | ||
| Here's the step-by-step beam path: | ||
|
|
||
| **Step 1**: The beam travels along the x-axis (y = 0) and first encounters **Crystal #2** at position `(10, 0)`. | ||
| This crystal has a refraction angle of 90°, which means it bends the beam perpendicular to its current path. | ||
| The beam, originally traveling at 0°, is now redirected to 90° (straight up). | ||
|
|
||
| **Step 2**: The beam now travels vertically upward from position `(10, 0)` and strikes **Crystal #1** at position `(10, 10)`. | ||
| This crystal has a refraction angle of -90°, bending the beam by -90° relative to its current direction. | ||
| The beam was traveling at 90°, so after refraction it's now at 0° (90° + (-90°) = 0°), traveling horizontally to the right again. | ||
|
|
||
| **Step 3**: From position `(10, 10)`, the beam travels horizontally and encounters **Crystal #3** at position `(30, 10)`. | ||
| This crystal refracts the beam by 45°, changing its direction to 45°. | ||
| The beam continues into empty space beyond the array. | ||
|
|
||
|  |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Introduction | ||
|
|
||
| You're a researcher at **PRISM** (Precariously Redirected Illumination Safety Management), working with a precision laser calibration system that tests experimental crystal prisms. | ||
| These crystals are being developed for next-generation optical computers, and each one has unique refractive properties based on its molecular structure. | ||
| The lab's laser system can damage crystals if they receive unexpected illumination, so precise path prediction is critical. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Used by "mix format" | ||
| [ | ||
| inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # The directory Mix will write compiled artifacts to. | ||
| /_build/ | ||
|
|
||
| # If you run "mix test --cover", coverage assets end up here. | ||
| /cover/ | ||
|
|
||
| # The directory Mix downloads your dependencies sources to. | ||
| /deps/ | ||
|
|
||
| # Where third-party dependencies like ExDoc output generated docs. | ||
| /doc/ | ||
|
|
||
| # Ignore .fetch files in case you like to edit your project deps locally. | ||
| /.fetch | ||
|
|
||
| # If the VM crashes, it generates a dump, let's ignore it too. | ||
| erl_crash.dump | ||
|
|
||
| # Also ignore archive artifacts (built via "mix archive.build"). | ||
| *.ez | ||
|
|
||
| # Ignore package tarball (built via "mix hex.build"). | ||
| prism-*.tar | ||
|
|
||
| # Temporary files, for example, from tests. | ||
| /tmp/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "authors": [ | ||
| "jiegillet" | ||
| ], | ||
| "files": { | ||
| "solution": [ | ||
| "lib/prism.ex" | ||
| ], | ||
| "test": [ | ||
| "test/prism_test.exs" | ||
| ], | ||
| "example": [ | ||
| ".meta/example.ex" | ||
| ] | ||
| }, | ||
| "blurb": "Calculate the path of a laser through refractive prisms.", | ||
| "source": "FraSanga", | ||
| "source_url": "https://github.com/exercism/problem-specifications/pull/2625" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| defmodule Prism do | ||
| @doc """ | ||
| Finds the sequence of prisms that the laser will hit. | ||
| """ | ||
|
|
||
| @type start :: %{angle: number(), x: number(), y: number()} | ||
| @type prism :: %{id: integer(), angle: number(), x: number(), y: number()} | ||
|
|
||
| @spec find_sequence(prisms :: [prism()], start :: start()) :: [integer()] | ||
| def find_sequence(prisms, start) do | ||
| find_next_prism(start, prisms, []) | ||
| end | ||
|
|
||
| @precision 0.01 | ||
| defp find_next_prism(start, prisms, sequence) do | ||
| next_prism = | ||
| prisms | ||
| |> Enum.filter(fn %{x: x, y: y} -> | ||
| different_prism? = x != start.x or y != start.y | ||
|
|
||
| angle_to_prism = :math.atan2(y - start.y, x - start.x) / :math.pi() * 180 | ||
| angle_difference = abs(:math.fmod(angle_to_prism - start.angle, 360)) | ||
|
|
||
| pointing_to_prism? = | ||
| angle_difference < @precision or 360 - angle_difference < @precision | ||
|
|
||
| different_prism? and pointing_to_prism? | ||
| end) | ||
| |> Enum.min_by( | ||
| fn %{x: x, y: y} -> (x - start.x) ** 2 + (y - start.y) ** 2 end, | ||
| &<=/2, | ||
| fn -> nil end | ||
| ) | ||
|
|
||
| case next_prism do | ||
| nil -> | ||
| Enum.reverse(sequence) | ||
|
|
||
| %{id: id, angle: angle, x: x, y: y} -> | ||
| next_start = %{angle: start.angle + angle, x: x, y: y} | ||
| find_next_prism(next_start, prisms, [id | sequence]) | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # This is an auto-generated file. | ||
| # | ||
| # Regenerating this file via `configlet sync` will: | ||
| # - Recreate every `description` key/value pair | ||
| # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications | ||
| # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) | ||
| # - Preserve any other key/value pair | ||
| # | ||
| # As user-added comments (using the # character) will be removed when this file | ||
| # is regenerated, comments can be added via a `comment` key. | ||
|
|
||
| [ec65d3b3-f7bf-4015-8156-0609c141c4c4] | ||
| description = "zero prisms" | ||
|
|
||
| [ec0ca17c-0c5f-44fb-89ba-b76395bdaf1c] | ||
| description = "one prism one hit" | ||
|
|
||
| [0db955f2-0a27-4c82-ba67-197bd6202069] | ||
| description = "one prism zero hits" | ||
|
|
||
| [8d92485b-ebc0-4ee9-9b88-cdddb16b52da] | ||
| description = "going up zero hits" | ||
|
|
||
| [78295b3c-7438-492d-8010-9c63f5c223d7] | ||
| description = "going down zero hits" | ||
|
|
||
| [acc723ea-597b-4a50-8d1b-b980fe867d4c] | ||
| description = "going left zero hits" | ||
|
|
||
| [3f19b9df-9eaa-4f18-a2db-76132f466d17] | ||
| description = "negative angle" | ||
|
|
||
| [96dacffb-d821-4cdf-aed8-f152ce063195] | ||
| description = "large angle" | ||
|
|
||
| [513a7caa-957f-4c5d-9820-076842de113c] | ||
| description = "upward refraction two hits" | ||
|
|
||
| [d452b7c7-9761-4ea9-81a9-2de1d73eb9ef] | ||
| description = "downward refraction two hits" | ||
|
|
||
| [be1a2167-bf4c-4834-acc9-e4d68e1a0203] | ||
| description = "same prism twice" | ||
|
|
||
| [df5a60dd-7c7d-4937-ac4f-c832dae79e2e] | ||
| description = "simple path" | ||
|
|
||
| [8d9a3cc8-e846-4a3b-a137-4bfc4aa70bd1] | ||
| description = "multiple prisms floating point precision" | ||
|
|
||
| [e077fc91-4e4a-46b3-a0f5-0ba00321da56] | ||
| description = "complex path with multiple prisms floating point precision" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| defmodule Prism do | ||
| @doc """ | ||
| Finds the sequence of prisms that the laser will hit. | ||
| """ | ||
|
|
||
| @type start :: %{angle: number(), x: number(), y: number()} | ||
| @type prism :: %{id: integer(), angle: number(), x: number(), y: number()} | ||
|
|
||
| @spec find_sequence(prisms :: [prism()], start :: start()) :: [integer()] | ||
| def find_sequence(prisms, start) do | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| defmodule Prism.MixProject do | ||
| use Mix.Project | ||
|
|
||
| def project do | ||
| [ | ||
| app: :prism, | ||
| version: "0.1.0", | ||
| start_permanent: Mix.env() == :prod, | ||
| deps: deps() | ||
| ] | ||
| end | ||
|
|
||
| # Run "mix help compile.app" to learn about applications. | ||
| def application do | ||
| [ | ||
| extra_applications: [:logger] | ||
| ] | ||
| end | ||
|
|
||
| # Run "mix help deps" to learn about dependencies. | ||
| defp deps do | ||
| [ | ||
| # {:dep_from_hexpm, "~> 0.3.0"}, | ||
| # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} | ||
| ] | ||
| end | ||
| end |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely!