Skip to content

Commit

Permalink
alphametics: sync (#1956)
Browse files Browse the repository at this point in the history
[no important files changed]
  • Loading branch information
senekor authored Aug 13, 2024
1 parent 104b472 commit eafd873
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 86 deletions.
19 changes: 19 additions & 0 deletions exercises/practice/alphametics/.meta/test_template.tera
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use alphametics::*;

{% for test in cases %}
#[test]
#[ignore]
fn {{ test.description | snake_case }}() {
let answer = solve({{ test.input.puzzle | json_encode() }});
{%- if test.expected is object %}
let expected = [
{%- for key, val in test.expected %}
('{{ key }}', {{val}}),
{%- endfor %}
].into_iter().collect();
assert_eq!(answer, Some(expected));
{%- else %}
assert_eq!(answer, None);
{%- endif %}
}
{% endfor -%}
40 changes: 37 additions & 3 deletions exercises/practice/alphametics/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in a "comment" key.
# 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.

[e0c08b07-9028-4d5f-91e1-d178fead8e1a]
description = "puzzle with three letters"

[a504ee41-cb92-4ec2-9f11-c37e95ab3f25]
description = "solution must have unique value for each letter"

[4e3b81d2-be7b-4c5c-9a80-cd72bc6d465a]
description = "leading zero solution is invalid"

[8a3e3168-d1ee-4df7-94c7-b9c54845ac3a]
description = "puzzle with two digits final carry"

[a9630645-15bd-48b6-a61e-d85c4021cc09]
description = "puzzle with four letters"

[3d905a86-5a52-4e4e-bf80-8951535791bd]
description = "puzzle with six letters"

[4febca56-e7b7-4789-97b9-530d09ba95f0]
description = "puzzle with seven letters"

[12125a75-7284-4f9a-a5fa-191471e0d44f]
description = "puzzle with eight letters"

[fb05955f-38dc-477a-a0b6-5ef78969fffa]
description = "puzzle with ten letters"

[9a101e81-9216-472b-b458-b513a7adacf7]
description = "puzzle with ten letters and 199 addends"
163 changes: 80 additions & 83 deletions exercises/practice/alphametics/tests/alphametics.rs
Original file line number Diff line number Diff line change
@@ -1,132 +1,129 @@
use std::collections::HashMap;

fn assert_alphametic_solution_eq(puzzle: &str, solution: &[(char, u8)]) {
let answer = alphametics::solve(puzzle);
let solution: HashMap<char, u8> = solution.iter().cloned().collect();
assert_eq!(answer, Some(solution));
}
use alphametics::*;

#[test]
fn with_three_letters() {
assert_alphametic_solution_eq("I + BB == ILL", &[('I', 1), ('B', 9), ('L', 0)]);
fn puzzle_with_three_letters() {
let answer = solve("I + BB == ILL");
let expected = [('I', 1), ('B', 9), ('L', 0)].into_iter().collect();
assert_eq!(answer, Some(expected));
}

#[test]
#[ignore]
fn must_have_unique_value_for_each_letter() {
let answer = alphametics::solve("A == B");
fn solution_must_have_unique_value_for_each_letter() {
let answer = solve("A == B");
assert_eq!(answer, None);
}

#[test]
#[ignore]
fn leading_zero_solution_is_invalid() {
let answer = alphametics::solve("ACA + DD == BD");
assert_eq!(answer, None);
}

#[test]
#[ignore]
fn sum_must_be_wide_enough() {
let answer = alphametics::solve("ABC + DEF == GH");
let answer = solve("ACA + DD == BD");
assert_eq!(answer, None);
}

#[test]
#[ignore]
fn puzzle_with_two_digits_final_carry() {
assert_alphametic_solution_eq(
"A + A + A + A + A + A + A + A + A + A + A + B == BCC",
&[('A', 9), ('B', 1), ('C', 0)],
);
let answer = solve("A + A + A + A + A + A + A + A + A + A + A + B == BCC");
let expected = [('A', 9), ('B', 1), ('C', 0)].into_iter().collect();
assert_eq!(answer, Some(expected));
}

#[test]
#[ignore]
fn puzzle_with_four_letters() {
assert_alphametic_solution_eq("AS + A == MOM", &[('A', 9), ('S', 2), ('M', 1), ('O', 0)]);
let answer = solve("AS + A == MOM");
let expected = [('A', 9), ('S', 2), ('M', 1), ('O', 0)]
.into_iter()
.collect();
assert_eq!(answer, Some(expected));
}

#[test]
#[ignore]
fn puzzle_with_six_letters() {
assert_alphametic_solution_eq(
"NO + NO + TOO == LATE",
&[('N', 7), ('O', 4), ('T', 9), ('L', 1), ('A', 0), ('E', 2)],
);
let answer = solve("NO + NO + TOO == LATE");
let expected = [('N', 7), ('O', 4), ('T', 9), ('L', 1), ('A', 0), ('E', 2)]
.into_iter()
.collect();
assert_eq!(answer, Some(expected));
}

#[test]
#[ignore]
fn puzzle_with_seven_letters() {
assert_alphametic_solution_eq(
"HE + SEES + THE == LIGHT",
&[
('E', 4),
('G', 2),
('H', 5),
('I', 0),
('L', 1),
('S', 9),
('T', 7),
],
);
let answer = solve("HE + SEES + THE == LIGHT");
let expected = [
('E', 4),
('G', 2),
('H', 5),
('I', 0),
('L', 1),
('S', 9),
('T', 7),
]
.into_iter()
.collect();
assert_eq!(answer, Some(expected));
}

#[test]
#[ignore]
fn puzzle_with_eight_letters() {
assert_alphametic_solution_eq(
"SEND + MORE == MONEY",
&[
('S', 9),
('E', 5),
('N', 6),
('D', 7),
('M', 1),
('O', 0),
('R', 8),
('Y', 2),
],
);
let answer = solve("SEND + MORE == MONEY");
let expected = [
('S', 9),
('E', 5),
('N', 6),
('D', 7),
('M', 1),
('O', 0),
('R', 8),
('Y', 2),
]
.into_iter()
.collect();
assert_eq!(answer, Some(expected));
}

#[test]
#[ignore]
fn puzzle_with_ten_letters() {
assert_alphametic_solution_eq(
"AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE",
&[
('A', 5),
('D', 3),
('E', 4),
('F', 7),
('G', 8),
('N', 0),
('O', 2),
('R', 1),
('S', 6),
('T', 9),
],
);
let answer = solve("AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE");
let expected = [
('A', 5),
('D', 3),
('E', 4),
('F', 7),
('G', 8),
('N', 0),
('O', 2),
('R', 1),
('S', 6),
('T', 9),
]
.into_iter()
.collect();
assert_eq!(answer, Some(expected));
}

#[test]
#[ignore]
fn puzzle_with_ten_letters_and_199_addends() {
assert_alphametic_solution_eq(
"THIS + A + FIRE + THEREFORE + FOR + ALL + HISTORIES + I + TELL + A + TALE + THAT + FALSIFIES + ITS + TITLE + TIS + A + LIE + THE + TALE + OF + THE + LAST + FIRE + HORSES + LATE + AFTER + THE + FIRST + FATHERS + FORESEE + THE + HORRORS + THE + LAST + FREE + TROLL + TERRIFIES + THE + HORSES + OF + FIRE + THE + TROLL + RESTS + AT + THE + HOLE + OF + LOSSES + IT + IS + THERE + THAT + SHE + STORES + ROLES + OF + LEATHERS + AFTER + SHE + SATISFIES + HER + HATE + OFF + THOSE + FEARS + A + TASTE + RISES + AS + SHE + HEARS + THE + LEAST + FAR + HORSE + THOSE + FAST + HORSES + THAT + FIRST + HEAR + THE + TROLL + FLEE + OFF + TO + THE + FOREST + THE + HORSES + THAT + ALERTS + RAISE + THE + STARES + OF + THE + OTHERS + AS + THE + TROLL + ASSAILS + AT + THE + TOTAL + SHIFT + HER + TEETH + TEAR + HOOF + OFF + TORSO + AS + THE + LAST + HORSE + FORFEITS + ITS + LIFE + THE + FIRST + FATHERS + HEAR + OF + THE + HORRORS + THEIR + FEARS + THAT + THE + FIRES + FOR + THEIR + FEASTS + ARREST + AS + THE + FIRST + FATHERS + RESETTLE + THE + LAST + OF + THE + FIRE + HORSES + THE + LAST + TROLL + HARASSES + THE + FOREST + HEART + FREE + AT + LAST + OF + THE + LAST + TROLL + ALL + OFFER + THEIR + FIRE + HEAT + TO + THE + ASSISTERS + FAR + OFF + THE + TROLL + FASTS + ITS + LIFE + SHORTER + AS + STARS + RISE + THE + HORSES + REST + SAFE + AFTER + ALL + SHARE + HOT + FISH + AS + THEIR + AFFILIATES + TAILOR + A + ROOFS + FOR + THEIR + SAFE == FORTRESSES",
&[
('A', 1),
('E', 0),
('F', 5),
('H', 8),
('I', 7),
('L', 2),
('O', 6),
('R', 3),
('S', 4),
('T', 9),
],
);
let answer = solve("THIS + A + FIRE + THEREFORE + FOR + ALL + HISTORIES + I + TELL + A + TALE + THAT + FALSIFIES + ITS + TITLE + TIS + A + LIE + THE + TALE + OF + THE + LAST + FIRE + HORSES + LATE + AFTER + THE + FIRST + FATHERS + FORESEE + THE + HORRORS + THE + LAST + FREE + TROLL + TERRIFIES + THE + HORSES + OF + FIRE + THE + TROLL + RESTS + AT + THE + HOLE + OF + LOSSES + IT + IS + THERE + THAT + SHE + STORES + ROLES + OF + LEATHERS + AFTER + SHE + SATISFIES + HER + HATE + OFF + THOSE + FEARS + A + TASTE + RISES + AS + SHE + HEARS + THE + LEAST + FAR + HORSE + THOSE + FAST + HORSES + THAT + FIRST + HEAR + THE + TROLL + FLEE + OFF + TO + THE + FOREST + THE + HORSES + THAT + ALERTS + RAISE + THE + STARES + OF + THE + OTHERS + AS + THE + TROLL + ASSAILS + AT + THE + TOTAL + SHIFT + HER + TEETH + TEAR + HOOF + OFF + TORSO + AS + THE + LAST + HORSE + FORFEITS + ITS + LIFE + THE + FIRST + FATHERS + HEAR + OF + THE + HORRORS + THEIR + FEARS + THAT + THE + FIRES + FOR + THEIR + FEASTS + ARREST + AS + THE + FIRST + FATHERS + RESETTLE + THE + LAST + OF + THE + FIRE + HORSES + THE + LAST + TROLL + HARASSES + THE + FOREST + HEART + FREE + AT + LAST + OF + THE + LAST + TROLL + ALL + OFFER + THEIR + FIRE + HEAT + TO + THE + ASSISTERS + FAR + OFF + THE + TROLL + FASTS + ITS + LIFE + SHORTER + AS + STARS + RISE + THE + HORSES + REST + SAFE + AFTER + ALL + SHARE + HOT + FISH + AS + THEIR + AFFILIATES + TAILOR + A + ROOFS + FOR + THEIR + SAFE == FORTRESSES");
let expected = [
('A', 1),
('E', 0),
('F', 5),
('H', 8),
('I', 7),
('L', 2),
('O', 6),
('R', 3),
('S', 4),
('T', 9),
]
.into_iter()
.collect();
assert_eq!(answer, Some(expected));
}

0 comments on commit eafd873

Please sign in to comment.