Skip to content

Commit b090e36

Browse files
authored
Add resistor-color-trio exercise (#187)
1 parent ac3af1c commit b090e36

17 files changed

Lines changed: 669 additions & 4 deletions

File tree

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,14 @@
650650
"prerequisites": [],
651651
"difficulty": 6
652652
},
653+
{
654+
"slug": "resistor-color-trio",
655+
"name": "Resistor Color Trio",
656+
"uuid": "a3763bb0-6eb4-4cec-8879-6069fb1418a2",
657+
"practices": [],
658+
"prerequisites": [],
659+
"difficulty": 6
660+
},
653661
{
654662
"slug": "book-store",
655663
"name": "Book Store",

exercises/practice/resistor-color-duo/.docs/instructions.append.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ You may consider the absence of an error as a passing test.
2424
If you work locally or in Lean's [online playground][playground], you will get instant feedback on any error reported by `#guard_msgs` through Lean InfoView.
2525

2626
~~~~exercism/caution
27-
For practical reasons, the online test runner does not currently have support to the built-in `Lean` library.
28-
This means that, although you are free to import this library, or any module within it, when working locally or in Lean's online playground, this will cause a solution to fail when submitted to exercism.
27+
The online test runner does not currently support importing the full `Lean` meta-programming library.
28+
While you are free to use any features available in Lean by default, including those within the `Lean` namespace, adding `import Lean` or importing specific modules from the `Lean` namespace will cause your submission to fail when submitted to Exercism.
2929
30-
Note that this library is not necessary to solve the exercise.
30+
Note that importing the Lean library is not necessary to solve this exercise.
3131
~~~~
3232

3333
[macro-reference]: https://lean-lang.org/doc/reference/latest/Notations-and-Macros/#language-extension
3434
[guard-msgs]: https://lean-lang.org/doc/reference/latest/Interacting-with-Lean/#hash-guard_msgs
3535
[eval]: https://lean-lang.org/doc/reference/latest/Interacting-with-Lean/#hash-eval
36-
[playground]: https://live.lean-lang.org/
36+
[playground]: https://live.lean-lang.org/
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Instructions append
2+
3+
## Defining syntax
4+
5+
~~~~exercism/caution
6+
This exercise is intended as a continuation of [`Resistor Color Duo`][resistor-color-duo] and builds upon it.
7+
Although you may solve practice exercises in any order, we encourage you to follow the suggested sequence.
8+
9+
[resistor-color-duo]: https://exercism.org/tracks/lean/exercises/resistor-color-duo
10+
~~~~
11+
12+
In this exercise, you are given syntax for colors already predefined using the `c*` prefix, e.g., `c*black`.
13+
You must then define syntax that associates a sequence of colors to a resistance value with its SI unit, possibly with a metric prefix, according to the instructions.
14+
The colors are within `*[[` and `]]` and separated by `, `, e.g., `*[[c*black, c*yellow, c*violet]]`.
15+
16+
This task will likely require you to use either notations or macros.
17+
You might want to check a [reference][macro-reference].
18+
19+
Because new syntax is expanded at compile time, any test would fail to compile unless all the required syntax is defined.
20+
For this reason, instead of relying on traditional runtime tests, we use [`#guard_msgs`][guard-msgs].
21+
This command compares a given docstring with a message generated by another command, in this case [`#eval`][eval], and reports an error if they are different.
22+
You may consider the absence of an error as a passing test.
23+
24+
If you work locally or in Lean's [online playground][playground], you will get instant feedback on any error reported by `#guard_msgs` through Lean InfoView.
25+
26+
~~~~exercism/note
27+
The resistance value should be output using the unit `Ω` (ohm).
28+
This unicode character can be generated locally on in Lean's online playground with the shortcut `\ohm`.
29+
If you are working in Exercism's online editor, feel free to copy the character from the instructions.
30+
~~~~
31+
32+
~~~~exercism/caution
33+
The online test runner does not currently support importing the full `Lean` meta-programming library.
34+
While you are free to use any features available in Lean by default, including those within the `Lean` namespace, adding `import Lean` or importing specific modules from the `Lean` namespace will cause your submission to fail when submitted to Exercism.
35+
36+
Note that importing the Lean library is not necessary to solve this exercise.
37+
~~~~
38+
39+
[macro-reference]: https://lean-lang.org/doc/reference/latest/Notations-and-Macros/#language-extension
40+
[guard-msgs]: https://lean-lang.org/doc/reference/latest/Interacting-with-Lean/#hash-guard_msgs
41+
[eval]: https://lean-lang.org/doc/reference/latest/Interacting-with-Lean/#hash-eval
42+
[playground]: https://live.lean-lang.org/
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Instructions
2+
3+
If you want to build something using a Raspberry Pi, you'll probably use _resistors_.
4+
For this exercise, you need to know only three things about them:
5+
6+
- Each resistor has a resistance value.
7+
- Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read.
8+
To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values.
9+
- Each band acts as a digit of a number.
10+
For example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15.
11+
In this exercise, you are going to create a helpful program so that you don't have to remember the values of the bands.
12+
The program will take 3 colors as input, and outputs the correct value, in ohms.
13+
The color bands are encoded as follows:
14+
15+
- black: 0
16+
- brown: 1
17+
- red: 2
18+
- orange: 3
19+
- yellow: 4
20+
- green: 5
21+
- blue: 6
22+
- violet: 7
23+
- grey: 8
24+
- white: 9
25+
26+
In Resistor Color Duo you decoded the first two colors.
27+
For instance: orange-orange got the main value `33`.
28+
The third color stands for how many zeros need to be added to the main value.
29+
The main value plus the zeros gives us a value in ohms.
30+
For the exercise it doesn't matter what ohms really are.
31+
For example:
32+
33+
- orange-orange-black would be 33 and no zeros, which becomes 33 ohms.
34+
- orange-orange-red would be 33 and 2 zeros, which becomes 3300 ohms.
35+
- orange-orange-orange would be 33 and 3 zeros, which becomes 33000 ohms.
36+
37+
(If Math is your thing, you may want to think of the zeros as exponents of 10.
38+
If Math is not your thing, go with the zeros.
39+
It really is the same thing, just in plain English instead of Math lingo.)
40+
41+
This exercise is about translating the colors into a label:
42+
43+
> "... ohms"
44+
45+
So an input of `"orange", "orange", "black"` should return:
46+
47+
> "33 ohms"
48+
49+
When we get to larger resistors, a [metric prefix][metric-prefix] is used to indicate a larger magnitude of ohms, such as "kiloohms".
50+
That is similar to saying "2 kilometers" instead of "2000 meters", or "2 kilograms" for "2000 grams".
51+
52+
For example, an input of `"orange", "orange", "orange"` should return:
53+
54+
> "33 kiloohms"
55+
56+
[metric-prefix]: https://en.wikipedia.org/wiki/Metric_prefix
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Extra
2+
3+
open Lean Syntax Macro
4+
5+
namespace ResistorColorTrio
6+
7+
structure ResistorValue where
8+
text : String
9+
10+
instance : Repr ResistorValue where
11+
reprPrec v _ := f!"{v.text}"
12+
13+
macro_rules
14+
| `(*[[ $colors,* ]]) => do
15+
match colors.getElems.take 3 with
16+
| #[c₁, c₂, c₃] =>
17+
match c₁, c₂, c₃ with
18+
| `(ident| $v₁), `(ident| $v₂), `(ident| $v₃) =>
19+
let str ← `(
20+
let total := ((10 * ↑$v₁) + ↑$v₂) * (10 ^ ↑$v₃)
21+
if total >= 1_000_000_000 then
22+
let resistance := total / 1_000_000_000
23+
s!"{resistance} GΩ"
24+
else if total >= 1_000_000 then
25+
let resistance := total / 1_000_000
26+
s!"{resistance} MΩ"
27+
else if total >= 1_000 then
28+
let resistance := total / 1_000
29+
s!"{resistance} kΩ"
30+
else s!"{total} Ω"
31+
)
32+
`(ResistorValue.mk $str)
33+
| _ => Lean.Macro.throwUnsupported
34+
35+
end ResistorColorTrio
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"oxe-i"
4+
],
5+
"files": {
6+
"solution": [
7+
"ResistorColorTrio.lean"
8+
],
9+
"test": [
10+
"ResistorColorTrioTest.lean"
11+
],
12+
"example": [
13+
".meta/Example.lean"
14+
]
15+
},
16+
"blurb": "Convert color codes, as used on resistors, to a human-readable label.",
17+
"source": "Maud de Vries, Erik Schierboom",
18+
"source_url": "https://github.com/exercism/problem-specifications/issues/1549"
19+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[d6863355-15b7-40bb-abe0-bfb1a25512ed]
13+
description = "Orange and orange and black"
14+
15+
[1224a3a9-8c8e-4032-843a-5224e04647d6]
16+
description = "Blue and grey and brown"
17+
18+
[b8bda7dc-6b95-4539-abb2-2ad51d66a207]
19+
description = "Red and black and red"
20+
21+
[5b1e74bc-d838-4eda-bbb3-eaba988e733b]
22+
description = "Green and brown and orange"
23+
24+
[f5d37ef9-1919-4719-a90d-a33c5a6934c9]
25+
description = "Yellow and violet and yellow"
26+
27+
[5f6404a7-5bb3-4283-877d-3d39bcc33854]
28+
description = "Blue and violet and blue"
29+
30+
[7d3a6ab8-e40e-46c3-98b1-91639fff2344]
31+
description = "Minimum possible value"
32+
33+
[ca0aa0ac-3825-42de-9f07-dac68cc580fd]
34+
description = "Maximum possible value"
35+
36+
[0061a76c-903a-4714-8ce2-f26ce23b0e09]
37+
description = "First two colors make an invalid octal number"
38+
39+
[30872c92-f567-4b69-a105-8455611c10c4]
40+
description = "Ignore extra colors"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
declare_syntax_cat colors
2+
syntax "c*" ident : colors
3+
4+
macro_rules
5+
| `(colors|c*black) => `((0 : Fin 10))
6+
| `(colors|c*brown) => `((1 : Fin 10))
7+
| `(colors|c*red) => `((2 : Fin 10))
8+
| `(colors|c*orange) => `((3 : Fin 10))
9+
| `(colors|c*yellow) => `((4 : Fin 10))
10+
| `(colors|c*green) => `((5 : Fin 10))
11+
| `(colors|c*blue) => `((6 : Fin 10))
12+
| `(colors|c*violet) => `((7 : Fin 10))
13+
| `(colors|c*grey) => `((8 : Fin 10))
14+
| `(colors|c*white) => `((9 : Fin 10))
15+
16+
syntax "*[[" colors,* "]]" : term
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Extra
2+
3+
/-
4+
You are given syntax for colors already predefined using the `c*` prefix, e.g., `c*black`.
5+
You must then define syntax that associates a sequence of colors to a number, according to the instructions.
6+
The colors are within `*[[` and `]]` and separated by `, `, e.g., `*[[c*black, c*yellow, c*violet]]`.
7+
8+
Note that the online test runner does not have support to the `Lean` library.
9+
Any solution that uses it will fail when submitted to exercism, even if correct.
10+
This library is not necessary to solve the exercise.
11+
12+
Macros and notations are not qualified by namespace.
13+
For this reason, this exercise does not define a namespace.
14+
-/
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import LeanTest
2+
import ResistorColorTrio
3+
4+
open LeanTest
5+
6+
/--
7+
info: 33 Ω
8+
-/
9+
#guard_msgs(info, drop all) in
10+
#eval *[[c*orange, c*orange, c*black]]
11+
12+
/--
13+
info: 680 Ω
14+
-/
15+
#guard_msgs(info, drop all) in
16+
#eval *[[c*blue, c*grey, c*brown]]
17+
18+
/--
19+
info: 2 kΩ
20+
-/
21+
#guard_msgs(info, drop all) in
22+
#eval *[[c*red, c*black, c*red]]
23+
24+
/--
25+
info: 51 kΩ
26+
-/
27+
#guard_msgs(info, drop all) in
28+
#eval *[[c*green, c*brown, c*orange]]
29+
30+
/--
31+
info: 470 kΩ
32+
-/
33+
#guard_msgs(info, drop all) in
34+
#eval *[[c*yellow, c*violet, c*yellow]]
35+
36+
/--
37+
info: 67 MΩ
38+
-/
39+
#guard_msgs(info, drop all) in
40+
#eval *[[c*blue, c*violet, c*blue]]
41+
42+
/--
43+
info: 0 Ω
44+
-/
45+
#guard_msgs(info, drop all) in
46+
#eval *[[c*black, c*black, c*black]]
47+
48+
/--
49+
info: 99 GΩ
50+
-/
51+
#guard_msgs(info, drop all) in
52+
#eval *[[c*white, c*white, c*white]]
53+
54+
/--
55+
info: 8 Ω
56+
-/
57+
#guard_msgs(info, drop all) in
58+
#eval *[[c*black, c*grey, c*black]]
59+
60+
/--
61+
info: 650 kΩ
62+
-/
63+
#guard_msgs(info, drop all) in
64+
#eval *[[c*blue, c*green, c*yellow, c*orange]]
65+
66+
def main : IO UInt32 := do
67+
runTestSuitesWithExitCode []

0 commit comments

Comments
 (0)