Skip to content

Commit

Permalink
Sync alphametics (exercism#846)
Browse files Browse the repository at this point in the history
[no important files changed]
  • Loading branch information
tomasnorre committed Nov 14, 2024
1 parent f196032 commit 473630b
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 65 deletions.
4 changes: 1 addition & 3 deletions exercises/practice/alphametics/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Instructions

Write a function to solve alphametics puzzles.
Given an alphametics puzzle, find the correct solution.

[Alphametics][alphametics] is a puzzle where letters in words are replaced with numbers.

Expand All @@ -26,6 +26,4 @@ This is correct because every letter is replaced by a different number and the w

Each letter must represent a different digit, and the leading digit of a multi-digit number must not be zero.

Write a function to solve alphametics puzzles.

[alphametics]: https://en.wikipedia.org/wiki/Alphametics
2 changes: 1 addition & 1 deletion exercises/practice/alphametics/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
".meta/example.php"
]
},
"blurb": "Write a function to solve alphametics puzzles."
"blurb": "Given an alphametics puzzle, find the correct solution."
}
22 changes: 0 additions & 22 deletions exercises/practice/alphametics/.meta/example.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

class Alphametics
Expand Down
40 changes: 40 additions & 0 deletions exercises/practice/alphametics/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 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"
99 changes: 60 additions & 39 deletions exercises/practice/alphametics/AlphameticsTest.php
Original file line number Diff line number Diff line change
@@ -1,91 +1,107 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

class AlphameticsTest extends PHPUnit\Framework\TestCase
{
private Alphametics $alphametics;

public static function setUpBeforeClass(): void
{
require_once 'Alphametics.php';
}

public function setUp(): void
{
$this->alphametics = new Alphametics();
}

/**
* uuid e0c08b07-9028-4d5f-91e1-d178fead8e1a
* @testdox puzzle with three letters
*/
public function testSolveThreeLetterPuzzle(): void
{
$this->assertEquals(['I' => 1, 'B' => 9, 'L' => 0], $this->alphametics->solve('I + BB == ILL'));
$alphametics = new Alphametics();
$this->assertEquals(['I' => 1, 'B' => 9, 'L' => 0], $alphametics->solve('I + BB == ILL'));
}

/**
* uuid a504ee41-cb92-4ec2-9f11-c37e95ab3f25
* @testdox solution must have unique value for each letter
*/
public function testSolutionsMustHaveUniqueValuesForLetters(): void
{
$this->assertEquals(null, $this->alphametics->solve('A == B'));
$alphametics = new Alphametics();
$this->assertEquals(null, $alphametics->solve('A == B'));
}

/**
* uuid 4e3b81d2-be7b-4c5c-9a80-cd72bc6d465a
* @testdox leading zero solution is invalid
*/
public function testLeadingZerosAreInvalid(): void
{
$this->assertEquals(null, $this->alphametics->solve('ACA + DD == BD'));
$alphametics = new Alphametics();
$this->assertEquals(null, $alphametics->solve('ACA + DD == BD'));
}

/**
* uuid 8a3e3168-d1ee-4df7-94c7-b9c54845ac3a
* @testdox puzzle with two digits final carry
*/
public function testPuzzleWithTwoDigitsFinalCarry(): void
{
$result = $this->alphametics->solve('A + A + A + A + A + A + A + A + A + A + A + B == BCC');
$alphametics = new Alphametics();
$result = $alphametics->solve('A + A + A + A + A + A + A + A + A + A + A + B == BCC');
$this->assertEquals(['A' => 9, 'B' => 1, 'C' => 0], $result);
}

/**
* uuid a9630645-15bd-48b6-a61e-d85c4021cc09
* @testdox puzzle with four letters
*/
public function testPuzzleWithFourLetters(): void
{
$result = $this->alphametics->solve('AS + A == MOM');
$alphametics = new Alphametics();
$result = $alphametics->solve('AS + A == MOM');
$this->assertEquals(['A' => 9, 'S' => 2, 'M' => 1, 'O' => 0], $result);
}

/**
* uuid 3d905a86-5a52-4e4e-bf80-8951535791bd
* @testdox puzzle with six letters
*/
public function testPuzzleWithSixLetters(): void
{
$result = $this->alphametics->solve('NO + NO + TOO == LATE');
$alphametics = new Alphametics();
$result = $alphametics->solve('NO + NO + TOO == LATE');
$this->assertEquals(['N' => 7, 'O' => 4, 'T' => 9, 'L' => 1, 'A' => 0, 'E' => 2], $result);
}

/**
* uuid 4febca56-e7b7-4789-97b9-530d09ba95f0
* @testdox puzzle with seven letters
*/
public function testPuzzleWithSevenLetter(): void
{
$result = $this->alphametics->solve('HE + SEES + THE == LIGHT');
$alphametics = new Alphametics();
$result = $alphametics->solve('HE + SEES + THE == LIGHT');
$this->assertEquals(['E' => 4, 'G' => 2, 'H' => 5, 'I' => 0, 'L' => 1, 'S' => 9, 'T' => 7], $result);
}

/**
* uuid 12125a75-7284-4f9a-a5fa-191471e0d44f
* @testdox puzzle with eight letters
*/
public function testPuzzleWithEightLetters(): void
{
$result = $this->alphametics->solve('SEND + MORE == MONEY');
$alphametics = new Alphametics();
$result = $alphametics->solve('SEND + MORE == MONEY');
$this->assertEquals(['S' => 9, 'E' => 5, 'N' => 6, 'D' => 7, 'M' => 1, 'O' => 0, 'R' => 8, 'Y' => 2], $result);
}

/**
* uuid fb05955f-38dc-477a-a0b6-5ef78969fffa
* @testdox puzzle with ten letters
*/
public function testPuzzleWithTenLetters(): void
{
$result = $this->alphametics->solve('AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE');
$alphametics = new Alphametics();
$result = $alphametics->solve('AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE');
$this->assertEquals([
'A' => 5,
'D' => 3,
Expand All @@ -100,8 +116,13 @@ public function testPuzzleWithTenLetters(): void
], $result);
}

/**
* uuid 9a101e81-9216-472b-b458-b513a7adacf7
* @testdox puzzle with ten letters and 199 addends
*/
public function testPuzzleWithTenLettersAnd199Addends(): void
{
$alphametics = new Alphametics();
$puzzle = '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' .
Expand All @@ -117,7 +138,7 @@ public function testPuzzleWithTenLettersAnd199Addends(): void
' + 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';
$result = $this->alphametics->solve($puzzle);
$result = $alphametics->solve($puzzle);
$this->assertEquals([
'A' => 1,
'E' => 0,
Expand Down

0 comments on commit 473630b

Please sign in to comment.