Skip to content
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
40 changes: 24 additions & 16 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,14 @@
"prerequisites": [],
"difficulty": 4
},
{
"slug": "nth-prime",
"name": "Nth Prime",
"uuid": "9edd0fda-cc73-40a2-a32c-b16918c65167",
"practices": [],
"prerequisites": [],
"difficulty": 4
},
{
"slug": "pascals-triangle",
"name": "Pascal's Triangle",
Expand Down Expand Up @@ -327,6 +335,14 @@
"prerequisites": [],
"difficulty": 4
},
{
"slug": "saddle-points",
"name": "Saddle Points",
"uuid": "5efb23b7-fa38-4667-a344-4455877beb03",
"practices": [],
"prerequisites": [],
"difficulty": 4
},
{
"slug": "scrabble-score",
"name": "Scrabble Score",
Expand Down Expand Up @@ -607,6 +623,14 @@
"prerequisites": [],
"difficulty": 7
},
{
"slug": "piecing-it-together",
"name": "Piecing It Together",
"uuid": "18f049a1-428b-4364-9d28-28208119b7de",
"practices": [],
"prerequisites": [],
"difficulty": 7
},
{
"slug": "pig-latin",
"name": "Pig Latin",
Expand Down Expand Up @@ -678,22 +702,6 @@
"practices": [],
"prerequisites": [],
"difficulty": 8
},
{
"slug": "nth-prime",
"name": "Nth Prime",
"uuid": "9edd0fda-cc73-40a2-a32c-b16918c65167",
"practices": [],
"prerequisites": [],
"difficulty": 2
},
{
"slug": "saddle-points",
"name": "Saddle Points",
"uuid": "5efb23b7-fa38-4667-a344-4455877beb03",
"practices": [],
"prerequisites": [],
"difficulty": 4
}
]
},
Expand Down
41 changes: 41 additions & 0 deletions exercises/practice/piecing-it-together/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Instructions

Given partial information about a jigsaw puzzle, add the missing pieces.

If the information is insufficient to complete the details, or if given parts are in contradiction, the user should be notified.

The full information about the jigsaw puzzle contains the following parts:

- `pieces`: Total number of pieces
- `border`: Number of border pieces
- `inside`: Number of inside (non-border) pieces
- `rows`: Number of rows
- `columns`: Number of columns
- `aspectRatio`: Aspect ratio of columns to rows
- `format`: Puzzle format, which can be `portrait`, `square`, or `landscape`

For this exercise, you may assume square pieces, so that the format can be derived from the aspect ratio:

- If the aspect ratio is less than 1, it's `portrait`
- If it is equal to 1, it's `square`
- If it is greater than 1, it's `landscape`

## Three examples

### Portrait

A portrait jigsaw puzzle with 6 pieces, all of which are border pieces and none are inside pieces. It has 3 rows and 2 columns. The aspect ratio is 1.5 (3/2).

![A 2 by 3 jigsaw puzzle](https://assets.exercism.org/images/exercises/piecing-it-together/jigsaw-puzzle-2x3.svg)

### Square

A square jigsaw puzzle with 9 pieces, all of which are border pieces except for the one in the center, which is an inside piece. It has 3 rows and 3 columns. The aspect ratio is 1 (3/3).

![A 3 by 3 jigsaw puzzle](https://assets.exercism.org/images/exercises/piecing-it-together/jigsaw-puzzle-3x3.svg)

### Landscape

A landscape jigsaw puzzle with 12 pieces, 10 of which are border pieces and 2 are inside pieces. It has 3 rows and 4 columns. The aspect ratio is 1.333333... (4/3).

![A 4 by 3 jigsaw puzzle](https://assets.exercism.org/images/exercises/piecing-it-together/jigsaw-puzzle-4x3.svg)
6 changes: 6 additions & 0 deletions exercises/practice/piecing-it-together/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Introduction

Your best friend has started collecting jigsaw puzzles and wants to build a detailed catalog of their collection — recording information such as the total number of pieces, the number of rows and columns, the number of border and inside pieces, aspect ratio, and puzzle format.
Even with your powers combined, it takes multiple hours to solve a single jigsaw puzzle with one thousand pieces — and then you still need to count the rows and columns and calculate the remaining numbers manually.
The even larger puzzles with thousands of pieces look quite daunting now.
"There has to be a better way!" you exclaim and sit down in front of your computer to solve the problem.
18 changes: 18 additions & 0 deletions exercises/practice/piecing-it-together/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"root": true,
"extends": "@exercism/eslint-config-javascript",
"env": {
"jest": true
},
"overrides": [
{
"files": [
"*.spec.js"
],
"excludedFiles": [
"custom.spec.js"
],
"extends": "@exercism/eslint-config-javascript/maintainers"
}
]
}
28 changes: 28 additions & 0 deletions exercises/practice/piecing-it-together/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"authors": [
"atk"
],
"files": {
"solution": [
"piecing-it-together.wat"
],
"test": [
"piecing-it-together.spec.js"
],
"example": [
".meta/proof.ci.wat"
],
"invalidator": [
"package.json"
]
},
"blurb": "Fill in missing jigsaw puzzle details from partial data",
"source": "atk just started another 1000-pieces jigsaw puzzle when this idea hit him",
"source_url": "https://github.com/exercism/problem-specifications/pull/2554",
"custom": {
"version.tests.compatibility": "jest-27",
"flag.tests.task-per-describe": false,
"flag.tests.may-run-long": false,
"flag.tests.includes-optional": false
}
}
137 changes: 137 additions & 0 deletions exercises/practice/piecing-it-together/.meta/proof.ci.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
(module
;; formats
(global $landscape (export "landscape") i32 (i32.const 1))
(global $square (export "square") i32 (i32.const 2))
(global $portrait (export "portrait") i32 (i32.const 3))
;; errors
(global $INSUFFICIENT (export "INSUFFICIENT") i32 (i32.const -2))
(global $CONTRADICTORY (export "CONTRADICTORY") i32 (i32.const -3))

;;
;; findColumns - find the columns for puzzles based on pieces, border pieces and format
;;
;; @param {i32} $pieces - total number of pieces
;; @param {i32} $border - number of border pieces
;; @param {i32} $format - see formats globals
;;
;; @returns {i32} number of columns
;;
(func $findColumns (param $pieces i32) (param $border i32) (param $format i32) (result i32)
(local $c i32)
(local.set $c (i32.trunc_f64_u (f64.ceil (f64.sqrt (f64.convert_i32_u (local.get $pieces))))))
(loop $find
(local.set $c (i32.sub (local.get $c) (i32.const 1)))
(br_if $find (i32.and (i32.gt_s (local.get $c) (i32.const 0)) (i32.or
(i32.ne (i32.rem_u (local.get $pieces) (local.get $c)) (i32.const 0))
(i32.ne (i32.shl (i32.add (local.get $c) (i32.div_u (local.get $pieces) (local.get $c))) (i32.const 1))
(i32.add (local.get $border) (i32.const 4)))))))
(select (local.get $c) (i32.div_u (local.get $pieces) (local.get $c))
(i32.eq (local.get $format) (global.get $portrait)))
)

;;
;; jigsawData - find the missing pieces of jigsaw puzzle data
;;
;; @param {i32} $pieces - total number of pieces*
;; @param {i32} $border - number of border pieces*
;; @param {i32} $inside - number of inside pieces*
;; @param {i32} $rows - number of rows*
;; @param {i32} $columns - number of columns*
;; @param {f64} $aspectRatio - aspect ratio between columns and rows*
;; @param {i32} $format - see formats globals*
;;
;; @returns {(i32,i32,i32,i32,i32,f64,i32)} - completed data in the same order**
;;
;; * 0 if not given
;; ** if an error occurs, it replaces the first return value
;;
(func (export "jigsawData") (param $pieces i32) (param $border i32) (param $inside i32)
(param $rows i32) (param $columns i32) (param $aspectRatio f64) (param $format i32)
(result i32 i32 i32 i32 i32 f64 i32)
(local $i i32)
(local $r f64)
(if (i32.eqz (local.get $pieces)) (then
(if (i32.and (i32.ne (local.get $border) (i32.const 0)
(i32.ne (local.get $inside) (i32.const 0))))
(then (local.set $pieces (i32.add (local.get $border) (local.get $inside))))
(else (if (i32.and (i32.ne (local.get $rows) (i32.const 0))
(i32.ne (local.get $columns) (i32.const 0)))
(then (local.set $pieces (i32.mul (local.get $rows) (local.get $columns))))
(else (if (i32.and (i32.ne (local.get $rows) (i32.const 0))
(f64.ne (local.get $aspectRatio) (f64.const 0.0)))
(then (local.set $pieces (i32.mul (local.get $rows) (i32.trunc_f64_u
(f64.mul (local.get $aspectRatio) (f64.convert_i32_u (local.get $rows)))))))
(else (if (i32.and (i32.ne (local.get $columns) (i32.const 0))
(f64.ne (local.get $aspectRatio) (f64.const 0.0)))
(then (local.set $pieces (i32.mul (local.get $rows) (i32.trunc_f64_u
(f64.div (f64.convert_i32_u (local.get $columns)) (local.get $aspectRatio))))))
(else (if (i32.and (i32.ne (local.get $rows) (i32.const 0))
(i32.eq (local.get $format) (global.get $square)))
(then (local.set $pieces (i32.mul (local.get $rows) (local.get $rows))))
(else (if (i32.and (i32.ne (local.get $columns) (i32.const 0))
(i32.eq (local.get $format) (global.get $square)))
(then (local.set $pieces (i32.mul (local.get $columns) (local.get $columns))))
(else (if (i32.and (i32.ne (local.get $inside) (i32.const 0))
(i32.or (i32.eq (local.get $format) (global.get $square))
(f64.eq (local.get $aspectRatio) (f64.const 1.0))))
(then (local.set $i (i32.add (i32.const 2)
(i32.trunc_f64_u (f64.sqrt (f64.convert_i32_u (local.get $inside))))))
(local.set $pieces (i32.mul (local.get $i) (local.get $i))))
(else (if (i32.and (i32.ne (local.get $border) (i32.const 0))
(i32.or (i32.eq (local.get $format) (global.get $square))
(f64.eq (local.get $aspectRatio) (f64.const 1.0))))
(then (local.set $i (i32.shr_u (i32.add (local.get $border) (i32.const 4)) (i32.const 2)))
(local.set $pieces (i32.mul (local.get $i) (local.get $i)))))))))))))))))))))
(if (i32.eqz (local.get $pieces)) (then (return (global.get $INSUFFICIENT)
(local.get $border) (local.get $inside) (local.get $rows) (local.get $columns)
(local.get $aspectRatio) (local.get $format))))
(if (i32.eqz (local.get $columns)) (then
(if (local.get $rows) (then (local.set $columns (i32.div_u (local.get $pieces) (local.get $rows))))
(else (if (i32.trunc_f64_u (local.get $aspectRatio))
(then (local.set $columns (i32.trunc_f64_u (f64.sqrt
(f64.mul (local.get $aspectRatio) (f64.convert_i32_u (local.get $pieces)))))))
(else (if (i32.and (i32.ne (local.get $border) (i32.const 0))
(i32.ne (local.get $format) (i32.const 0)))
(then (local.set $columns (call $findColumns
(local.get $pieces) (local.get $border) (local.get $format))))
(else (if (i32.and (i32.ne (local.get $inside) (i32.const 0))
(i32.ne (local.get $format) (i32.const 0)))
(then (local.set $columns (call $findColumns (local.get $pieces)
(i32.sub (local.get $pieces) (local.get $inside)) (local.get $format)))))))))))))
(if (i32.eqz (local.get $columns)) (then (return (global.get $INSUFFICIENT)
(local.get $border) (local.get $inside) (local.get $rows) (local.get $columns)
(local.get $aspectRatio) (local.get $format))))
(local.set $i (i32.div_u (local.get $pieces) (local.get $columns)))
(if (i32.eqz (local.get $rows)) (then (local.set $rows (local.get $i)))
(else (if (i32.ne (local.get $rows) (local.get $i)) (then (return (global.get $CONTRADICTORY)
(local.get $border) (local.get $inside) (local.get $rows) (local.get $columns)
(local.get $aspectRatio) (local.get $format))))))
(local.set $i (i32.sub (i32.shl (i32.add (local.get $rows) (local.get $columns))
(i32.const 1)) (i32.const 4)))
(if (i32.eqz (local.get $border)) (then (local.set $border (local.get $i)))
(else (if (i32.ne (local.get $border) (local.get $i)) (then (return (global.get $CONTRADICTORY)
(local.get $border) (local.get $inside) (local.get $rows) (local.get $columns)
(local.get $aspectRatio) (local.get $format))))))
(local.set $i (i32.sub (local.get $pieces) (local.get $border)))
(if (i32.eqz (local.get $inside)) (then (local.set $inside (local.get $i)))
(else (if (i32.ne (local.get $inside) (local.get $i)) (then (return (global.get $CONTRADICTORY)
(local.get $border) (local.get $inside) (local.get $rows) (local.get $columns)
(local.get $aspectRatio) (local.get $format))))))
(local.set $r (f64.div (f64.convert_i32_u (local.get $columns))
(f64.convert_i32_u (local.get $rows))))
(if (f64.eq (local.get $aspectRatio) (f64.const 0.0)) (then (local.set $aspectRatio (local.get $r)))
(else (if (f64.ne (local.get $aspectRatio) (local.get $r)) (then (return (global.get $CONTRADICTORY)
(local.get $border) (local.get $inside) (local.get $rows) (local.get $columns)
(local.get $r) (local.get $format))))))
(if (i32.eq (local.get $rows) (local.get $columns)) (then (local.set $i (global.get $square)))
(else (if (i32.lt_u (local.get $rows) (local.get $columns))
(then (local.set $i (global.get $landscape)))
(else (local.set $i (global.get $portrait))))))
(if (i32.eqz (local.get $format)) (then (local.set $format (local.get $i)))
(else (if (i32.ne (local.get $format) (local.get $i)) (then (return (global.get $CONTRADICTORY)
(local.get $border) (local.get $inside) (local.get $rows) (local.get $columns)
(local.get $aspectRatio) (local.get $i))))))
(local.get $pieces) (local.get $border) (local.get $inside)
(local.get $rows) (local.get $columns) (local.get $aspectRatio) (local.get $format)
)
)
31 changes: 31 additions & 0 deletions exercises/practice/piecing-it-together/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 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.

[ad626f23-09a2-4f5f-ba22-eec0671fa2a9]
description = "1000 pieces puzzle with 1.6 aspect ratio"

[3e0c5919-3561-42f5-b9ed-26d70c20214e]
description = "square puzzle with 32 rows"

[1126f160-b094-4dc2-bf37-13e36e394867]
description = "400 pieces square puzzle with only inside pieces and aspect ratio"

[a9743178-5642-4cc0-8fdb-00d6b031c3a0]
description = "1500 pieces landscape puzzle with 30 rows and 1.6 aspect ratio"

[f6378369-989c-497f-a6e2-f30b1fa76cba]
description = "300 pieces portrait puzzle with 70 border pieces"

[f53f82ba-5663-4c7e-9e86-57fdbb3e53d2]
description = "puzzle with insufficient data"

[a3d5c31a-cc74-44bf-b4fc-9e4d65f1ac1a]
description = "puzzle with contradictory data"
1 change: 1 addition & 0 deletions exercises/practice/piecing-it-together/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
audit=false
21 changes: 21 additions & 0 deletions exercises/practice/piecing-it-together/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 Exercism

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
4 changes: 4 additions & 0 deletions exercises/practice/piecing-it-together/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default {
presets: ["@exercism/babel-preset-javascript"],
plugins: [],
};
35 changes: 35 additions & 0 deletions exercises/practice/piecing-it-together/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "@exercism/wasm-piecing-it-together",
"description": "Exercism exercises in WebAssembly.",
"author": "Alex Lohr",
"type": "module",
"private": true,
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/exercism/wasm",
"directory": "exercises/practice/piecing-it-together"
},
"jest": {
"maxWorkers": 1
},
"devDependencies": {
"@babel/core": "^7.23.3",
"@exercism/babel-preset-javascript": "^0.4.0",
"@exercism/eslint-config-javascript": "^0.6.0",
"@types/jest": "^29.5.8",
"@types/node": "^20.9.1",
"babel-jest": "^29.7.0",
"core-js": "^3.33.2",
"eslint": "^8.54.0",
"jest": "^29.7.0"
},
"dependencies": {
"@exercism/wasm-lib": "^0.2.0"
},
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js ./*",
"watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch ./*",
"lint": "eslint ."
}
}
Loading