Skip to content

Commit 7a5fa23

Browse files
authored
Sync Grains (#930)
[no important files changed]
1 parent b1c62d0 commit 7a5fa23

File tree

9 files changed

+107
-97
lines changed

9 files changed

+107
-97
lines changed

bin/auto-sync.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ flower-field
2929
food-chain
3030
gigasecond
3131
grade-school
32+
grains
3233
hamming
3334
hello-world
3435
high-scores

config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@
919919
"uuid": "3b001897-4052-4dab-84fd-b971a9946e0a",
920920
"practices": [],
921921
"prerequisites": [],
922-
"difficulty": 3,
922+
"difficulty": 4,
923923
"topics": [
924924
"algorithms",
925925
"floating_point_numbers"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Instructions append
2+
3+
## Maximum integer value
4+
5+
According to [the PHP docs][php-int] there is a maximum integer value:
6+
7+
> The size of an `int` is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed).
8+
> 64-bit platforms usually have a maximum value of about 9E18.
9+
> PHP does not support unsigned `int`s.
10+
11+
In other words, PHP cannot express any number `2^63` or greater as an integer.
12+
Some of the tests for this exercise require 64 bit integers (`2^64`) which is beyond the integer size limitation of PHP.
13+
14+
[PHP automatically converts][php-int-to-float] `int`s to `float`s, when the numbers get too big:
15+
16+
> If PHP encounters a number beyond the bounds of the `int` type, it will be interpreted as a `float` instead.
17+
> Also, an operation which results in a number beyond the bounds of the `int` type will return a `float` instead.
18+
19+
But the `float` type [has limited precision][php-float-precision].
20+
And King hates unprecision.
21+
So King decided to expect the results of the calculations as a string which expresses the integer value, rather than expressing the answer as `int` or `float`.
22+
And he wants integer calculations, not just a lazy conversion at the end.
23+
24+
Can you solve this by avoiding numbers that are larger than the language will allow directly?
25+
And please don't use other PHP libraries like `gmp` or `bc`, too.
26+
27+
[php-int]: https://www.php.net/manual/en/language.types.integer.php
28+
[php-int-to-float]: https://www.php.net/manual/en/language.types.integer.php
29+
[php-float-precision]: https://php.net/manual/en/language.types.float.php
Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
11
# Instructions
22

3-
Calculate the number of grains of wheat on a chessboard given that the number
4-
on each square doubles.
3+
Calculate the number of grains of wheat on a chessboard.
54

6-
There once was a wise servant who saved the life of a prince. The king
7-
promised to pay whatever the servant could dream up. Knowing that the
8-
king loved chess, the servant told the king he would like to have grains
9-
of wheat. One grain on the first square of a chess board, with the number
10-
of grains doubling on each successive square.
5+
A chessboard has 64 squares.
6+
Square 1 has one grain, square 2 has two grains, square 3 has four grains, and so on, doubling each time.
117

12-
There are 64 squares on a chessboard (where square 1 has one grain, square 2 has two grains, and so on).
8+
Write code that calculates:
139

14-
Write code that shows:
15-
- how many grains were on a given square, and
10+
- the number of grains on a given square
1611
- the total number of grains on the chessboard
17-
18-
## For bonus points
19-
20-
Did you get the tests passing and the code clean? If you want to, these
21-
are some additional things you could try:
22-
23-
- Optimize for speed.
24-
- Optimize for readability.
25-
26-
Then please share your thoughts in a comment on the submission. Did this
27-
experiment make the code better? Worse? Did you learn anything from it?
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Introduction
2+
3+
There once was a wise servant who saved the life of a prince.
4+
The king promised to pay whatever the servant could dream up.
5+
Knowing that the king loved chess, the servant told the king he would like to have grains of wheat.
6+
One grain on the first square of a chessboard, with the number of grains doubling on each successive square.

exercises/practice/grains/.meta/config.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"arueckauer",
77
"G-Rath",
88
"kytrinyx",
9-
"petemcfarlane"
9+
"petemcfarlane",
10+
"A-O-Emmanuel"
1011
],
1112
"files": {
1213
"solution": [
@@ -20,6 +21,6 @@
2021
]
2122
},
2223
"blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.",
23-
"source": "JavaRanch Cattle Drive, exercise 6",
24-
"source_url": "https://www.javaranch.com/grains.jsp"
24+
"source": "The CodeRanch Cattle Drive, Assignment 6",
25+
"source_url": "https://web.archive.org/web/20240908084142/https://coderanch.com/wiki/718824/Grains"
2526
}

exercises/practice/grains/.meta/example.php

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,5 @@
11
<?php
22

3-
/*
4-
* By adding type hints and enabling strict type checking, code can become
5-
* easier to read, self-documenting and reduce the number of potential bugs.
6-
* By default, type declarations are non-strict, which means they will attempt
7-
* to change the original type to match the type specified by the
8-
* type-declaration.
9-
*
10-
* In other words, if you pass a string to a function requiring a float,
11-
* it will attempt to convert the string value to a float.
12-
*
13-
* To enable strict mode, a single declare directive must be placed at the top
14-
* of the file.
15-
* This means that the strictness of typing is configured on a per-file basis.
16-
* This directive not only affects the type declarations of parameters, but also
17-
* a function's return type.
18-
*
19-
* For more info review the Concept on strict type checking in the PHP track
20-
* <link>.
21-
*
22-
* To disable strict typing, comment out the directive below.
23-
*/
24-
253
declare(strict_types=1);
264

275
/**

exercises/practice/grains/.meta/tests.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,34 @@
33
# so comments can be added in a "comment" key.
44

55
[9fbde8de-36b2-49de-baf2-cd42d6f28405]
6-
description = "1"
6+
description = "grains on square 1"
77

88
[ee1f30c2-01d8-4298-b25d-c677331b5e6d]
9-
description = "2"
9+
description = "grains on square 2"
1010

1111
[10f45584-2fc3-4875-8ec6-666065d1163b]
12-
description = "3"
12+
description = "grains on square 3"
1313

1414
[a7cbe01b-36f4-4601-b053-c5f6ae055170]
15-
description = "4"
15+
description = "grains on square 4"
1616

1717
[c50acc89-8535-44e4-918f-b848ad2817d4]
18-
description = "16"
18+
description = "grains on square 16"
1919

2020
[acd81b46-c2ad-4951-b848-80d15ed5a04f]
21-
description = "32"
21+
description = "grains on square 32"
2222

2323
[c73b470a-5efb-4d53-9ac6-c5f6487f227b]
24-
description = "64"
24+
description = "grains on square 64"
2525

2626
[1d47d832-3e85-4974-9466-5bd35af484e3]
27-
description = "square 0 raises an exception"
27+
description = "square 0 is invalid"
2828

2929
[61974483-eeb2-465e-be54-ca5dde366453]
30-
description = "negative square raises an exception"
30+
description = "negative square is invalid"
3131

3232
[a95e4374-f32c-45a7-a10d-ffec475c012f]
33-
description = "square greater than 64 raises an exception"
33+
description = "square greater than 64 is invalid"
3434

3535
[6eb07385-3659-4b45-a6be-9dc474222750]
3636
description = "returns the total number of grains on the board"

exercises/practice/grains/GrainsTest.php

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,8 @@
11
<?php
22

3-
/*
4-
* By adding type hints and enabling strict type checking, code can become
5-
* easier to read, self-documenting and reduce the number of potential bugs.
6-
* By default, type declarations are non-strict, which means they will attempt
7-
* to change the original type to match the type specified by the
8-
* type-declaration.
9-
*
10-
* In other words, if you pass a string to a function requiring a float,
11-
* it will attempt to convert the string value to a float.
12-
*
13-
* To enable strict mode, a single declare directive must be placed at the top
14-
* of the file.
15-
* This means that the strictness of typing is configured on a per-file basis.
16-
* This directive not only affects the type declarations of parameters, but also
17-
* a function's return type.
18-
*
19-
* For more info review the Concept on strict type checking in the PHP track
20-
* <link>.
21-
*
22-
* To disable strict typing, comment out the directive below.
23-
*/
24-
253
declare(strict_types=1);
264

5+
use PHPUnit\Framework\Attributes\TestDox;
276
use PHPUnit\Framework\TestCase;
287

298
class GrainsTest extends TestCase
@@ -34,73 +13,105 @@ public static function setUpBeforeClass(): void
3413
}
3514

3615
/**
37-
* PHP integers greater than 2^31 (32-bit systems)
38-
* or 2^63 (64-bit) are casted to floats.
39-
* In some cases it may lead to problems
40-
* https://php.net/manual/ru/language.types.float.php#warn.float-precision
41-
*
42-
* Consider King hates floats and demands solution with
43-
* precise integer-only calculations. Don't involve any floats.
44-
* Don't use gmp or any other similar libraries.
45-
* Try to make the solution for virtually any board size.
16+
* uuid: 9fbde8de-36b2-49de-baf2-cd42d6f28405
4617
*/
47-
48-
public function testInput1(): void
18+
#[TestDox('grains on square 1')]
19+
public function testGrainsOnSquare1(): void
4920
{
5021
$this->assertSame('1', square(1));
5122
}
5223

53-
public function testInput2(): void
24+
/**
25+
* uuid: ee1f30c2-01d8-4298-b25d-c677331b5e6d
26+
*/
27+
#[TestDox('grains on square 2')]
28+
public function testGrainsOnSquare2(): void
5429
{
5530
$this->assertSame('2', square(2));
5631
}
5732

58-
public function testInput3(): void
33+
/**
34+
* uuid: 10f45584-2fc3-4875-8ec6-666065d1163b
35+
*/
36+
#[TestDox('grains on square 3')]
37+
public function testGrainsOnSquare3(): void
5938
{
6039
$this->assertSame('4', square(3));
6140
}
6241

63-
public function testInput4(): void
42+
/**
43+
* uuid: a7cbe01b-36f4-4601-b053-c5f6ae055170
44+
*/
45+
#[TestDox('grains on square 4')]
46+
public function testGrainsOnSquare4(): void
6447
{
6548
$this->assertSame('8', square(4));
6649
}
6750

68-
public function testInput16(): void
51+
/**
52+
* uuid: c50acc89-8535-44e4-918f-b848ad2817d4
53+
*/
54+
#[TestDox('grains on square 16')]
55+
public function testGrainsOnSquare16(): void
6956
{
7057
$this->assertSame('32768', square(16));
7158
}
7259

73-
public function testInput32(): void
60+
/**
61+
* uuid: acd81b46-c2ad-4951-b848-80d15ed5a04f
62+
*/
63+
#[TestDox('grains on square 32')]
64+
public function testGrainsOnSquare32(): void
7465
{
7566
$this->assertSame('2147483648', square(32));
7667
}
7768

78-
public function testInput64(): void
69+
/**
70+
* uuid: c73b470a-5efb-4d53-9ac6-c5f6487f227b
71+
*/
72+
#[TestDox('grains on square 64')]
73+
public function testGrainsOnSquare64(): void
7974
{
8075
$this->assertSame('9223372036854775808', square(64));
8176
}
8277

83-
public function testRejectsZero(): void
78+
/**
79+
* uuid: 1d47d832-3e85-4974-9466-5bd35af484e3
80+
*/
81+
#[TestDox('square 0 is invalid')]
82+
public function testSquare0IsInvalid(): void
8483
{
8584
$this->expectException(InvalidArgumentException::class);
8685

8786
square(0);
8887
}
8988

89+
/**
90+
* uuid: 61974483-eeb2-465e-be54-ca5dde366453
91+
*/
92+
#[TestDox('negative square is invalid')]
9093
public function testRejectsNegative(): void
9194
{
9295
$this->expectException(InvalidArgumentException::class);
9396

9497
square(-1);
9598
}
9699

100+
/**
101+
* uuid: a95e4374-f32c-45a7-a10d-ffec475c012f
102+
*/
103+
#[TestDox('square greater than 64 is invalid')]
97104
public function testRejectsGreaterThan64(): void
98105
{
99106
$this->expectException(InvalidArgumentException::class);
100107

101108
square(65);
102109
}
103110

111+
/**
112+
* uuid: 6eb07385-3659-4b45-a6be-9dc474222750
113+
*/
114+
#[TestDox('returns the total number of grains on the board')]
104115
public function testTotal(): void
105116
{
106117
$this->assertSame('18446744073709551615', total());

0 commit comments

Comments
 (0)