@untangle-code/parser-registry 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/NOTICE +90 -0
- package/README.md +352 -2
- package/THIRD_PARTY_LICENSES.md +91 -0
- package/dist/boundaries/expression.d.ts +10 -0
- package/dist/boundaries/expression.d.ts.map +1 -0
- package/dist/boundaries/expression.js +95 -0
- package/dist/boundaries/expression.js.map +1 -0
- package/dist/boundaries/extract.d.ts +12 -0
- package/dist/boundaries/extract.d.ts.map +1 -0
- package/dist/boundaries/extract.js +259 -0
- package/dist/boundaries/extract.js.map +1 -0
- package/dist/boundaries/python.d.ts +6 -0
- package/dist/boundaries/python.d.ts.map +1 -0
- package/dist/boundaries/python.js +154 -0
- package/dist/boundaries/python.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/languages/astgrep-backend/adapter.d.ts +101 -0
- package/dist/languages/astgrep-backend/adapter.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/adapter.js +130 -0
- package/dist/languages/astgrep-backend/adapter.js.map +1 -0
- package/dist/languages/astgrep-backend/index.d.ts +29 -0
- package/dist/languages/astgrep-backend/index.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/index.js +28 -0
- package/dist/languages/astgrep-backend/index.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/bash.d.ts +38 -0
- package/dist/languages/astgrep-backend/lang/bash.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/bash.js +42 -0
- package/dist/languages/astgrep-backend/lang/bash.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/c.d.ts +33 -0
- package/dist/languages/astgrep-backend/lang/c.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/c.js +85 -0
- package/dist/languages/astgrep-backend/lang/c.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/cpp.d.ts +27 -0
- package/dist/languages/astgrep-backend/lang/cpp.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/cpp.js +38 -0
- package/dist/languages/astgrep-backend/lang/cpp.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/csharp.d.ts +24 -0
- package/dist/languages/astgrep-backend/lang/csharp.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/csharp.js +102 -0
- package/dist/languages/astgrep-backend/lang/csharp.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/index.d.ts +29 -0
- package/dist/languages/astgrep-backend/lang/index.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/index.js +22 -0
- package/dist/languages/astgrep-backend/lang/index.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/java.d.ts +26 -0
- package/dist/languages/astgrep-backend/lang/java.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/java.js +89 -0
- package/dist/languages/astgrep-backend/lang/java.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/kotlin.d.ts +44 -0
- package/dist/languages/astgrep-backend/lang/kotlin.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/kotlin.js +94 -0
- package/dist/languages/astgrep-backend/lang/kotlin.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/php.d.ts +23 -0
- package/dist/languages/astgrep-backend/lang/php.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/php.js +80 -0
- package/dist/languages/astgrep-backend/lang/php.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/ruby.d.ts +37 -0
- package/dist/languages/astgrep-backend/lang/ruby.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/ruby.js +70 -0
- package/dist/languages/astgrep-backend/lang/ruby.js.map +1 -0
- package/dist/languages/astgrep-backend/lang/swift.d.ts +34 -0
- package/dist/languages/astgrep-backend/lang/swift.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/lang/swift.js +86 -0
- package/dist/languages/astgrep-backend/lang/swift.js.map +1 -0
- package/dist/languages/astgrep-backend/languages.d.ts +55 -0
- package/dist/languages/astgrep-backend/languages.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/languages.js +214 -0
- package/dist/languages/astgrep-backend/languages.js.map +1 -0
- package/dist/languages/astgrep-backend/napi.d.ts +71 -0
- package/dist/languages/astgrep-backend/napi.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/napi.js +176 -0
- package/dist/languages/astgrep-backend/napi.js.map +1 -0
- package/dist/languages/astgrep-backend/syntax.d.ts +88 -0
- package/dist/languages/astgrep-backend/syntax.d.ts.map +1 -0
- package/dist/languages/astgrep-backend/syntax.js +180 -0
- package/dist/languages/astgrep-backend/syntax.js.map +1 -0
- package/dist/languages/index.d.ts +14 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +37 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/javascript/index.d.ts +4 -0
- package/dist/languages/javascript/index.d.ts.map +1 -0
- package/dist/languages/javascript/index.js +7 -0
- package/dist/languages/javascript/index.js.map +1 -0
- package/dist/languages/jsx/index.d.ts +4 -0
- package/dist/languages/jsx/index.d.ts.map +1 -0
- package/dist/languages/jsx/index.js +7 -0
- package/dist/languages/jsx/index.js.map +1 -0
- package/dist/languages/prose/index.d.ts +53 -0
- package/dist/languages/prose/index.d.ts.map +1 -0
- package/dist/languages/prose/index.js +172 -0
- package/dist/languages/prose/index.js.map +1 -0
- package/dist/languages/prose/line-bytes.d.ts +31 -0
- package/dist/languages/prose/line-bytes.d.ts.map +1 -0
- package/dist/languages/prose/line-bytes.js +39 -0
- package/dist/languages/prose/line-bytes.js.map +1 -0
- package/dist/languages/python/create-adapter.d.ts +20 -0
- package/dist/languages/python/create-adapter.d.ts.map +1 -0
- package/dist/languages/python/create-adapter.js +9 -0
- package/dist/languages/python/create-adapter.js.map +1 -0
- package/dist/languages/python/index.d.ts +4 -0
- package/dist/languages/python/index.d.ts.map +1 -0
- package/dist/languages/python/index.js +6 -0
- package/dist/languages/python/index.js.map +1 -0
- package/dist/languages/python/profile.d.ts +36 -0
- package/dist/languages/python/profile.d.ts.map +1 -0
- package/dist/languages/python/profile.js +282 -0
- package/dist/languages/python/profile.js.map +1 -0
- package/dist/languages/python/signature.d.ts +53 -0
- package/dist/languages/python/signature.d.ts.map +1 -0
- package/dist/languages/python/signature.js +188 -0
- package/dist/languages/python/signature.js.map +1 -0
- package/dist/languages/python/table.d.ts +46 -0
- package/dist/languages/python/table.d.ts.map +1 -0
- package/dist/languages/python/table.js +88 -0
- package/dist/languages/python/table.js.map +1 -0
- package/dist/languages/shared/call-detection.d.ts +17 -0
- package/dist/languages/shared/call-detection.d.ts.map +1 -0
- package/dist/languages/shared/call-detection.js +86 -0
- package/dist/languages/shared/call-detection.js.map +1 -0
- package/dist/languages/shared/chunks.d.ts +28 -0
- package/dist/languages/shared/chunks.d.ts.map +1 -0
- package/dist/languages/shared/chunks.js +181 -0
- package/dist/languages/shared/chunks.js.map +1 -0
- package/dist/languages/shared/create-adapter.d.ts +11 -0
- package/dist/languages/shared/create-adapter.d.ts.map +1 -0
- package/dist/languages/shared/create-adapter.js +90 -0
- package/dist/languages/shared/create-adapter.js.map +1 -0
- package/dist/languages/shared/decisions.d.ts +45 -0
- package/dist/languages/shared/decisions.d.ts.map +1 -0
- package/dist/languages/shared/decisions.js +141 -0
- package/dist/languages/shared/decisions.js.map +1 -0
- package/dist/languages/shared/dialect.d.ts +18 -0
- package/dist/languages/shared/dialect.d.ts.map +1 -0
- package/dist/languages/shared/dialect.js +37 -0
- package/dist/languages/shared/dialect.js.map +1 -0
- package/dist/languages/shared/doc-binding.d.ts +26 -0
- package/dist/languages/shared/doc-binding.d.ts.map +1 -0
- package/dist/languages/shared/doc-binding.js +50 -0
- package/dist/languages/shared/doc-binding.js.map +1 -0
- package/dist/languages/shared/engine.d.ts +49 -0
- package/dist/languages/shared/engine.d.ts.map +1 -0
- package/dist/languages/shared/engine.js +317 -0
- package/dist/languages/shared/engine.js.map +1 -0
- package/dist/languages/shared/extract-symbols.d.ts +5 -0
- package/dist/languages/shared/extract-symbols.d.ts.map +1 -0
- package/dist/languages/shared/extract-symbols.js +31 -0
- package/dist/languages/shared/extract-symbols.js.map +1 -0
- package/dist/languages/shared/fingerprint.d.ts +7 -0
- package/dist/languages/shared/fingerprint.d.ts.map +1 -0
- package/dist/languages/shared/fingerprint.js +95 -0
- package/dist/languages/shared/fingerprint.js.map +1 -0
- package/dist/languages/shared/grammar-loader.d.ts +15 -0
- package/dist/languages/shared/grammar-loader.d.ts.map +1 -0
- package/dist/languages/shared/grammar-loader.js +48 -0
- package/dist/languages/shared/grammar-loader.js.map +1 -0
- package/dist/languages/shared/import-detection.d.ts +24 -0
- package/dist/languages/shared/import-detection.d.ts.map +1 -0
- package/dist/languages/shared/import-detection.js +138 -0
- package/dist/languages/shared/import-detection.js.map +1 -0
- package/dist/languages/shared/js-family-profile.d.ts +5 -0
- package/dist/languages/shared/js-family-profile.d.ts.map +1 -0
- package/dist/languages/shared/js-family-profile.js +179 -0
- package/dist/languages/shared/js-family-profile.js.map +1 -0
- package/dist/languages/shared/node-kinds.d.ts +78 -0
- package/dist/languages/shared/node-kinds.d.ts.map +1 -0
- package/dist/languages/shared/node-kinds.js +141 -0
- package/dist/languages/shared/node-kinds.js.map +1 -0
- package/dist/languages/shared/node-utils.d.ts +31 -0
- package/dist/languages/shared/node-utils.d.ts.map +1 -0
- package/dist/languages/shared/node-utils.js +89 -0
- package/dist/languages/shared/node-utils.js.map +1 -0
- package/dist/languages/shared/parse-diagnostics.d.ts +44 -0
- package/dist/languages/shared/parse-diagnostics.d.ts.map +1 -0
- package/dist/languages/shared/parse-diagnostics.js +64 -0
- package/dist/languages/shared/parse-diagnostics.js.map +1 -0
- package/dist/languages/shared/parse-limits.d.ts +24 -0
- package/dist/languages/shared/parse-limits.d.ts.map +1 -0
- package/dist/languages/shared/parse-limits.js +134 -0
- package/dist/languages/shared/parse-limits.js.map +1 -0
- package/dist/languages/shared/profile.d.ts +149 -0
- package/dist/languages/shared/profile.d.ts.map +1 -0
- package/dist/languages/shared/profile.js +9 -0
- package/dist/languages/shared/profile.js.map +1 -0
- package/dist/languages/shared/scope-model.d.ts +32 -0
- package/dist/languages/shared/scope-model.d.ts.map +1 -0
- package/dist/languages/shared/scope-model.js +2 -0
- package/dist/languages/shared/scope-model.js.map +1 -0
- package/dist/languages/shared/scope-naming.d.ts +20 -0
- package/dist/languages/shared/scope-naming.d.ts.map +1 -0
- package/dist/languages/shared/scope-naming.js +118 -0
- package/dist/languages/shared/scope-naming.js.map +1 -0
- package/dist/languages/shared/scope-signature.d.ts +14 -0
- package/dist/languages/shared/scope-signature.d.ts.map +1 -0
- package/dist/languages/shared/scope-signature.js +82 -0
- package/dist/languages/shared/scope-signature.js.map +1 -0
- package/dist/languages/shared/signature.d.ts +55 -0
- package/dist/languages/shared/signature.d.ts.map +1 -0
- package/dist/languages/shared/signature.js +147 -0
- package/dist/languages/shared/signature.js.map +1 -0
- package/dist/languages/shared/syntax.d.ts +115 -0
- package/dist/languages/shared/syntax.d.ts.map +1 -0
- package/dist/languages/shared/syntax.js +2 -0
- package/dist/languages/shared/syntax.js.map +1 -0
- package/dist/languages/shared/table-profile-decisions.d.ts +54 -0
- package/dist/languages/shared/table-profile-decisions.d.ts.map +1 -0
- package/dist/languages/shared/table-profile-decisions.js +245 -0
- package/dist/languages/shared/table-profile-decisions.js.map +1 -0
- package/dist/languages/shared/table-profile-module-facts.d.ts +29 -0
- package/dist/languages/shared/table-profile-module-facts.d.ts.map +1 -0
- package/dist/languages/shared/table-profile-module-facts.js +139 -0
- package/dist/languages/shared/table-profile-module-facts.js.map +1 -0
- package/dist/languages/shared/table-profile-queries.d.ts +27 -0
- package/dist/languages/shared/table-profile-queries.d.ts.map +1 -0
- package/dist/languages/shared/table-profile-queries.js +70 -0
- package/dist/languages/shared/table-profile-queries.js.map +1 -0
- package/dist/languages/shared/table-profile-scopes.d.ts +46 -0
- package/dist/languages/shared/table-profile-scopes.d.ts.map +1 -0
- package/dist/languages/shared/table-profile-scopes.js +180 -0
- package/dist/languages/shared/table-profile-scopes.js.map +1 -0
- package/dist/languages/shared/table-profile.d.ts +302 -0
- package/dist/languages/shared/table-profile.d.ts.map +1 -0
- package/dist/languages/shared/table-profile.js +125 -0
- package/dist/languages/shared/table-profile.js.map +1 -0
- package/dist/languages/shared/tree-sitter-types.d.ts +44 -0
- package/dist/languages/shared/tree-sitter-types.d.ts.map +1 -0
- package/dist/languages/shared/tree-sitter-types.js +2 -0
- package/dist/languages/shared/tree-sitter-types.js.map +1 -0
- package/dist/languages/structured-text/index.d.ts +48 -0
- package/dist/languages/structured-text/index.d.ts.map +1 -0
- package/dist/languages/structured-text/index.js +120 -0
- package/dist/languages/structured-text/index.js.map +1 -0
- package/dist/languages/tsx/index.d.ts +4 -0
- package/dist/languages/tsx/index.d.ts.map +1 -0
- package/dist/languages/tsx/index.js +7 -0
- package/dist/languages/tsx/index.js.map +1 -0
- package/dist/languages/typescript/index.d.ts +4 -0
- package/dist/languages/typescript/index.d.ts.map +1 -0
- package/dist/languages/typescript/index.js +7 -0
- package/dist/languages/typescript/index.js.map +1 -0
- package/dist/languages/vue/index.d.ts +21 -0
- package/dist/languages/vue/index.d.ts.map +1 -0
- package/dist/languages/vue/index.js +234 -0
- package/dist/languages/vue/index.js.map +1 -0
- package/dist/languages/vue/mapping.d.ts +11 -0
- package/dist/languages/vue/mapping.d.ts.map +1 -0
- package/dist/languages/vue/mapping.js +77 -0
- package/dist/languages/vue/mapping.js.map +1 -0
- package/dist/registry.d.ts +24 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +42 -0
- package/dist/registry.js.map +1 -0
- package/dist/text/byte-offset-table.d.ts +27 -0
- package/dist/text/byte-offset-table.d.ts.map +1 -0
- package/dist/text/byte-offset-table.js +39 -0
- package/dist/text/byte-offset-table.js.map +1 -0
- package/package.json +125 -3
- package/src/boundaries/expression.ts +95 -0
- package/src/boundaries/extract.ts +307 -0
- package/src/boundaries/python.ts +181 -0
- package/src/index.ts +51 -0
- package/src/languages/__golden__/javascript-basic.json +32 -0
- package/src/languages/__golden__/tsx-basic.json +19 -0
- package/src/languages/__golden__/typescript-basic.json +37 -0
- package/src/languages/astgrep-backend/GRAMMARS.md +86 -0
- package/src/languages/astgrep-backend/README.md +112 -0
- package/src/languages/astgrep-backend/__golden__/bash-basic.sh +53 -0
- package/src/languages/astgrep-backend/__golden__/c-basic.c +64 -0
- package/src/languages/astgrep-backend/__golden__/cpp-basic.cpp +65 -0
- package/src/languages/astgrep-backend/__golden__/csharp-basic.cs +73 -0
- package/src/languages/astgrep-backend/__golden__/go-basic.go +93 -0
- package/src/languages/astgrep-backend/__golden__/java-basic.java +62 -0
- package/src/languages/astgrep-backend/__golden__/kotlin-basic.kt +58 -0
- package/src/languages/astgrep-backend/__golden__/php-basic.php +72 -0
- package/src/languages/astgrep-backend/__golden__/ruby-basic.rb +62 -0
- package/src/languages/astgrep-backend/__golden__/rust-basic.rs +82 -0
- package/src/languages/astgrep-backend/__golden__/swift-basic.swift +73 -0
- package/src/languages/astgrep-backend/adapter.ts +240 -0
- package/src/languages/astgrep-backend/index.ts +44 -0
- package/src/languages/astgrep-backend/lang/README.md +115 -0
- package/src/languages/astgrep-backend/lang/bash.ts +78 -0
- package/src/languages/astgrep-backend/lang/c.ts +119 -0
- package/src/languages/astgrep-backend/lang/cpp.ts +65 -0
- package/src/languages/astgrep-backend/lang/csharp.ts +125 -0
- package/src/languages/astgrep-backend/lang/index.ts +61 -0
- package/src/languages/astgrep-backend/lang/java.ts +115 -0
- package/src/languages/astgrep-backend/lang/kotlin.ts +136 -0
- package/src/languages/astgrep-backend/lang/php.ts +105 -0
- package/src/languages/astgrep-backend/lang/ruby.ts +105 -0
- package/src/languages/astgrep-backend/lang/swift.ts +118 -0
- package/src/languages/astgrep-backend/languages.ts +238 -0
- package/src/languages/astgrep-backend/napi.ts +261 -0
- package/src/languages/astgrep-backend/syntax.ts +242 -0
- package/src/languages/index.ts +53 -0
- package/src/languages/javascript/index.ts +9 -0
- package/src/languages/jsx/index.ts +9 -0
- package/src/languages/prose/index.ts +270 -0
- package/src/languages/prose/line-bytes.ts +52 -0
- package/src/languages/python/README.md +246 -0
- package/src/languages/python/__golden__/python-basic.json +44 -0
- package/src/languages/python/create-adapter.ts +29 -0
- package/src/languages/python/index.ts +8 -0
- package/src/languages/python/profile.ts +341 -0
- package/src/languages/python/signature.ts +183 -0
- package/src/languages/python/table.ts +135 -0
- package/src/languages/shared/__fixtures__/large-over-32kib.ts.txt +1207 -0
- package/src/languages/shared/call-detection.ts +112 -0
- package/src/languages/shared/chunks.ts +255 -0
- package/src/languages/shared/create-adapter.ts +136 -0
- package/src/languages/shared/decisions.ts +204 -0
- package/src/languages/shared/dialect.ts +55 -0
- package/src/languages/shared/doc-binding.ts +78 -0
- package/src/languages/shared/engine.ts +461 -0
- package/src/languages/shared/extract-symbols.ts +35 -0
- package/src/languages/shared/fingerprint.ts +99 -0
- package/src/languages/shared/grammar-loader.ts +67 -0
- package/src/languages/shared/import-detection.ts +154 -0
- package/src/languages/shared/js-family-profile.ts +246 -0
- package/src/languages/shared/node-kinds.ts +153 -0
- package/src/languages/shared/node-utils.ts +120 -0
- package/src/languages/shared/parse-diagnostics.ts +125 -0
- package/src/languages/shared/parse-limits.ts +147 -0
- package/src/languages/shared/profile.ts +184 -0
- package/src/languages/shared/scope-model.ts +43 -0
- package/src/languages/shared/scope-naming.ts +124 -0
- package/src/languages/shared/scope-signature.ts +108 -0
- package/src/languages/shared/signature.ts +149 -0
- package/src/languages/shared/syntax.ts +116 -0
- package/src/languages/shared/table-profile-decisions.ts +251 -0
- package/src/languages/shared/table-profile-module-facts.ts +177 -0
- package/src/languages/shared/table-profile-queries.ts +85 -0
- package/src/languages/shared/table-profile-scopes.ts +198 -0
- package/src/languages/shared/table-profile.ts +427 -0
- package/src/languages/shared/tree-sitter-types.ts +46 -0
- package/src/languages/structured-text/index.ts +192 -0
- package/src/languages/tsx/index.ts +9 -0
- package/src/languages/typescript/index.ts +9 -0
- package/src/languages/vue/index.ts +312 -0
- package/src/languages/vue/mapping.ts +93 -0
- package/src/registry.ts +61 -0
- package/src/text/byte-offset-table.ts +63 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// A tiny matrix.
|
|
2
|
+
#include <vector>
|
|
3
|
+
#include <stdexcept>
|
|
4
|
+
#include "matrix.hpp"
|
|
5
|
+
|
|
6
|
+
namespace linalg {
|
|
7
|
+
|
|
8
|
+
constexpr int kMax = 1024;
|
|
9
|
+
|
|
10
|
+
struct Shape {
|
|
11
|
+
int rows;
|
|
12
|
+
int cols;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
enum class Order { RowMajor, ColMajor };
|
|
16
|
+
|
|
17
|
+
class Matrix {
|
|
18
|
+
public:
|
|
19
|
+
/// Builds a matrix.
|
|
20
|
+
Matrix(int rows, int cols) : rows_(rows), cols_(cols), data_(rows * cols) {}
|
|
21
|
+
|
|
22
|
+
double at(int r, int c) const {
|
|
23
|
+
if (r < 0 || c < 0) {
|
|
24
|
+
throw std::out_of_range("negative");
|
|
25
|
+
} else if (r >= rows_ || c >= cols_) {
|
|
26
|
+
throw std::out_of_range("bounds");
|
|
27
|
+
}
|
|
28
|
+
return data_[r * cols_ + c];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void fill(double v) {
|
|
32
|
+
for (int i = 0; i < rows_; ++i) {
|
|
33
|
+
for (int j = 0; j < cols_; ++j) {
|
|
34
|
+
if (i == j && v > 0 || v == 0) {
|
|
35
|
+
data_[i * cols_ + j] = v;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
while (rows_ > kMax) {
|
|
41
|
+
throw std::runtime_error("too big");
|
|
42
|
+
}
|
|
43
|
+
} catch (const std::exception &e) {
|
|
44
|
+
data_.clear();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private:
|
|
49
|
+
int rows_;
|
|
50
|
+
int cols_;
|
|
51
|
+
std::vector<double> data_;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
template <typename T>
|
|
55
|
+
T twice(T v) {
|
|
56
|
+
return v + v;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Matrix identity(int n) {
|
|
60
|
+
Matrix m(n, n);
|
|
61
|
+
m.fill(1.0);
|
|
62
|
+
return m;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
} // namespace linalg
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using Sys = System.Text;
|
|
4
|
+
|
|
5
|
+
namespace Example.Caching
|
|
6
|
+
{
|
|
7
|
+
/// <summary>A tiny cache.</summary>
|
|
8
|
+
public interface ICache<T>
|
|
9
|
+
{
|
|
10
|
+
T Get(string key);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public enum Mode { Read, Write }
|
|
14
|
+
|
|
15
|
+
public struct Slot
|
|
16
|
+
{
|
|
17
|
+
public int Size;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public class Cache : ICache<string>, IDisposable
|
|
21
|
+
{
|
|
22
|
+
private readonly Dictionary<string, string> _items = new();
|
|
23
|
+
public const int Max = 16;
|
|
24
|
+
|
|
25
|
+
public Cache(Dictionary<string, string> items)
|
|
26
|
+
{
|
|
27
|
+
_items = items;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public string Name { get; set; }
|
|
31
|
+
|
|
32
|
+
/// <summary>Reads one entry.</summary>
|
|
33
|
+
public string Get(string key)
|
|
34
|
+
{
|
|
35
|
+
if (key == null || key.Length == 0)
|
|
36
|
+
{
|
|
37
|
+
throw new ArgumentNullException(nameof(key));
|
|
38
|
+
}
|
|
39
|
+
else if (_items.Count > Max)
|
|
40
|
+
{
|
|
41
|
+
_items.Clear();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try
|
|
45
|
+
{
|
|
46
|
+
foreach (var kv in _items)
|
|
47
|
+
{
|
|
48
|
+
if (kv.Key == key) return kv.Value;
|
|
49
|
+
}
|
|
50
|
+
for (int i = 0; i < Max; i++)
|
|
51
|
+
{
|
|
52
|
+
while (i < 0) { i++; }
|
|
53
|
+
}
|
|
54
|
+
switch (key)
|
|
55
|
+
{
|
|
56
|
+
case "a":
|
|
57
|
+
return "A";
|
|
58
|
+
case "b":
|
|
59
|
+
return "B";
|
|
60
|
+
default:
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (InvalidOperationException e)
|
|
65
|
+
{
|
|
66
|
+
Console.WriteLine(e.Message);
|
|
67
|
+
}
|
|
68
|
+
return key.Length > 0 ? key : null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public void Dispose() => _items.Clear();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Package worker drains a queue.
|
|
2
|
+
package worker
|
|
3
|
+
|
|
4
|
+
import (
|
|
5
|
+
"context"
|
|
6
|
+
"errors"
|
|
7
|
+
"fmt"
|
|
8
|
+
ts "time"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// ErrClosed is returned once the pool is closed.
|
|
12
|
+
var ErrClosed = errors.New("closed")
|
|
13
|
+
|
|
14
|
+
const maxRetries = 3
|
|
15
|
+
|
|
16
|
+
// Job is one unit of work.
|
|
17
|
+
type Job struct {
|
|
18
|
+
ID string
|
|
19
|
+
Payload []byte
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Runner runs jobs.
|
|
23
|
+
type Runner interface {
|
|
24
|
+
Run(ctx context.Context, j Job) error
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type pool struct {
|
|
28
|
+
jobs chan Job
|
|
29
|
+
runner Runner
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// NewPool builds a pool.
|
|
33
|
+
func NewPool(r Runner, size int) *pool {
|
|
34
|
+
return &pool{jobs: make(chan Job, size), runner: r}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Drain consumes jobs until the context ends.
|
|
38
|
+
func (p *pool) Drain(ctx context.Context) error {
|
|
39
|
+
for {
|
|
40
|
+
select {
|
|
41
|
+
case j, ok := <-p.jobs:
|
|
42
|
+
if !ok {
|
|
43
|
+
return ErrClosed
|
|
44
|
+
}
|
|
45
|
+
if err := p.runOne(ctx, j); err != nil && !errors.Is(err, ErrClosed) {
|
|
46
|
+
return fmt.Errorf("job %s: %w", j.ID, err)
|
|
47
|
+
}
|
|
48
|
+
case <-ctx.Done():
|
|
49
|
+
return ctx.Err()
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func (p *pool) runOne(ctx context.Context, j Job) error {
|
|
55
|
+
for attempt := 0; attempt < maxRetries; attempt++ {
|
|
56
|
+
err := p.runner.Run(ctx, j)
|
|
57
|
+
if err == nil {
|
|
58
|
+
return nil
|
|
59
|
+
}
|
|
60
|
+
switch {
|
|
61
|
+
case errors.Is(err, ErrClosed):
|
|
62
|
+
return err
|
|
63
|
+
default:
|
|
64
|
+
ts.Sleep(ts.Millisecond)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return ErrClosed
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func describe(v any) string {
|
|
71
|
+
switch x := v.(type) {
|
|
72
|
+
case string:
|
|
73
|
+
return x
|
|
74
|
+
case int, int64:
|
|
75
|
+
return fmt.Sprint(x)
|
|
76
|
+
default:
|
|
77
|
+
return "?"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
func each(items []Job, fn func(Job) bool) int {
|
|
82
|
+
n := 0
|
|
83
|
+
for i, it := range items {
|
|
84
|
+
if i > 0 && fn(it) || len(it.ID) == 0 {
|
|
85
|
+
n++
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
go func() {
|
|
89
|
+
defer func() { _ = recover() }()
|
|
90
|
+
_ = n
|
|
91
|
+
}()
|
|
92
|
+
return n
|
|
93
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
package com.example.ledger;
|
|
2
|
+
|
|
3
|
+
import java.util.List;
|
|
4
|
+
import java.util.Map;
|
|
5
|
+
import static java.util.Collections.emptyList;
|
|
6
|
+
|
|
7
|
+
/** A ledger of entries. */
|
|
8
|
+
public class Ledger implements AutoCloseable {
|
|
9
|
+
private final Map<String, Long> balances;
|
|
10
|
+
public static final int MAX = 100;
|
|
11
|
+
|
|
12
|
+
public Ledger(Map<String, Long> balances) {
|
|
13
|
+
this.balances = balances;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Applies one entry. */
|
|
17
|
+
public long apply(String account, long amount) throws IllegalStateException {
|
|
18
|
+
if (account == null || account.isEmpty()) {
|
|
19
|
+
throw new IllegalStateException("account");
|
|
20
|
+
} else if (amount == 0) {
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
long current = balances.getOrDefault(account, 0L);
|
|
24
|
+
long next = current + amount;
|
|
25
|
+
try {
|
|
26
|
+
for (int i = 0; i < MAX && next > 0; i++) {
|
|
27
|
+
next -= 1;
|
|
28
|
+
}
|
|
29
|
+
while (next < 0) { next++; }
|
|
30
|
+
switch (account) {
|
|
31
|
+
case "a":
|
|
32
|
+
next = 1;
|
|
33
|
+
break;
|
|
34
|
+
case "b":
|
|
35
|
+
case "c":
|
|
36
|
+
next = 2;
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
} catch (RuntimeException e) {
|
|
42
|
+
next = current;
|
|
43
|
+
} finally {
|
|
44
|
+
balances.put(account, next);
|
|
45
|
+
}
|
|
46
|
+
return next > 0 ? next : 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface Visitor {
|
|
50
|
+
void visit(String key);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
enum Kind { DEBIT, CREDIT }
|
|
54
|
+
|
|
55
|
+
record Entry(String account, long amount) {}
|
|
56
|
+
|
|
57
|
+
@Override
|
|
58
|
+
public void close() {
|
|
59
|
+
List<String> keys = emptyList();
|
|
60
|
+
keys.forEach(k -> balances.remove(k));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
package com.example.cache
|
|
2
|
+
|
|
3
|
+
import kotlin.math.max
|
|
4
|
+
import java.util.concurrent.ConcurrentHashMap as CMap
|
|
5
|
+
|
|
6
|
+
const val LIMIT = 32
|
|
7
|
+
|
|
8
|
+
/** A cache entry. */
|
|
9
|
+
data class Entry(val key: String, val size: Int)
|
|
10
|
+
|
|
11
|
+
interface Store {
|
|
12
|
+
fun get(key: String): Entry?
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
enum class Mode { READ, WRITE }
|
|
16
|
+
|
|
17
|
+
object Registry {
|
|
18
|
+
val all = mutableListOf<String>()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** In-memory store. */
|
|
22
|
+
class MemStore(private val items: CMap<String, Entry>) : Store {
|
|
23
|
+
var name: String = ""
|
|
24
|
+
|
|
25
|
+
override fun get(key: String): Entry? {
|
|
26
|
+
if (key.isEmpty()) {
|
|
27
|
+
return null
|
|
28
|
+
} else if (items.size > LIMIT) {
|
|
29
|
+
items.clear()
|
|
30
|
+
}
|
|
31
|
+
for ((k, v) in items) {
|
|
32
|
+
if (k == key && v.size > 0 || v.size == 0) {
|
|
33
|
+
return v
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
var i = 0
|
|
37
|
+
while (i < LIMIT) {
|
|
38
|
+
i++
|
|
39
|
+
}
|
|
40
|
+
return try {
|
|
41
|
+
when (key) {
|
|
42
|
+
"a" -> items["a"]
|
|
43
|
+
"b", "c" -> items["b"]
|
|
44
|
+
else -> null
|
|
45
|
+
}
|
|
46
|
+
} catch (e: IllegalStateException) {
|
|
47
|
+
null
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fun sizes(): List<Int> = items.values.map { it.size }
|
|
52
|
+
|
|
53
|
+
companion object {
|
|
54
|
+
fun empty(): MemStore = MemStore(CMap())
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fun biggest(a: Int, b: Int): Int = if (a > b) max(a, b) else b
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Billing;
|
|
4
|
+
|
|
5
|
+
use App\Money;
|
|
6
|
+
use App\Contracts\Payable as PayableContract;
|
|
7
|
+
|
|
8
|
+
const TAX = 0.19;
|
|
9
|
+
|
|
10
|
+
interface Payable
|
|
11
|
+
{
|
|
12
|
+
public function total(): float;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
trait HasLines
|
|
16
|
+
{
|
|
17
|
+
public function lineCount(): int
|
|
18
|
+
{
|
|
19
|
+
return count($this->lines);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** An invoice. */
|
|
24
|
+
class Invoice implements Payable
|
|
25
|
+
{
|
|
26
|
+
use HasLines;
|
|
27
|
+
|
|
28
|
+
private array $lines = [];
|
|
29
|
+
public const CURRENCY = 'EUR';
|
|
30
|
+
|
|
31
|
+
public function __construct(array $lines)
|
|
32
|
+
{
|
|
33
|
+
$this->lines = $lines;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Sums all lines. */
|
|
37
|
+
public function total(): float
|
|
38
|
+
{
|
|
39
|
+
if (empty($this->lines)) {
|
|
40
|
+
return 0.0;
|
|
41
|
+
} elseif (count($this->lines) > 100) {
|
|
42
|
+
throw new \RuntimeException('too many');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
$sum = 0.0;
|
|
46
|
+
foreach ($this->lines as $line) {
|
|
47
|
+
if ($line['amount'] > 0 && !$line['void'] || $line['forced']) {
|
|
48
|
+
$sum += $line['amount'];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for ($i = 0; $i < 3; $i++) {
|
|
52
|
+
while ($sum < 0) { $sum++; }
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
switch (self::CURRENCY) {
|
|
56
|
+
case 'EUR':
|
|
57
|
+
$sum *= (1 + TAX);
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
} catch (\Throwable $e) {
|
|
63
|
+
$sum = 0.0;
|
|
64
|
+
}
|
|
65
|
+
return $sum > 0 ? $sum : 0.0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function makeInvoice(array $lines): Invoice
|
|
70
|
+
{
|
|
71
|
+
return new Invoice($lines);
|
|
72
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require_relative 'helper'
|
|
5
|
+
|
|
6
|
+
# A report builder.
|
|
7
|
+
module Reporting
|
|
8
|
+
MAX = 10
|
|
9
|
+
|
|
10
|
+
class Report
|
|
11
|
+
attr_reader :rows
|
|
12
|
+
|
|
13
|
+
def initialize(rows)
|
|
14
|
+
@rows = rows
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Renders the report.
|
|
18
|
+
def render(format = :text)
|
|
19
|
+
raise ArgumentError, 'no rows' if @rows.empty?
|
|
20
|
+
|
|
21
|
+
out = []
|
|
22
|
+
@rows.each_with_index do |row, i|
|
|
23
|
+
next if row.nil?
|
|
24
|
+
if i.zero?
|
|
25
|
+
out << header(row)
|
|
26
|
+
elsif i > MAX
|
|
27
|
+
break
|
|
28
|
+
else
|
|
29
|
+
out << body(row)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
case format
|
|
34
|
+
when :json then JSON.dump(out)
|
|
35
|
+
when :text then out.join("\n")
|
|
36
|
+
else
|
|
37
|
+
raise "unknown #{format}"
|
|
38
|
+
end
|
|
39
|
+
rescue StandardError => e
|
|
40
|
+
warn(e.message)
|
|
41
|
+
''
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def header(row)
|
|
47
|
+
row.to_s.upcase
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def body(row)
|
|
51
|
+
row.to_s if row && !row.empty? || row == 0
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.build(rows)
|
|
55
|
+
new(rows)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.quick(rows)
|
|
60
|
+
Report.build(rows).render
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//! A tiny store.
|
|
2
|
+
use std::collections::HashMap;
|
|
3
|
+
use std::fmt::{self, Display};
|
|
4
|
+
|
|
5
|
+
pub const LIMIT: usize = 8;
|
|
6
|
+
|
|
7
|
+
/// A stored record.
|
|
8
|
+
#[derive(Debug, Clone)]
|
|
9
|
+
pub struct Record {
|
|
10
|
+
pub id: String,
|
|
11
|
+
pub size: usize,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub enum Slot {
|
|
15
|
+
Empty,
|
|
16
|
+
Filled(Record),
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
pub trait Store {
|
|
20
|
+
fn get(&self, id: &str) -> Option<&Record>;
|
|
21
|
+
fn put(&mut self, r: Record) -> Result<(), String>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
pub struct MemStore {
|
|
25
|
+
items: HashMap<String, Record>,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
impl MemStore {
|
|
29
|
+
/// Builds an empty store.
|
|
30
|
+
pub fn new() -> Self {
|
|
31
|
+
MemStore { items: HashMap::new() }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fn check(&self, r: &Record) -> Result<(), String> {
|
|
35
|
+
if r.size > LIMIT {
|
|
36
|
+
return Err("too big".to_string());
|
|
37
|
+
} else if r.id.is_empty() {
|
|
38
|
+
return Err("no id".to_string());
|
|
39
|
+
}
|
|
40
|
+
Ok(())
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
impl Store for MemStore {
|
|
45
|
+
fn get(&self, id: &str) -> Option<&Record> {
|
|
46
|
+
self.items.get(id)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
fn put(&mut self, r: Record) -> Result<(), String> {
|
|
50
|
+
self.check(&r)?;
|
|
51
|
+
let slot = match self.items.get(&r.id) {
|
|
52
|
+
Some(existing) if existing.size == r.size => Slot::Filled(existing.clone()),
|
|
53
|
+
Some(_) => Slot::Empty,
|
|
54
|
+
None => Slot::Empty,
|
|
55
|
+
};
|
|
56
|
+
if let Slot::Filled(_) = slot {
|
|
57
|
+
return Ok(());
|
|
58
|
+
}
|
|
59
|
+
while self.items.len() > LIMIT {
|
|
60
|
+
self.items.clear();
|
|
61
|
+
}
|
|
62
|
+
for (k, v) in self.items.iter() {
|
|
63
|
+
if v.size == 0 && !k.is_empty() || k == "x" {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
self.items.insert(r.id.clone(), r);
|
|
68
|
+
Ok(())
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
impl Display for Record {
|
|
73
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
74
|
+
write!(f, "{}", self.id)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
pub fn count_all(stores: &[MemStore]) -> usize {
|
|
79
|
+
stores.iter().map(|s| s.items.len()).sum()
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type Alias = HashMap<String, Record>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import os.log
|
|
3
|
+
|
|
4
|
+
let limit = 32
|
|
5
|
+
|
|
6
|
+
/// A record.
|
|
7
|
+
public struct Record {
|
|
8
|
+
let id: String
|
|
9
|
+
var size: Int
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public protocol Store {
|
|
13
|
+
func get(_ id: String) -> Record?
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public enum Mode {
|
|
17
|
+
case read
|
|
18
|
+
case write
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// In-memory store.
|
|
22
|
+
public final class MemStore: Store {
|
|
23
|
+
private var items: [String: Record] = [:]
|
|
24
|
+
|
|
25
|
+
public init(items: [String: Record]) {
|
|
26
|
+
self.items = items
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public func get(_ id: String) -> Record? {
|
|
30
|
+
guard !id.isEmpty else {
|
|
31
|
+
return nil
|
|
32
|
+
}
|
|
33
|
+
if items.count > limit {
|
|
34
|
+
items.removeAll()
|
|
35
|
+
} else if id == "x" {
|
|
36
|
+
return nil
|
|
37
|
+
}
|
|
38
|
+
for (k, v) in items {
|
|
39
|
+
if k == id && v.size > 0 || v.size == 0 {
|
|
40
|
+
return v
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
var i = 0
|
|
44
|
+
while i < limit {
|
|
45
|
+
i += 1
|
|
46
|
+
}
|
|
47
|
+
switch id {
|
|
48
|
+
case "a":
|
|
49
|
+
return items["a"]
|
|
50
|
+
case "b", "c":
|
|
51
|
+
return items["b"]
|
|
52
|
+
default:
|
|
53
|
+
break
|
|
54
|
+
}
|
|
55
|
+
do {
|
|
56
|
+
return try load(id)
|
|
57
|
+
} catch {
|
|
58
|
+
return nil
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private func load(_ id: String) throws -> Record? {
|
|
63
|
+
return items[id]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
extension MemStore {
|
|
68
|
+
var count: Int { items.count }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
func biggest(_ a: Int, _ b: Int) -> Int {
|
|
72
|
+
return a > b ? a : b
|
|
73
|
+
}
|