## Problem: Add
### Statement
Write a function that returns the sum of two numbers.
### Solutions
#### Option 1
```rust
fn add(param1: Int, param2: Int){
param1 + param2
}
```
#### Option 2
```rust
fn add(a: Int, b: Int) -> Int {a + b}
```
## Problem: Make Array Consecutive 2
### Statement
Ratiorg got `statues` of _different_ sizes as a present from CodeMaster for his birthday, each statue having an non-negative integer size. Since he likes to make things perfect, he wants to arrange them from smallest to largest so that each statue will be bigger than the previous one exactly by `1`. He may need some additional statues to be able to accomplish that. Help him figure out the minimum number of additional statues needed.
**Example**:
For `statues = [6, 2, 3, 8]`, the output should be `make_array_consecutive_2(statues) = 3`.
Ratiorg needs statues of sizes `4`, `5` and `7`.
### Solutions
#### Option 1
```rust
use aiken/list
use aiken/int
use aiken/math
fn make_array_consecutive_2(xs: List<Int>) -> Int {
let vmax = list.foldl(xs, 0, fn(n, reduced) { math.max(n, reduced) })
let vmin = list.foldl(xs, 1000, fn(n, reduced) { math.min(n, reduced) })
vmax - vmin + 1 - list.length(xs)
}
```
#### Option 2
```rust
use aiken/list
use aiken/int
use aiken/option
fn make_array_consecutive_2(xs: List<Int>) -> Int {
let sorted = list.sort(xs, int.compare)
option.or_else(list.last(sorted), 0) - option.or_else(list.head(sorted), 0) + 1 - list.length(xs)
}
```
## Problem: Circle of Numbers
### Statement
Consider integer numbers from `0` to `n - 1` written down along the circle in such a way that the distance between any two neighboring numbers is equal (note that `0` and `n - 1` are neighboring, too).
Given `n` and `firstNumber`, find the number which is written in the radially opposite position to `firstNumber`.
**Example**:
For `n = 10` and `firstNumber = 2`, the output should be `circle_of_numbers(n, firstNumber) = 7`.
### Solutions
#### Option 1
```rust
fn circle_of_numbers(n: Int, firstNumber: Int) -> Int {
(firstNumber + n / 2) % n
}
```
#### Option 2
```rust
fn circle_of_numbers(n: Int, firstNumber: Int) -> Int {
let res = firstNumber + n / 2
if (res >= n) {
res - n
} else {
res
}
}
```
## Problem: evenDigitsOnly
### Statement
Check if all digits of the given integer are even.
### Solutions
#### Option 1
```rust
fn evenDigitsOnly(n: Int) -> Bool {
if (n == 0) {
True
} else if (n % 2 != 0) {
False
} else {
evenDigitsOnly(n / 10)
}
}
```
## Problem: chessBoardCellColor
### Statement
Given two cells on the standard chess board, determine whether they have the same color or not.
### Solutions
#### Option 1
```rust
use aiken/bytearray
fn chessBoardCellColor(c1: ByteArray, c2: ByteArray) -> Bool {
let x1 = bytearray.foldl(c1, 0, fn(byte, acc) { byte + acc})
let x2 = bytearray.foldl(c2, 0, fn(byte, acc) { byte + acc})
x1 % 2 == x2 % 2
}
```
#### Option 2
```rust
fn chessBoardCellColor(c1: ByteArray, c2: ByteArray) -> Bool {
let x1 = bytearray.reduce(c1, 0, fn(byte, acc) { byte + acc})
let x2 = bytearray.reduce(c2, 0, fn(byte, acc) { byte + acc})
x1 % 2 == x2 % 2
}
```
## Problem: [Aiken] Prove NFT Existence
### Statement
Write a function to proves that within a given value, there exists a Policy ID with a single token name having a quantity of 1.
### Solutions
#### Option 1
```rust
use aiken/dict
use aiken/list
use aiken/transaction/value.{PolicyId, Value}
pub fn has_nfts(pid: PolicyId, total: Value) {
when value.tokens(total, pid) |> dict.to_list is {
[(_name, qty)] -> qty == 1
_ -> False
}
}
```
#### Option 2
```rust
fn has_nfts(pid: PolicyId, total: Value) {
let tkns: List<Int> = value.tokens(total, pid) |> dict.values()
let sum: Int = list.foldl(tkns, 0, fn(n, total) { n + total })
and {
// must have only one asset name
list.length(tkns) == 1,
sum == 1,
}
}
```
## Problem: [Aiken] Split list
### Statement
Write a function to divide the list into two parts: the first part contains the first n elements of the original list, and the second part contains the remaining elements. If n is negative or greater than the length of the list, the first part will be empty, and the second part will contain the entire original list.
```
Example:
span([1, 2, 3, 4, 5], 3) == ([1, 2, 3], [4, 5])
```
### Solutions
#### Option 1
```rust
use aiken/list
pub fn span(self: List<a>, n: Int) -> (List<a>, List<a>) {
if n < 0 || n > list.length(self) {
([], self)
} else {
list.span(self, n)
}
```
#### Option 2
```rust
use aiken/list
fn span(self: List<a>, n: Int) -> (List<a>, List<a>) {
if n < 0 || n > list.length(self) {
([], self)
} else {
(list.slice(self, 0, n - 1), list.slice(self, n, list.length(self) - 1))
}
}
```
#### Option 3
```rust
fn span(self: List<a>, n: Int) -> (List<a>, List<a>) {
when self is {
[] -> ([], [])
[x, ..xs] ->
if n <= 0 {
([], self)
} else {
let (left, right) = span(xs, n - 1)
([x, ..left], right)
}
}
}
```
## Problem: [Aiken] Identify Spent Input
### Statement
Check if a specific input by output reference is being spent. This is useful when a minting script requires a utxo to be spent but doesn't need any specific information about that input.
### Solutions
#### Option 1
```rust
use aiken/transaction.{
InlineDatum, Input, Output, OutputReference, TransactionId,
}
use aiken/list
// dont remove imports
pub fn is_spending_input(inputs: List<Input>, out_ref: OutputReference) -> Bool {
list.any(inputs, fn(in) { in.output_reference == out_ref })
}
```
#### Option 2
```rust
use aiken/transaction.{
InlineDatum, Input, Output, OutputReference, TransactionId,
}
pub fn is_spending_input(inputs: List<Input>, out_ref: OutputReference) -> Bool {
when transaction.find_input(inputs, out_ref) is {
None -> False
_ -> True
}
}
```
### Option 3
```rust
use aiken/transaction.{
InlineDatum, Input, Output, OutputReference, TransactionId,
}
pub fn is_spending_input(inputs: List<Input>, out_ref: OutputReference) -> Bool {
// write your code here
when inputs is {
[input, ..rest] ->
if input.output_reference == out_ref {
// it is being spent
True
} else {
is_spending_input(rest, out_ref)
}
// nothing is found so fail
[] -> fail @"Input Not Spent"
}
}
```
## Problem: [Aiken] Create an output reference
### Statement
Create an `OutputReference` from the `TxId#Idx` information. This is useful for building correct output references of specific UTxOs.
### Solutions
#### Option 1
```rust
use aiken/transaction.{
OutputReference,TransactionId,
}
pub fn out_ref(tx_id_hash: ByteArray, idx: Int) -> OutputReference {
// write your code here
OutputReference(TransactionId(tx_id_hash), idx)
}
```
#### Option 2
```rust
use aiken/transaction.{
OutputReference,TransactionId,
}
pub fn out_ref(tx_hash: ByteArray, idx: Int) -> OutputReference {
// write your code here
OutputReference(TransactionId(tx_hash), idx)
}
```
## Problem: [Aiken] Retrieve Datum Data by Hash
### Statement
Find the datum data on a input by the datum hash or error. The data is assumed to be embedded data and must be referenced by its hash
### Solutions
#### Option 1
```rust
use aiken/dict.{Dict}
use aiken/hash.{Blake2b_224, Blake2b_256, Hash}
use aiken/transaction.{DatumHash, NoDatum, InlineDatum, Input, Output, OutputReference, TransactionId}
pub fn input_datum_by_hash(
possible_input: Input,
datums: Dict<Hash<Blake2b_256, Data>, Data>,
) -> Data {
// Write your code here
expect Some(resolved_datum) =
when possible_input.output.datum is {
NoDatum -> None
DatumHash(h) -> dict.get(datums, h)
InlineDatum(d) -> Some(d)
}
resolved_datum
}
```
#### Option 2
```rust
use aiken/dict.{Dict}
use aiken/hash.{Blake2b_224, Blake2b_256, Hash}
use aiken/transaction.{DatumHash, Input, Output, OutputReference, TransactionId}
pub fn input_datum_by_hash(
possible_input: Input,
datums: Dict<Hash<Blake2b_256, Data>, Data>,
) -> Data {
// Write your code here
when possible_input.output.datum is {
DatumHash(inbound_datum_hash) ->
when dict.get(datums, inbound_datum_hash) is {
Some(inbound_datum) -> inbound_datum
_ -> fail @"No Input Datum Attached"
}
_ -> fail @"No Input Datum"
}
}
```
## Problem: [Aiken] Verify Script Output Count
### Statement
Verify that the number of outputs from a specific script is equal the amount intended in the contract. The amount must be exact with the counter.
### Solutions
#### Option 1
```rust
use aiken/transaction.{Input, Output,OutputReference, Transaction, Spend, InlineDatum, TransactionId, NoDatum}
use aiken/transaction/credential.{Address,Script, VerificationKey,Referenced, Credential, StakeCredential, Inline, ScriptCredential}
use aiken/list
pub fn outputs_by_addr(
outputs: List<Output>,
addr: Address,
amount: Int,
) -> Bool {
// write your code here
amount == list.count(outputs, fn(out) { out.address.payment_credential == addr.payment_credential})
}
```
#### Option 2
```rust
use aiken/transaction.{Input, Output,OutputReference, Transaction, Spend, InlineDatum, TransactionId, NoDatum}
use aiken/transaction/credential.{Address,Script, VerificationKey,Referenced, Credential, StakeCredential, Inline, ScriptCredential}
pub fn outputs_by_addr(
outputs: List<Output>,
addr: Address,
amount: Int,
) -> Bool {
// write your code here
do_outputs_by_addr(outputs, addr, 0) == amount
}
// Internal only
fn do_outputs_by_addr(outputs: List<Output>, addr: Address, counter: Int) -> Int {
when outputs is {
[output, ..rest] ->
// exact address match
if output.address == addr {
do_outputs_by_addr(rest, addr, counter + 1)
} else {
do_outputs_by_addr(rest, addr, counter)
}
// loop entire list then return counter
[] -> counter
}
}
```