Skip to content
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

feat(stdlib)!: Change array rotation direction #1552

Merged
merged 1 commit into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions compiler/test/stdlib/array.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -377,31 +377,31 @@ assert arr1 == [> 1, 2, 3, 4, 5]

let arr2 = [> 1, 2, 3, 4, 5]
Array.rotate(3, arr2)
assert arr2 == [> 3, 4, 5, 1, 2]
assert arr2 == [> 4, 5, 1, 2, 3]

let arr3 = [> 1, 2, 3, 4, 5]
Array.rotate(-4, arr3)
assert arr3 == [> 5, 1, 2, 3, 4]
assert arr3 == [> 2, 3, 4, 5, 1]

let arr4 = [> 1, 2, 3, 4, 5]
Array.rotate(5, arr4)
assert arr4 == [> 1, 2, 3, 4, 5]

let arr5 = [> 1, 2, 3, 4, 5]
Array.rotate(48, arr5)
assert arr5 == [> 3, 4, 5, 1, 2]
assert arr5 == [> 4, 5, 1, 2, 3]

let arr6 = [> 1, 2, 3, 4, 5]
Array.rotate(-54, arr6)
assert arr6 == [> 5, 1, 2, 3, 4]
assert arr6 == [> 2, 3, 4, 5, 1]

let arr7 = [>]: Array<Number>
Array.rotate(1, arr7)
assert arr7 == [>]

let arr8 = [> "a", "b", "c"]
Array.rotate(1, arr8)
assert arr8 == [> "c", "a", "b"]
assert arr8 == [> "b", "c", "a"]

let arr9 = [>]
Array.rotate(1, arr9)
Expand Down
14 changes: 8 additions & 6 deletions stdlib/array.gr
Original file line number Diff line number Diff line change
Expand Up @@ -978,17 +978,20 @@ export let sort = (comp, array) => {
}

/**
* Rotates array elements by the specified amount to the right, in place.
* Rotates array elements in place by the specified amount to the left, such
* that the `n`th element becomes the first in the array.
*
* If value is negative, array elements will be rotated by the
* specified amount to the left. See examples.
* specified amount to the right. See examples.
*
* @param n: The number of elements to rotate by
* @param arr: The array to be rotated
*
* @example let array = [> 1, 2, 3, 4, 5]; rotate(2, arr); arr == [> 4, 5, 1, 2, 3]
* @example let array = [> 1, 2, 3, 4, 5]; rotate(-1, arr); arr == [> 2, 3, 4, 5, 1]
* @example let array = [> 1, 2, 3, 4, 5]; rotate(2, arr); arr == [> 3, 4, 5, 1, 2]
* @example let array = [> 1, 2, 3, 4, 5]; rotate(-1, arr); arr == [> 5, 1, 2, 3, 4]
* @since v0.4.5
*
* @history v0.6.0: Behavior changed from right-rotation to left-rotation
*/
export let rotate = (n, arr) => {
let rec gcd = (a, b) => {
Expand All @@ -1002,13 +1005,12 @@ export let rotate = (n, arr) => {
let arrLen = length(arr)
if (arrLen > 0) {
let k = n % arrLen
let mut d = -1
let mut j = 0
for (let mut i = 0; i < gcd(arrLen, k); i += 1) {
j = i
let temp = arr[i]
while (true) {
d = (j - k) % arrLen
let d = (j + k) % arrLen
if (d == i) {
break
}
Expand Down
22 changes: 15 additions & 7 deletions stdlib/array.md
Original file line number Diff line number Diff line change
Expand Up @@ -1182,19 +1182,27 @@ Parameters:

### Array.**rotate**

<details disabled>
<summary tabindex="-1">Added in <code>0.4.5</code></summary>
No other changes yet.
<details>
<summary>Added in <code>0.4.5</code></summary>
<table>
<thead>
<tr><th>version</th><th>changes</th></tr>
</thead>
<tbody>
<tr><td><code>next</code></td><td>Behavior changed from right-rotation to left-rotation</td></tr>
</tbody>
</table>
</details>

```grain
rotate : (Number, Array<a>) -> Void
```

Rotates array elements by the specified amount to the right, in place.
Rotates array elements in place by the specified amount to the left, such
that the `n`th element becomes the first in the array.

If value is negative, array elements will be rotated by the
specified amount to the left. See examples.
specified amount to the right. See examples.

Parameters:

Expand All @@ -1206,10 +1214,10 @@ Parameters:
Examples:

```grain
let array = [> 1, 2, 3, 4, 5]; rotate(2, arr); arr == [> 4, 5, 1, 2, 3]
let array = [> 1, 2, 3, 4, 5]; rotate(2, arr); arr == [> 3, 4, 5, 1, 2]
```

```grain
let array = [> 1, 2, 3, 4, 5]; rotate(-1, arr); arr == [> 2, 3, 4, 5, 1]
let array = [> 1, 2, 3, 4, 5]; rotate(-1, arr); arr == [> 5, 1, 2, 3, 4]
```

3 changes: 2 additions & 1 deletion stdlib/immutablearray.gr
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,8 @@ export let sort = (comp, array) => {
}

/**
* Rotates array elements by the specified amount to the left.
* Rotates array elements by the specified amount to the left, such that the
* `n`th element is the first in the new array.
*
* If value is negative, array elements will be rotated by the
* specified amount to the right. See examples.
Expand Down
3 changes: 2 additions & 1 deletion stdlib/immutablearray.md
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,8 @@ No other changes yet.
rotate : (Number, ImmutableArray<a>) -> ImmutableArray<a>
```

Rotates array elements by the specified amount to the left.
Rotates array elements by the specified amount to the left, such that the
`n`th element is the first in the new array.

If value is negative, array elements will be rotated by the
specified amount to the right. See examples.
Expand Down
9 changes: 5 additions & 4 deletions stdlib/list.gr
Original file line number Diff line number Diff line change
Expand Up @@ -512,12 +512,13 @@ export let part = (count, list) => {
}

/**
* Rotates list elements by the specified amount to the left.
* Rotates list elements by the specified amount to the left, such that `n`th
* element is the first in the new list.
*
* If value is negative, list elements will be rotated by the
* specified amount to the right. See examples.
*
* @param count: The number of elements to rotate by
* @param n: The number of elements to rotate by
* @param list: The list to be rotated
*
* @example List.rotate(2, [1, 2, 3, 4, 5]) // [3, 4, 5, 1, 2]
Expand All @@ -527,9 +528,9 @@ export let part = (count, list) => {
*
* @since v0.1.0
*/
export let rotate = (count, list) => {
export let rotate = (n, list) => {
let (beginning, end) =
if (count >= 0) part(count, list) else part(length(list) + count, list)
if (n >= 0) part(n, list) else part(length(list) + n, list)
append(end, beginning)
}

Expand Down
5 changes: 3 additions & 2 deletions stdlib/list.md
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,8 @@ No other changes yet.
rotate : (Number, List<a>) -> List<a>
```

Rotates list elements by the specified amount to the left.
Rotates list elements by the specified amount to the left, such that `n`th
element is the first in the new list.

If value is negative, list elements will be rotated by the
specified amount to the right. See examples.
Expand All @@ -782,7 +783,7 @@ Parameters:

|param|type|description|
|-----|----|-----------|
|`count`|`Number`|The number of elements to rotate by|
|`n`|`Number`|The number of elements to rotate by|
|`list`|`List<a>`|The list to be rotated|

Throws:
Expand Down