LocalStorage disabled or you are using an old browser. We try out best to deal with it, but you will need to register (and log in) to have your solutions saved.

Welcome to the 2021 APL Problem Solving Competition!

Learn APL, have fun, and maybe be a prizewinner!

Dyalog Ltd invites you to use the APL programming language and your problem solving skills to compete for a total of USD 6,500 in cash prizes and a paid trip to the next Dyalog user meeting.

The competition is free to enter. The deadline for submission is Friday 30 July 2021 at 23:59 BST.

Overview

The competition consists of two parts:

  • Phase 1 asks you to solve 10 puzzles by writing short APL functions, allowing you to demonstrate array-oriented thinking. You can begin without registering — your solutions should be stored by your browser until you decide to register and submit them (not all browsers do this).
  • Phase 2 comprises a collection of more difficult problems, each having one or two tasks. In addition to requiring array-oriented thinking, this enables you to show off your ability to write larger amounts of well-documented, high-quality, code.

The problem specifications given on this site can also be downloaded as PDF files:

Running Dyalog APL

Although TryAPL might be sufficient for solving the Phase 1 problems, for Phase 2 we highly recommend installing a local desktop Dyalog APL development environment. It is free to download for all platforms (no registration required).

Don't know APL?

Would you like to be able to translate know-how into computer-based solutions quickly and efficiently? APL is an array-oriented programming language that will change the way you think about problems and data. It doesn't take long to learn enough to participate in the competition. Many previous winners of the competition learned APL after they heard about the competition – APL is easy to learn and fun to use, and this is your opportunity to profit from the experience!

Don't have time?

You can win a cash prize without writing a single line of code! Just refer someone to the competition, and if they win a cash prize then you'll receive the same amount as a referral award.

If you're interested in the competition, but don't want to actively participate this year, please register – this will ensure that you're notified with updates on the competition as well as informed about next year's competition (you can un-register at any time).

Are you ready?

To proceed through the competition, click Next .

Discover APL

Getting started with any new programming language can seem like a daunting task so we've tried to simplify this process for you:

  • Start by consulting the APL Wiki's comprehensive index of learning resourcesas well as the materials from previous competitions on Dyalog Ltd's website.

  • If you have a generally applicable question (not a competition-specific one!), consider asking it on Stack Overflow. APL questions are usually answered very quickly there.

  • For technical problems, FAQs, advice and tips, browse the Dyalog Forums.

  • If you need more individual or interactive advice, consider consulting an experienced APLer in The APL Orchard chatroom.

In addition, the core language is fully documented in the online documentation, and the complete documentation set can be found in the Documentation Centre.

Prizes

Only those in full-time education are eligible to win the majority of prizes, although there is a non-student prize that is available if you're not in full-time education.

You do not need to submit an entry in Phase 2 to win a Phase 1 prize, but to win a phase 2 or the non-student prize you must complete at least one Phase 1 problem and at least one problem in Phase 2.

We reserve the right to choose the winners at our sole discretion. Although not anticipated, competition rules and prizes can be changed or altered at any time. The judges' decision is final and no correspondence will be entered into by the judges in relation to their decisions.

Grand prize

USD 2,500 cash prize and an invitation to attend the next Dyalog user meeting. At the user meeting, the winner will receive their prize and have the opportunity to present their winning work. Dyalog Ltd will cover all user meeting fees and travel costs up to USD 3,500, plus USD 500 for incidental expenses, for the winner, but not for family or friends. The winning student is responsible for visas, travel documents and other necessary arrangements and must be legally able to travel.

Traditionally, the Grand Prize winner of the APL Problem Solving Competition is invited to present their work at the annual Dyalog user meeting. As of the 1 February 2021 the next Dyalog user meeting (Dyalog '21) is planned to be held from 10-14 October 2021 in Olhão, Portugal. Should the physical meeting need to be rescheduled due to COVID-19 pandemic safety and travel restrictions, the invitation will still apply to whenever the next user meeting is conducted. In addition, if an online user meeting is held, as it was in 2020, the Grand Prize winner will be invited to present their work at that online event. They will still also receive the cash prize of USD 2,500.

Second prize

USD 1,250 cash prize.

Third prize

USD 750 cash prize.

Phase 2 prizes (5 random participants)

USD 200 cash prize for 5 participants who submit at least one correct entry for Phase 2 of the competition, selected at random.

Phase 1 prizes (top 10)

USD 100 in cash to each of the top 10 Phase 1 participants.

Non-student prize

One non-student participant will win complimentary registration for the next Dyalog user meeting.

Payment

While all prizes are denominated in U.S. dollars, they can be awarded in U.S. dollars (USD), pounds sterling (GBP) or euros (EUR) by electronic transfer to a bank account or a PayPal account. No other forms of payment will be made.

If you are selected as a winner and are unable or unwilling to accept the prize, you cannot transfer the prize or designate someone else as the winner. We reserve the right to award unclaimed prizes to the next highest scoring entrant.

If you accept a prize, you will be solely responsible for all applicable taxes related to accepting that prize.

Sponsors

Referral awards

You can win referral awards equal in value to the cash prizes won by participants who you introduce to the competition.

You do not need to be a student or submit an entry yourself to earn a referral award. For example, if you are not a student but introduced the second prize winner and two winners of Phase 2 prizes, you would receive USD 1,650. If you are the student who won third prize and you also introduced the second prize winner, you would receive USD 2,000.

How do I indicate who referred me? Put the name and email address of your referrer into the "Referrer" input box on your Account details form. This form can be found by clicking the email/username button at the top-right of this page after you've logged in.

Note: All winners who did not indicate at the time of submission who introduced them will forfeit any matching referral awards. You cannot win a referral award for referring a participant of a previous competition.

Timeline for the 2021 Competition

These are the important dates in this year's competition:

Friday 30 July 2021 at 23:59 BST

The competition closes. All entries must be submitted by this time. It doesn't matter when you submit your entries as long as it's before this deadline. You can submit as many times as you like – only your final submission before the deadline will be judged. Submissions will be judged after the deadline has been reached.

Monday 23 August 2021

Announcement of the winners of the competition (they will be formally notified by e-mail by this date).

Detailed rules

Eligibility

The competition is open to everyone except Dyalog employees and problem set contributors. Proof of full-time primary, secondary, college or graduate enrolment is necessary to claim any of the prizes (except the non-student prize). You can be on a sabbatical as long as you will be returning to full-time student status within a year.

Conditions

All participants must submit to these rules.

Participants can only compete with one entry in the competition. However, until the deadline, participants can submit replacement solutions. Only the last submitted solution for a given problem will be judged.

Participants must provide truthful and accurate information regarding contact and personal information.

All entry material must be presented and submitted in English.

Only entries that are received by the deadline are eligible. We cannot accept responsibility for entries that are lost, delayed or damaged. Proof of sending an online entry is not proof that we received it.

Entries not submitted in accordance with these terms and all other rules and directions, or entries that are incomplete or illegible (at the sole discretion of Dyalog Ltd) will be excluded from the competition.

Your submission and its contents can be used at the discretion of Dyalog Ltd

Collaboration

Participants must ensure that all solutions and answers are produced and owned by the participant. If multiple people make nearly identical Phase 2 submissions, all of them will be disqualified. For simpler Phase 2 problems the solutions are likely to end up being similar, so make your submission unique by adding comments in your own words, making it clear that you understand what your code does. You are allowed to collaborate with others in learning APL and solving the problems, but each submission must be made by a single individual and only that individual will be eligible for a prize. Each collaborator can submit their own entry, as long as each entrant's code is unique.

If you choose to share your winnings with other people, then you must make your own arrangements. If you win the grand prize, then you can choose to send a collaborator to the user meeting instead of yourself, but that person is expected to be able to present the work competently.

Please do not post your (partial) solutions online until after the competition has closed, nor seek help from services that provide peer review. We monitor various sites, and reserve the right to disqualify or penalise you for doing so.

Frequently Asked Questions (FAQ)

In APL, how do I...?

In fairness to all, we cannot provide answers to contest-specific questions. Instead, have a look at the Discover APL resources.

Can I utilise functions or code snippets from the workspaces that come with Dyalog (for example, dfns) or other sources?

Yes. However, you will be judged both on the uniqueness of your code and evidence of your understanding of what you are doing. The judges read various forums (and other similar channels) and will notice if contestants are asking for too much help. At a minimum, include comments (in your own words) indicating that you understand what the code is doing — don't just copy someone else's comments along with their code. If you really want to score well, you might want to see if you can improve on the code you find elsewhere.

Does the possibility of winning prize money classify as commercial use of Dyalog APL?

No.

What do I do if there is a problem with the website or I have a question about a problem?

Please report any problems or direct any questions to contest@dyalog.com.

What are the recommended browsers for this site?

We recommend the latest versions of Firefox, Safari, Chrome and Edge.

I did not receive an email with a code when registering. What should I do?

Click Register again and wait for 5–10 minutes. Make sure you check your spam folder. If the code still doesn't come through, then please report the problem to contest@dyalog.com.

Data protection and cookies

We use cookies to keep you logged in and to retain your solutions. By using this site, you agree to this.

We only collect the data necessary for the competition to run, and will use any personal information submitted in accordance with Dyalog Ltd's Privacy Policy.

At any time after you have registered and are logged in, you can erase all data that is stored about you as part of the competition by clicking the user button email@domain.com in the top right corner and selecting Erase account and data.

Consent to usage of information

By entering the competition, you consent to the use by Dyalog Ltd of all images, text and materials that you submit, for any purpose, in any media, for an unlimited period, without remuneration. We have the right to publish, display, reproduce, adapt, promote or otherwise use entries in any way we deem fit. You warrant that you are legally entitled to grant these rights to us and agree to indemnify us in the event that we suffer any loss as a result of false information you provide.

By entering the competition you agree that if you win and subsequently participate in any promotional activities or material, you will do so without additional payment or permission.

Disclaimers

We are not liable for any damage, loss or disappointment suffered by you for taking part or not being able to take part in this competition.

In the event of unforeseen circumstances, we may alter, amend or cancel the competition without prior notice.

We reserve the right to change these terms at any time.

These terms are governed by the Laws of England and Wales and all disputes subject to the jurisdiction of the courts of England and Wales.

Technology

This site was constructed with, and runs on,

MiServer, a free, open-source web server implemented in Dyalog APL. It enables the APL user to build sophisticated websites using the power of APL and with minimal knowledge of web technologies like HTML, JavaScript, and CSS.

To safely verify Phase 1 submissions, we use

Safe Execute for Dyalog APL, a tool developed by Adám Brudzewsky that validates APL expressions as non-destructive, covering built-ins if necessary, and executes them in a sandbox environment.

Contact

If you have feedback, or would like to ask a question that is not already answered here, please e-mail contest@dyalog.com.

image/svg+xml
APL Problem Solving Competition
Phase 1

Introduction

The Phase 1 problems are designed to be solved using short APL functions. If you find yourself writing more than a couple of statements in your solution, then there is probably a better way to do it.

Submission format

Each solution must be a single dfn or tacit function.

A dfn is one or more APL statements enclosed in braces {}. The left hand argument, if any, is represented in a dfn by , while the right hand argument is represented by . For example:

      'Hello' {⍺,'-',⍵,'!'} 'world'
Hello-world!

A dfn terminates on the first statement that is not an assignment. If that statement produces a value, then the dfn returns that value as its result. The diamond symbol separates APL statements. For example:

      'left' { ⍵ ⋄ ⍺ } 'right'
right

More information on dfns can be found on the APL Wiki.

A tacit function is an APL expression that does not explicitly mention its arguments. In the example below, (+⌿÷≢) is a tacit function that computes the average of a vector (list) of numbers:

      (+⌿÷≢) 1 2 3 4 5 6
3.5

More information on tacit functions can be found on the APL Wiki.

Judging Guidelines

Phase 1 will mainly be judged based on:

  • Generality: does your function handle the given edge-cases?
  • Use of array-oriented thinking: did you write array-oriented APL or something that looks more like C# written in APL?

You should not include comments in your Phase 1 solutions.

Tips

  • Several of the problem descriptions will describe arguments that can be a scalar (a single element) or a vector (a list). This is largely pedantic, but in such cases your functions should produce correct results for both types of input.
  • The symbol is the APL comment symbol. In some of the examples, we provide comments to give you more information about the problem.
  • Some of the problem test cases use "boxed display" to make the structure of the returned results clearer. Boxing is always active on TryAPL and can be enabled in your local APL Session with the ]Box user command:
          ⍳¨⍳4
     1  1 2  1 2 3  1 2 3 4 
          ]Box on
    Was OFF
          ⍳¨⍳4
    ┌─┬───┬─────┬───────┐
    │1│1 2│1 2 3│1 2 3 4│
    └─┴───┴─────┴───────┘

Submitting Your Phase 1 Solutions

  • Each problem has a description and one or more examples. Wherever you see "your_functionfn", this is where you should insert your solution (either a dfn or tacit function).
  • Your code must run in a default Dyalog environment using (⎕ML ⎕IO)←1. If you don't know what this means, don't worry as it's the default setting.

Sample problem

The content of the orange box shows what a typical Phase 1 problem description looks like. It also presents some possible solutions of varying quality, and explains how to provide your own solution.

Each problem starts with a task description; some also include a hint suggesting one or more APL primitives. These may be helpful in solving the problem, but you are under no obligation to use them. Clicking on a primitive in the hint opens the Dyalog documentation page for that primitive.

Each problem ends with some example cases. You can use these as a basis for implementing your solution.

Counting Vowels

Write an APL function to count the number of vowels (A, E, I, O, U) in an array consisting of uppercase letters (A–Z).

Hint: The membership function X∊Y could be helpful for this problem.

Examples

      (your_functionfn) 'COOLAPL'
3
      (your_functionfn) ''   ⍝ empty argument
0
      (your_functionfn) 'NVWLSHR'   ⍝ no vowels here
0

Below are three sample solutions. All three produce the correct answer, but the first two functions would be ranked higher by the competition judging committee as they demonstrate better use of array-oriented programming than the third one.

      ({+/⍵∊'AEIOU'}) 'COOLAPL'   ⍝ good dfn
3
      (+/∊∘'AEIOU') 'COOLAPL'   ⍝ good tacit function
3
      ⍝ suboptimal dfn:
      {(+/⍵='A')+(+/⍵='E')+(+/⍵='I')+(+/⍵='O')+(+/⍵='U')} 'COOLAPL'   ⍝ suboptimal dfn
3

Developing a solution/Using the language bar

You can develop your solution using an installed APL system or online using TryAPL and when ready to test it, paste it into the input field labelled your_functionfn, at the bottom of the page. However, you can type a solution directly using either an installed APL keyboard, or by clicking on the appropriate symbols in the language bar ←   + - × ÷ * ⍟ ○ ! ? found directly above the input field. Hovering over a symbol on the language bar will display:

  • The APL symbol.
  • The common names for the concepts that the symbol represents.
  • The symbol's "Tab" input method: Enter two symbols which resemble the APL symbol when overlaid, then press Tab  to combine them. For example, <-Tab  yields the symbol.
  • The symbol's "Backtick" input method: Press any one of the prefix keys `, §, °, ², µ, º, ½ or ù, and then the key according to the diagram here.

Enter your function (without any arguments) into the input field labelled your_functionfn and then hit  Test or   Enter.

  • The system will apply your function on a variety of test arguments.
  • You'll receive a silver trophy ( ) if your function passes all the basic tests.
  • If your solution passes all the basic tests and all the edge cases, you'll receive the highly prestigious and coveted gold trophy with a star ( ).
  • If your solution fails on one or more basic or edge test cases, the system will give an example of arguments that failed.

Submitting your solution

When you're happy with your solution, hit  Submit. You must be logged in to submit. The system will allow you to submit only solutions which at least pass all of the basic test cases. If you want to improve a solution you've previously submitted, you can come back and change your solution but you can only submit valid solutions.

Try it out!

If you put each of the above three functions into the input field and hit  Test or   Enter, you'll see that they receive a silver trophy ( ). This is because none of those functions handle arrays with 2 or more dimensions. The system will also give you an example of a multi-dimensional edge case that failed so that you can attempt to improve your solution.

Try entering {+/,⍵∊'AEIOU'} which handles all test cases and gives you a gold trophy with a star ( ). Note that this sample problem does not affect your results so you can safely leave this page in any state.

your_function ←fn ←

1: Are You a Bacteria?

A DNA string is composed of the letters 'A','C','G' and 'T'. The GC-content of a DNA string is given by the percentage of the symbols in the string that are either 'C' or 'G'. Very small discrepancies in GC-content can be used to distinguish species; for instance, most bacteria have a GC-content significantly higher than 50%.

Write a function that:

  • has a right argument that is a non-empty character vector representing a DNA string.
  • returns the percentage of GC-content in the string.

Hint: The membership function X∊Y could be helpful for this problem.


Examples
      (your_functionfn) 'GCGCGCGCCCGGGGCCG'
100

      (your_functionfn) 'ACGTACGTACGTACGT'
50

      (your_functionfn) 10 12 16 10/'ACGT'
58.33333333
your_function ←fn ←

2: Index-Of Modified

Write a function that behaves like the APL index-of function R←X⍳Y except that it returns 0 instead of 1+≢X for elements of Y not found in X.


Examples
      'DYALOG' (your_functionfn) 'APL'
3 0 4
      
      (5 5⍴⎕A) (your_functionfn) ↑'UVWXY' 'FGHIJ' 'XYZZY'
5 2 0
your_function ←fn ←

3: Multiplicity

Write a function that:

  • has a right argument Y which is an integer vector or scalar
  • has a left argument X which is also an integer vector or scalar
  • finds which elements of Y are multiples of each element of X and returns them as a vector (in the order of X) of vectors (in the order of Y).

Hint: The residue function X|Y and outer product operator X∘.fY might be useful for this problem.


Examples
      ⎕←Y←20?20 ⍝ your example may be different
5 7 8 1 12 10 20 16 11 4 2 15 3 18 14 19 13 9 17 6
      
      2 4 7 3 9 (your_functionfn) Y ⍝ using ]Box on
┌─────────────────────────┬────────────┬────┬──────────────┬────┐
│8 12 10 20 16 4 2 18 14 6│8 12 20 16 4│7 14│12 15 3 18 9 6│18 9│
└─────────────────────────┴────────────┴────┴──────────────┴────┘
      
      3 (your_functionfn) ⍳10
┌─────┐
│3 6 9│
└─────┘
      
      6 7 (your_functionfn) 42
┌──┬──┐
│42│42│
└──┴──┘
      
      2 3 5 (your_functionfn) ⍬ ⍝ returns a vector of 3 empty vectors
┌┬┬┐
││││
└┴┴┘

      ⍬ (your_functionfn) ⍳10 ⍝ returns an empty vector

your_function ←fn ←

4: Square Peg, Round Hole

Write a function that:

  • takes a right argument which is an array of positive numbers representing circle diameters
  • returns a numeric array of the same shape as the right argument representing the difference between the areas of the circles and the areas of the largest squares that can be inscribed within each circle

Hint: The pi times function ○Y could be helpful.


Examples
      (your_functionfn) 2×⍳5
1.141592654 4.566370614 10.27433388 18.26548246 28.53981634

      (your_functionfn) (2*.5)×3 3 ⍴⍳9
 0.5707963268  2.283185307  5.137166941
 9.132741229  14.26990817  20.54866776 
27.96902001   36.53096491  46.23450247 
your_function ←fn ←

5: Rect-ify

Suppose you have a number of trees that you want to plant in a rectangular pattern with complete rows and columns, meaning all rows have the same number of trees. You also want that rectangular pattern to be as "square" as possible, meaning there is a minimal difference between the number of rows and columns in the pattern.

Write a function that:

  • has a right argument N which is a positive integer less than or equal to 1,000,000.
  • returns a 2-element integer vector R representing the rows and columns of the rectangle such that:
    • N=×/R meaning N equals the number of rows × the number of columns (you planted all the trees!)
    • ≤/R meaning the number of rows is less than or equal to the number of columns
    • |-/R is minimal, meaning the difference between the elements of R is as small as possible

Examples using ]Box on
      (your_functionfn) 12
3 4

      (your_functionfn) 16
4 4

      (your_functionfn)¨⍳19
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬────┬───┬────┬───┬───┬───┬────┬───┬────┐
│1 1│1 2│1 3│2 2│1 5│2 3│1 7│2 4│3 3│2 5│1 11│3 4│1 13│2 7│3 5│4 4│1 17│3 6│1 19│
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴────┴───┴────┴───┴───┴───┴────┴───┴────┘

      (your_functionfn)¨999999 1000000
┌────────┬─────────┐
│999 1001│1000 1000│
└────────┴─────────┘
your_function ←fn ←

6: Fischer Random Chess

According to Wikipedia, Fischer random chess is a variation of the game of chess invented by former world chess champion Bobby Fischer. Fischer random chess employs the same board and pieces as standard chess, but the starting position of the non-pawn pieces on the players' home ranks is randomized, following certain rules. White's non-pawn pieces are placed on the first rank according to the following rules:

  • The Bishops must be placed on opposite-color squares.
  • The King must be placed on a square between the rooks.

The good news is that you don't actually need to know anything about chess to solve this problem! We'll use strings whose elements are 'KQRRBBNN' for the King (♔), Queen (♕), 2 Rooks (♖), 2 Bishops (♗), and 2 kNights (♘) respectively.

Write a function that:

  • has a character vector right argument that is a permutation of 'KQRRBBNN'
  • returns 1 if the following are true:
    • the K is between the two Rs
    • the Bs occupy one odd and one even position
    otherwise a 0 is returned.

Hint: The where function ⍸Y and the residue function X|Y could help with solving this problem.


Examples
      
      (your_functionfn) 'RNBQKBNR' ⍝ standard chess layout
1

      (your_functionfn) 'BBNRKNRQ' ⍝ layout in diagram above
1

      (your_functionfn) 'RBBNQNRK' ⍝ K not between Rs
0

      (your_functionfn) 'BRBKRNQN' ⍝ Bs both in odd positions 
0
your_function ←fn ←

7: Can You Feel the Magic?

Wikipedia states that, in recreational mathematics, a square array of numbers, usually positive integers, is called a magic square if the sums of the numbers in each row, each column, and both main diagonals are the same.

Write a function to test whether an array is a magic square. The function must:

  • have a right argument that is a square matrix of integers (not necessarily all positive integers)
  • return 1 if the array represents a magic square, otherwise return 0

Hint: The dyadic transpose X⍉Y function could be helpful for solving this problem.


Examples
      (your_functionfn) 1 1⍴42
1

      (your_functionfn) 3 3⍴4 9 2 3 5 7 8 1 6
1

      (your_functionfn) 2 2⍴1 2 3 4
0
your_function ←fn ←

8: Time to Make a Difference

Write a function that:

  • has a right argument that is a numeric scalar or vector of length up to 3, representing a number of [[[days] hours] minutes] – a single number represents minutes, a 2-element vector represents hours and minutes, and a 3-element vector represents days, hours, and minutes.
  • has a similar left argument, although not necessarily the same length as the right argument.
  • returns a single number representing the magnitude of the difference in minutes between the arguments.

Hint: The functions decode X⊥Y and take could be useful for this problem.


Examples
      2 30 (your_functionfn) 5 15
165
      5 15 (your_functionfn) 2 30
165
      1 0 0 (your_functionfn) 0 ⍝ number of minutes in a day
1440
      1 0 0 (your_functionfn) ⍬ ⍝ don't forget to handle empty arguments!
1440
      1 0 (your_functionfn)¯1 0
120
      1.5 0 (your_functionfn) 90
0
your_function ←fn ←

9: In the Long Run

Write a function that:

  • has a right argument that is a numeric vector of 2 or more elements representing daily prices of a stock.
  • returns an integer singleton that represents the highest number of consecutive days where the price increased, decreased, or remained the same, relative to the previous day.

Hint: The N-wise reduction operator X f/ Y function could be useful when solving this problem.


Examples (the longest runs are highlighted)
      (your_functionfn) 1 2 3 5 5 5 6 4 3
3
      (your_functionfn) 1 2 3 4 4 4 4 4 5 4 3
4
      (your_functionfn) 1 2
1
your_function ←fn ←

10: On the Right Side

Write a function that:

  • has a right argument T that is a character scalar, vector or a vector of character vectors/scalars.
  • has a left argument W that is a positive integer specifying the width of the result.
  • returns a right-aligned character array R< of shape ((2=|≡T)/≢T),W meaning R is one of the following:
    • a W-wide vector if T is a simple vector or scalar.
    • a W-wide matrix with the same number rows as elements of T if T is a vector of vectors/scalars.
  • if an element of T has length greater than W, truncate it after W characters.

Hint: Your solution might make use of take X ↑ Y.


Examples

In these examples, ⍴⎕← is inserted to display first the result and then its shape.


      ⍴⎕←6 (your_functionfn) '⍒'
     ⍒
6

      ⍴⎕←8 (your_functionfn) 'K' 'E' 'Iverson'
       K
       E
 Iverson
3 8

      ⍴⎕←10 (your_functionfn) 'Parade' 
    Parade
10

      ⍴⎕←8 (your_functionfn) 'Longer Phrase' 'APL' 'Parade' 
r Phrase
     APL
  Parade
3 8

      starsForSpaces←'*'@(=∘' ')
      starsForSpaces 6 (your_functionfn) '⍒'
*****⍒
  
your_function ←fn ←

Phase 1: Submissions

You must be logged in to view submitted solutions!

image/svg+xml
APL Problem Solving Competition
Phase 2

Introduction

Phase 2 is similar to Phase 1 in that you submit solutions for each problem separately. In contrast to Phase 1, Phase 2 solutions are likely larger and more complex, and they should be adequately commented. You need to have submitted at least one correct Phase 1 solution before you can submit anything for Phase 2.

Each Phase 2 problem comprises one or more tasks. You must complete all of the tasks for the problem to be considered complete and be judged by the competition committee. You can write additional subfunctions in support of your solutions if necessary.

Each problem description contains one or more examples. However, the judging committee will also submit your solutions to additional testing.

Submission format

You can write your solutions using any combination of tradfns or dfns. The only requirement is that the function name and syntax must match the task description. For example, if the task description is:

Write a function named Plus which:

  • takes a numeric array right argument.
  • takes a numeric singleton left argument.
  • returns a result that is the same shape as the right argument and whose values are the sums of the left argument added to each element of the right argument.

then either of the following would be valid solutions:

∇ r←a Plus b
  r←a+b
∇
Plus←{⍺+⍵}

Judging Guidelines

Phase 2 will mainly be judged based on:

  • Did you solve the problem?
  • Does your solution demonstrate appropriate use of array-oriented techniques? Solutions that use looping where an obvious array-based solution exists will be judged lower.
  • Did you comment your solution? It's not necessary to write a novel, or add a comment to every line, but comments describing non-trivial lines of code are advised. These help the judging committee determine your level of understanding of the problem and its solution.
  • Is your solution original? Your solution should be your own work and not a copy or near-copy of an already-published solution.

Tips

  • Read the descriptions carefully.
  • Don't make any assumptions about shape, rank, datatype, or values that are not explicitly stated in the description. For example, if an argument is stated to be a numeric array then it can be any numeric type (Boolean, integer, floating point, complex) and of any shape or depth.
  • Make sure that your functions return a result rather than just displaying output to the session.
  • Pay attention to any additional judging criteria that are stated in an individual problem's description.

Submitting Your Phase 2 Solutions

  • Unlike previous years where you were asked to submit a single file containing solutions to all the Phase 2 problems you solved, this year you will make an individual submission for each problem.
  • You can submit your solution to a problem in either of the following ways:
    • entering your code in the text area found on the problem page and then submitting the form.
    • saving your code in a file and uploading it from the problem page.
  • All code for your solution to each problem should be included in a single submission. If you define utilities functions used by your solutions, then they should be included. If a problem has more than one task, then you should include functions/operators for each task.
  • If you decide to improve an already-submitted solution, then you can submit new code until the competition deadline. Only the most recent submission for a problem will be judged.

1: Bowling Them Over... (2 tasks)

Ten-pin bowling is an activity in which a player rolls a bowling ball down a bowling lane toward ten pins arranged in an equilateral triangle. The objective is to knock over the pins with the ball. A game consists of ten frames. A frame consists of one or two rolls of the ball. If the first roll results in all ten pins being knocked down, this is known as a strike and the frame is over. Otherwise, the player rolls the ball a second time to attempt to knock down the remaining pins. If all of the remaining pins are knocked down, this is known as a spare. If any pins remain standing after the second roll, this is known as an open frame. Note that if the first roll knocks down zero pins yet the second roll knocks down all ten pins, this is still considered a spare and not a strike.

Scoring:

Each frame on a bowling scoresheet keeps a record of each roll as well as a running total. Frames are scored as follows:

  • Open frame: The total of the two rolls of the frame are added to the running point total.
  • Spare: The frame receives 10 points plus a bonus of the number of pins knocked down on the next roll. A spare in the tenth frame receives an additional roll for bonus points.
  • Strike: The frame receives 10 points plus a bonus of the number of pins knocked down on the next two rolls. A strike on the first roll of the tenth frame receives two additional rolls for bonus points.

Frame Notation:

  • A roll which does not knock down any pins is notated by .
  • A single roll resulting in a strike is notated by X.
  • A second roll resulting in a spare is notated by /.
  • Otherwise the number of pins knocked down is notated.

In the image below of a scored game of bowling there are 5 open frames (frames 1, 2, 3, 5 and 9), 2 spares (frames 4 and 10) and 3 strikes (frames 6, 7 and 8).

  • The scoring for the open frames just adds the total number of pins knocked down in the frame to the running total.
  • The scoring for frame 4 is 24 (the previous total in frame 3) plus 10 (for the spare) plus 9 (as the bonus from the next roll in frame 5) giving a score of 43.
  • The scoring for frame 6 is 52 (the previous total in frame 5) plus 10 (for the strike) plus 20 (as the bonus from the next two rolls which also happen to be strikes) giving a score of 82.
  • The scoring for frame 10 is 136 (the previous total in frame 9) plus 10 (for the spare) plus 7 (as the bonus roll) giving a final score of 153.

A game of bowling can be represented as a character vector. The game in the image can be represented as:

      game←'6272348/9-XXX638/7'

A perfect game consisting of 12 strikes (and scoring 300) would be represented as:

      game←'XXXXXXXXXXXX'

At the other end of the spectrum, a game scoring 0 points would be represented as:

      game←'--------------------'

Task 1: Write a monadic function named ValidGame that:

  • takes a character array right argument that represents a bowling game.
  • returns a Boolean scalar, where 1 indicates that the right argument represents a complete and valid bowling game; 0 otherwise.
Examples
      ValidGame '6272348/9-XXX638/7' ⍝ game from image above
1
      ValidGame ''  ⍝ bad length
0
      ValidGame 'X'  ⍝ not a vector
0
      ValidGame 1 12⍴'X' ⍝ not a vector
0
      ValidGame¨20 20 20 21 12⍴¨'6' '9-' '64' '9/' 'X'
0 1 0 1 1

Task 2: Write a monadic function named BowlingScore that:

  • takes a character vector right argument that represents a complete and valid bowling game.
  • returns a 10-element integer vector representing the frame-by-frame running total score of the game.
Examples
       BowlingScore '6272348/9-XXX638/7' ⍝ game from image above
8 17 24 43 52 82 108 127 136 153
      BowlingScore '--------------------'  
0 0 0 0 0 0 0 0 0 0 
      BowlingScore 'XXXXXXXXXXXX'
30 60 90 120 150 180 210 240 270 300

Your solution

You may submit Phase 2 solutions after you have submitted at least one correct Phase 1 solution.

You may submit your solution by either copying your code into the text area below or selecting a file containing your solution using the "Upload"-Button or by dragging and dropping it on the text-input(file-content will override input in the text-field!).

2: Make a List... (1 task)

This problem is inspired by the "pages to print" specification in many print dialog boxes, where you can enter a set of pages by entering any combination of comma-separated individual page numbers (as in 1,3,5), or hyphenated page number ranges (as in 4-7). Below are two examples of such dialog boxes.

This problem expands on that notation, allowing negative numbers to be used in the list specification. Negative numbers can be specified by prepending either the APL high minus (¯) or a hyphen (-).

Task 1: Write a monadic function named MakeList that:

  • takes a right argument that is a character vector or scalar representing a list specification.
  • returns a vector of the integer(s) specified in the list, in the order in which they were specified.
Examples
      1×MakeList '7' ⍝ the 1× is to verify that the result is numeric
7
      MakeList '7,42,-4,¯5' 
7 42 ¯4 ¯5
      ⍬≡MakeList ''  ⍝ empty list yields an empty numeric vector
1
      1×MakeList '44-42,-4--7,¯1-¯3,42-44'
44 43 42 ¯4 ¯5 ¯6 ¯7 ¯1 ¯2 ¯3 42 43 44

Your solution

You may submit Phase 2 solutions after you have submitted at least one correct Phase 1 solution.

You may submit your solution by either copying your code into the text area below or selecting a file containing your solution using the "Upload"-Button or by dragging and dropping it on the text-input(file-content will override input in the text-field!).

3: As Evenly as Possible... (1 task)

Task 1: Write a dyadic function named Divvy that:

  • has a right argument array that is a simple (non-nested) vector or scalar array.
  • has a left argument n that is a positive integer scalar.
  • returns a result r that is a nested vector such that the following are true:
    • there are n elements in the result: n = ≢r
    • the lengths of each element in the result must not differ by more than 1: 1≥(⌈/-⌊/)≢¨r
    • the elements of the result occur in the same order as the elements the right argument: r ≡⍥∊ array

Note that if the elements of the result are of unequal lengths, then there is no requirement that the longer (or shorter) elements occur in any particular order. This means that:

┌─┬───┬───┐
│1│2 3│4 5│
└─┴───┴───┘
┌───┬─┬───┐
│1 2│3│4 5│
└───┴─┴───┘
┌───┬───┬─┐
│1 2│3 4│5│
└───┴───┴─┘
are all correct answers for
      3 Divvy 1 2 3 4 5
Examples (using ]Box on)

As noted above, the grouping in your results when the elements of r are of different lengths might be different from these examples.

      3 Divvy¨ ⍳¨6 7 8 9
┌─────────────┬───────────────┬─────────────────┬───────────────────┐
│┌───┬───┬───┐│┌─────┬───┬───┐│┌─────┬─────┬───┐│┌─────┬─────┬─────┐│
││1 2│3 4│5 6│││1 2 3│4 5│6 7│││1 2 3│4 5 6│7 8│││1 2 3│4 5 6│7 8 9││
│└───┴───┴───┘│└─────┴───┴───┘│└─────┴─────┴───┘│└─────┴─────┴─────┘│
└─────────────┴───────────────┴─────────────────┴───────────────────┘
      1 Divvy 1 ⍝ returns a nested vector
┌─┐
│1│
└─┘
      5 Divvy 'Dyalog APL'  ⍝ works with character arrays
┌──┬──┬──┬──┬──┐
│Dy│al│og│ A│PL│
└──┴──┴──┴──┴──┘
      4 Divvy ''
┌┬┬┬┐
│││││
└┴┴┴┘
      5 Divvy 'APL'
┌┬─┬┬─┬─┐
││A││P│L│
└┴─┴┴─┴─┘
      1 2 3 Divvy¨ 1
┌───┬────┬─────┐
│┌─┐│┌┬─┐│┌┬┬─┐│
││1││││1│││││1││
│└─┘│└┴─┘│└┴┴─┘│
└───┴────┴─────┘      
      ⎕←a←,(⍳5),[1.1]'ABCDE'  ⍝ mixed character and number
1 A 2 B 3 C 4 D 5 E
      3 Divvy a
┌─────┬─────┬───────┐
│1 A 2│B 3 C│4 D 5 E│
└─────┴─────┴───────┘

Your solution

You may submit Phase 2 solutions after you have submitted at least one correct Phase 1 solution.

You may submit your solution by either copying your code into the text area below or selecting a file containing your solution using the "Upload"-Button or by dragging and dropping it on the text-input(file-content will override input in the text-field!).

4: Going to (Local) Extremes... (1 task)

Given a numeric vector that represents Y values on a graph (the X value is implied by its index within the vector), the midpoint of local minima or maxima can be thought of as the average of the index values that are bounded by positive and then negative slopes or negative and then positive slopes. Usually the midpoints will coincide with the minima or maxima; if there are multiple consecutive minima or maxima then the midpoint will be the mean of the extreme values.

For example, in the graph below, the maxima and minima midpoints as indicated by the red circles are 2 3 4 6.5 8 12. The 6.5 value is due to the consecutive local maximum values at indices 6 and 7.

Endpoints are not considered local minima or maxima. There is no local minima or maxima if there is no inflection of slope, implying that the argument must have at least 3 values.

Task 1: Write a monadic function named MinMax that:

  • takes a right argument that is an integer vector or scalar.
  • returns a numeric vector of the midpoints, if any, of the local minima and maxima.
Examples
      MinMax 3 1 4 1 5 9 9 2 6 6 6 8 5 ⍝ from the example above
2 3 4 6.5 8 12

      MinMax ⍬ ⍝ returns an empty vector (not enough values)

      MinMax 12 ⍝ returns an empty vector (not enough values)

      MinMax 3 3 3 ⍝ returns an empty vector (no inflection point)

      MinMax 1 3 2 4 
2 3

Your solution

You may submit Phase 2 solutions after you have submitted at least one correct Phase 1 solution.

You may submit your solution by either copying your code into the text area below or selecting a file containing your solution using the "Upload"-Button or by dragging and dropping it on the text-input(file-content will override input in the text-field!).

5: Lexicographically Ordered... (2 tasks)

These tasks are inspired by two problems from the excellent Bioinformatics website rosalind.info.

Task 1: Write a dyadic function named lexf that:

  • has a right argument A that is a character scalar or vector of at most 10 unique symbols that define an ordered alphabet.
  • has a left argument n that is an integer scalar in the range [0,6].
  • returns a vector of character vectors that represent all the strings of length n that can be made from A ordered lexicographically (in the same order as found in A).

The inspiration for this task originates from Enumerating k-mers Lexicographically. Note that this task varies slightly from the the original problem description in that we expect your function to address edge cases such as an empty alphabet or a left argument of 0.

Examples using ]Box on
      3 lexf 'APL'
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│AAA│AAP│AAL│APA│APP│APL│ALA│ALP│ALL│PAA│PAP│PAL│PPA│PPP│PPL│PLA│PLP│PLL│LAA│LAP│LAL│LPA│LPP│LPL│LLA│LLP│LLL│
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
      
      3 lexf '' ⍝ returns an empty vector

      3 lexf 'Q'
┌───┐
│QQQ│
└───┘  
      0 lexf 'DNA' ⍝ returns a 1-element vector containing an empty vector  
┌┐
││
└┘
      1 lexf 'DYALOG' ⍝ returns a vector of 1-element vectors
┌─┬─┬─┬─┬─┬─┐
│D│Y│A│L│O│G│
└─┴─┴─┴─┴─┴─┘

Task 2: Write a dyadic function named lexv that:

  • has a right argument A that is a character scalar or vector of at most 12 unique symbols that define an ordered alphabet.
  • has a left argument n that is a positive integer scalar in the range [1,4].
  • returns a vector of character vectors that represent all strings of up to length n that can be made from A ordered lexicographically (in the same order as found in A).

The inspiration for this task originates from Ordering Strings of Varying Length Lexicographically. Note that this task varies slightly from the original problem description.

Examples using ]Box on
      3 lexv 'DNA'
┌─┬──┬───┬───┬───┬──┬───┬───┬───┬──┬───┬───┬───┬─┬──┬───┬───┬───┬──┬───┬───┬───┬──┬───┬───┬───┬─┬──┬───┬───┬───┬──┬───┬───┬───┬──┬───┬───┬───┐
│D│DD│DDD│DDN│DDA│DN│DND│DNN│DNA│DA│DAD│DAN│DAA│N│ND│NDD│NDN│NDA│NN│NND│NNN│NNA│NA│NAD│NAN│NAA│A│AD│ADD│ADN│ADA│AN│AND│ANN│ANA│AA│AAD│AAN│AAA│
└─┴──┴───┴───┴───┴──┴───┴───┴───┴──┴───┴───┴───┴─┴──┴───┴───┴───┴──┴───┴───┴───┴──┴───┴───┴───┴─┴──┴───┴───┴───┴──┴───┴───┴───┴──┴───┴───┴───┘
                        
      3 lexv '' ⍝ returns an empty vector 
      
      1 lexv 'DYALOG' 
┌─┬─┬─┬─┬─┬─┐
│D│Y│A│L│O│G│
└─┴─┴─┴─┴─┴─┘

Your solution

You may submit Phase 2 solutions after you have submitted at least one correct Phase 1 solution.

You may submit your solution by either copying your code into the text area below or selecting a file containing your solution using the "Upload"-Button or by dragging and dropping it on the text-input(file-content will override input in the text-field!).

6: You Sunk My Battleship! (2 tasks)

Battleship is a strategy-type guessing game for two players. It is played on ruled grids (paper or board) on which each player's fleet of ships are marked. The locations of the fleets are concealed from the other player. Players alternate turns calling "shots" at the other player's ships, and the objective of the game is to locate and destroy the opposing player's fleet.

The board game is typically played on a 10×10 grid with each player having ships of lengths 5,4,3,3, and 2. Ships are placed horizontally and/or vertically and cannot overlap or intersect (but can touch other ships). However, for this problem, we'll allow a grid of any size and fleets of arbitrary size with ships of any length (that will fit within the grid).

Your first task will be to validate that a board is an acceptable configuration given the size and fleet parameters.

Task 1: Write a dyadic operator named ValidBoard that:

  • has a left operand size that is a 2-element integer vector specifying the size of the board.
  • has a right operand fleet that is an integer scalar or vector defining the size of ships in the fleet.
  • has a right argument board that is an integer matrix where:
    • a 0 indicates an empty cell.
    • a non-zero value n indicates a cell occupied by the ship at fleet[n]
  • returns an integer scalar or vector where:
    • 1 indicates the board is valid for the size and fleet specified.
    • 0 indicates the board is not valid for the size and fleet specified.
Examples

      ⊢board←3 3⍴2 2 2 1 3 3 1 0 4
2 2 2
1 3 3
1 0 4
      size←3 3
      fleet←2 3 2 1
      (size ValidBoard fleet) board ⍝ valid 3×3 board for fleet of 4 ships of lengths 2 3 2 1
1

⍝ ship 1 is not in contiguous cells
      (3 3 ValidBoard 2 3 2 1) ⎕←3 3⍴2 2 2 1 3 3 0 1 4
2 2 2
1 3 3
0 1 4
0

⍝ there is not a 5th ship in the fleet
      (3 3 ValidBoard 2 3 2 1) ⎕←3 3⍴2 2 2 1 3 3 1 5 4
2 2 2
1 3 3
1 5 4
0

⍝ ship 2 is not the correct length
      (3 3 ValidBoard 2 3 2 1) ⎕←3 3⍴0 2 2 1 3 3 1 0 4
0 2 2
1 3 3
1 0 4
0

⍝ empty fleet can be valid if the board contains no ships
      (3 3 ValidBoard ⍬) ⎕←3 3⍴0
0 0 0
0 0 0
0 0 0
1

⍝ board shape does not match the specified shape
      (4 3 ValidBoard 2 3 2 1) ⎕←3 3⍴2 2 2 1 3 3 1 0 4
2 2 2
1 3 3
1 0 4
0

examples continue…

⍝ ship 3 is not contiguous
      (3 3 ValidBoard 2 3 2 1) ⎕←3 3⍴2 2 2 3 1 3 0 1 4
2 2 2
3 1 3
0 1 4
0

⍝ can't have ships on an empty ocean
      (0 0 ValidBoard 2 3 2 1) 0 0⍴0
0

⍝ Zen Battleship - empty fleet on an empty ocean
      (0 0 ValidBoard ⍬) 0 0⍴0
1

For the second task, we're going to change things a bit by allowing ships to be placed diagonally as well. We know this stretches the laws of physics a bit because ships don't dynamically change length depending on their direction, but play along with us on this one... However, there's a limit to the laws of physics we're willing to violate, for example, ships still must not intersect:

      (2 2 ValidBoard2 2 2) ⎕←2 2⍴1 2 2 1
1 2
2 1
0

Task 2: Write a dyadic operator named ValidBoard2 that has syntax identical to ValidBoard but which allows ships to be placed on diagonals.

Examples
      ⎕←board←3 3⍴2 2 2 1 3 3 0 1 4 ⍝ ship 1 is diagonal

2 2 2
1 3 3
0 1 4
      (3 3 ValidBoard 2 3 2 1) board
0
      (3 3 ValidBoard2 2 3 2 1) board 
1
      
      (3 3 ValidBoard2 1 2 3 2 1) ⎕←3 3⍴1 2 3 2 3 4 3 4 5
1 2 3
2 3 4
3 4 5
1
      
      (3 3 ValidBoard2 3 2 2) ⎕←3 3⍴1 1 1 0 2 0 2 3 3
1 1 1
0 2 0
2 3 3
1      

      (2 2 ValidBoard2 2 2) ⎕←2 2 ⍴1 2 2 1 ⍝ ships may not intersect
1 2
2 1
0

⍝ Zen Battleship - empty fleet on an empty ocean
      (0 0 ValidBoard2 ⍬) 0 0⍴0
1

Your solution

You may submit Phase 2 solutions after you have submitted at least one correct Phase 1 solution.

You may submit your solution by either copying your code into the text area below or selecting a file containing your solution using the "Upload"-Button or by dragging and dropping it on the text-input(file-content will override input in the text-field!).

7: Subsequence-ially (2 tasks)

These tasks are inspired by two problems from the excellent Bioinformatics website rosalind.info.

A subsequence of a string is a collection of symbols contained in order (though not necessarily contiguously) within the string. For instance, 'RTPN' is a subsequence of "THE RAIN ON THE PLAIN IN SPAIN". The indices of a subsequence are the positions in the string where the symbols of the subsequence appear. For the previous example, the indices can be represented by (5 13 17 21). Note that a subsequence can have multiple collections of indices. For the previous example (5 13 17 24), (5 13 17 30) and (5 13 27 30) are also valid collections of indices.

The inspiration for the first task originates from Finding a Spliced Motif. Note that this task varies slightly from the original problem in that we expect your solution to handle empty arguments.

Task 1: Write a dyadic function named sseq that:

  • has a right argument string that is a character scalar or vector of up to 1000 elements
  • has a left argument sub that is also a character scalar or vector of up to 1000 elements
  • returns a 2-element vector where:
    • the first element is 1 or 0 indicating whether sub is a subsequence of string (1) or not (0)
    • the second element is one of the collections of indices for sub if it is a subsequence of string, otherwise

You can download sseqData.txt, which contains a sample dataset, from rosalind.info and use this file to test your solution on a larger dataset than those provided in the examples below. To use this file, substitute {your_foldername} with the location where you've saved the downloaded file:

      (string sub)←⊃⎕NGET '{your_foldername}/sseqData.txt' 1
      string sseq sub
Examples using ]Box on
      'ACGTACGTGACG' sseq 'GTA' ⍝ note: 3 4 10, 3 8 10 or 7 8 10 would also be acceptable 
┌─┬─────┐
│1│3 4 5│
└─┴─────┘
      'ACGTACGTGACG' sseq 'TTT' 
┌─┬┐
│0││
└─┴┘     
      'ACGTACGTGACG' sseq ''
┌─┬┐
│1││
└─┴┘
      '' sseq 'TTT' ⍝ returns empty
┌─┬┐
│0││
└─┴┘
      'T' sseq 'T'
┌─┬─┐
│1│1│
└─┴─┘

The inspiration for this second task originates from Finding a Shared Spliced Motif. Note that this task varies slightly from the original problem in that we expect your solution to handle empty arguments.

A string u is a common subsequence of strings s and t if the symbols of u appear in order as a subsequence of both s and t. For example, "ACTG" is a common subsequence of "AACCTTGG" and "ACACTGTGA".

Task 2: Write a dyadic function named lcsq that:

  • has a right argument s that is a character scalar or vector
  • has a left argument t that is also a character scalar or vector
  • returns a character vector that is a longest common subsequence of s and t. There might be more than one longest common subsequence; in this situation you need return only one.

You can download sseqData.txt, which contains a sample dataset, from rosalind.info and use this file to test your solution on a larger dataset than those provided in the examples below. The verified length of the longest common subsequence for this sample dataset is 619. To use this file, substitute {your_foldername} with the location where you've saved the downloaded file:

      (s t)←⊃⎕NGET '{your_foldername}/lcsqData.txt' 1
            t lcsq s
Examples
      'AACCTTGG' lcsq 'ACACTGTGA' ⍝ AACTTG, ACCTTG, ACCTGG are also valid results 
AACTGG 
      'ACGTACGTGACG' lcsq '' ⍝ returns empty
      
      'ACGTACGTGACG' lcsq 'XYZZYX' ⍝ returns empty

Your solution

You may submit Phase 2 solutions after you have submitted at least one correct Phase 1 solution.

You may submit your solution by either copying your code into the text area below or selecting a file containing your solution using the "Upload"-Button or by dragging and dropping it on the text-input(file-content will override input in the text-field!).

Phase 2 - Summary page

You must be logged in to view submitted solutions!

PLEASE WAIT