457
\$\begingroup\$

What is the Sandbox?

This "Sandbox" is a place where Code Golf users can get feedback on prospective challenges they wish to post to the main page. This is useful because writing a clear and fully specified challenge on the first try can be difficult. There is a much better chance of your challenge being well received if you post it in the Sandbox first.

To post to the Sandbox, scroll to the bottom of this page or click on the "Add Proposal" link below, and click "Answer This Question". Click "OK" when it asks if you really want to add another answer. Write your challenge just as you would when actually posting it. You may also add some notes about specific things you would like to clarify before posting it. Other users will help you improve your challenge by rating and discussing it. When you think your challenge is ready for the public, go ahead and post it, replace the post here with a link to the challenge and delete it.

See the Sandbox FAQ for more information on how to use the Sandbox.

The Sandbox works best if you sort posts by "active".

Add Proposal

Search the Sandbox

Browse your pending proposals

Get the Sandbox Viewer to view the sandbox more easily

To add an inline tag to a proposal use shortcut link syntax with a prefix: [tag:king-of-the-hill]

\$\endgroup\$
  • \$\begingroup\$ How are tags added to questions? \$\endgroup\$ – guest271314 Jan 9 at 7:51
  • \$\begingroup\$ @guest271314 You can use this markup to create a tag in a draft: [tag:code-golf] \$\endgroup\$ – DJMcMayhem Aug 29 at 15:19
  • \$\begingroup\$ Why no featured anymore? Can't we have it auto-added or something? \$\endgroup\$ – JL2210 Sep 26 at 15:57
  • 1
    \$\begingroup\$ @JL2210 We now have a permanent info box that links to the Sandbox, so the featured tag isn't necessary \$\endgroup\$ – caird coinheringaahing Sep 29 at 13:43
  • \$\begingroup\$ I think the sentence 'replace the post here with a link to the challenge and delete it' may specify that the deletion should be done immediately . \$\endgroup\$ – AZTECCO Oct 5 at 19:39

2558 Answers 2558

1
\$\begingroup\$

Lord Vetinari's Clock

Someone very clever — certainly someone much cleverer than whoever had trained that imp — must have made the clock for the Patrician’s waiting room. It went tick-tock like any other clock. But somehow, and against all usual horological practice, the tick and the tock were irregular. Tick tock tick ... and then the merest fraction of a second longer before ... tock tick tock ... and then a tick a fraction of a second earlier than the mind’s ear was now prepared for. The effect was enough, after ten minutes, to reduce the thinking processes of even the best-prepared to a sort of porridge. The Patrician must have paid the clockmaker quite highly.

-- Feet of Clay, by Terry Pratchett

The challenge

Write a function or a program that alternatively outputs "tick" and "tock" every second. There is a 1/5 chance that the tick or tock should be slightly faster or slightly later than expected, with a 50/50 chance between it being early or late. The time difference should be 0.2 seconds.

The clock should still keep accurate time: that is, if a tick or a tock is early or late, the next tick or tock should still be on-time. The clock itself should not "drift" because of the displaced ticks or tocks.

Rules

The usual rules and loopholes apply.

This is code golf: shortest code wins.

\$\endgroup\$
  • 3
    \$\begingroup\$ Please give an objective definition of "small, but noticeable". I can say 0.01s are noticeable to me because I am Data (or Lore) \$\endgroup\$ – wastl Jul 22 '18 at 13:00
  • 1
    \$\begingroup\$ I think an important part should be that, overall, the program should still keep accurate time \$\endgroup\$ – Jo King Jul 23 '18 at 2:58
  • \$\begingroup\$ I agree - I'll rewrite that part so that the clock still keeps accurate time. \$\endgroup\$ – Ciaran_McCarthy Jul 23 '18 at 7:54
  • \$\begingroup\$ Going Postal - "Sometimes the tick was just a fraction late, sometimes the tock was early. Occasionally, one or the other didn’t happen at all." <- any chance of including the bolded part (emphasis mine)? Also, is there a 1/5 chance of any alteration (fast or slow), or 1/5 chance of fast and another 1/5 of slow? \$\endgroup\$ – boboquack Aug 3 '18 at 11:43
  • \$\begingroup\$ @boboquack and if tock is omitted, is the next output a tick or a tock? \$\endgroup\$ – JayCe Aug 14 '18 at 20:25
  • \$\begingroup\$ @JayCe I would assume a tick though that's up to the OP of course. \$\endgroup\$ – boboquack Aug 14 '18 at 22:26
  • \$\begingroup\$ I would say that if a tock is omitted, the next output would be a tick, and vice versa. Would the Going Postal requirement be a good one for a bonus critera, so -10% for omitting the tick or the tock? Or would it be better as part of the normal requirements? \$\endgroup\$ – Ciaran_McCarthy Aug 16 '18 at 7:40
1
\$\begingroup\$

Looking for feedback on my first question.

Title: Largest Left-Truncatable Prime in Base \$b\$ (A103443)

Introduction

Numberphile recently posted a video about truncatable primes, and the concept seems like it would make a good base for a number of good code golf exercises. I explain the concepts below, but watch the video only if you want ideas about an algorithmic process for finding them.

A left-truncatable prime in base \$b\$ is a prime \$p\$ such that

  • all the digits of \$p\$ in base \$b\$ are nonzero, and
  • when any number of leading digits of \$p\$ when written in base \$b\$ are removed, the result is still a prime. (That is, every suffix of \$p\$ when written in base \$b\$ is a prime, when still interpreted in base \$b\$).

For example, \$1223\$ is a left-truncatable prime in base \$10\$, since \$1223\$, \$223\$, \$23\$, and \$3\$ are all prime; \$1223\$ is also a left-truncatable prime in base \$4\$, since \$1223\$, \$223\$, \$23\$, and \$3\$ are all prime when considered in base \$4\$ (in base \$10\$ they are \$107\$, \$43\$, \$11\$, and \$3\$, respectively). OEIS sequence A024785 is a list of all left-truncatable primes in base \$10\$.

There are many variants on this concept, but this is all you need for this challenge. This concept also appeared in this challenge from two years ago.

Challenge

Your challenge is to find the largest left-truncatable prime in base \$b\$. You can show (from this paper I believe) that there are only finitely many left-truncatable primes for a given base, so the largest one exists. Here it is instrumental that we require these primes to have all nonzero digits; otherwise, there would be no largest one.

For example, the largest left-truncatable prime in base \$10\$ is 357686312646216567629137, as mentioned in the above video. These are found in A103443.

Your program must input an integer \$b \geq 3\$, and output an integer written in base \$10\$ which is the largest left-truncatable prime in base \$b\$ (indeed, one must always exist as well). Your program/function should work for any input \$b\$ your language supports.

This is code-golf, so the shortest answer wins! No standard loopholes, but built-in primality testing is allowed.

If your program fails because it would require integers that exceed your language's max integer, then state so in your solution; these solutions are still allowed, but solutions that aren't limited by the language's max integer are better. Alternatively, if you are restricted by a max integer, give the largest left-truncatable prime base \$b\$ that is smaller than this max integer.

Example Input and Output

Input:

10

Output:

357686312646216567629137

See A103443 for more test cases.

Remember that \$1\$ is not a prime.

\$\endgroup\$
  • \$\begingroup\$ Hi, welcome to PPCG! This looks like a great and well-formatted first challenge, so not much to add. The only thing is that I would add some more test cases to the challenge description itself. I doubt the link oeis.org/A103443 will ever be gone, but challenges should be self-contained as much as possible. \$\endgroup\$ – Kevin Cruijssen Jul 31 '18 at 10:04
  • 2
    \$\begingroup\$ Looks pretty much fine to me as a pure golf. +1 on add a couple more test cases. Note, however, that it is likely that solutions, especially those in golfing languages, may well be posted that do not run for bases above some pretty low limit (e.g. 6) due to the implementation. In cases like this some like the challenge to remain pure-golf and allow this while others choose to require some observed run requirement - e.g. "must've been observed to run for base 12 within 60s (post online interpreter link or local output)". Totally up to you on that (anyone else here have an opinion?). \$\endgroup\$ – Jonathan Allan Jul 31 '18 at 12:04
  • \$\begingroup\$ I feel like this is going to work sort of like a breadth first search. \$\endgroup\$ – fəˈnɛtɪk Aug 3 '18 at 18:34
1
\$\begingroup\$

Locate Substring

This is not a challenge yet, just a place to write down an idea.

Given some finite binary string \$S\$, we can try to find the minimal length \$n \in \mathbb N\$ such that we can uniquely locate each contiguous substring \$ T \$ of \$ S \$ that has length \$ n \$.

Example

Let \$ S = 01000110 \$. Then surely \$ n > 1\$. But we also immediately see that \$ n > 2\$ because for instance the substring \$T = 01\$ appears twice in \$ S = \color{red}{01}00\color{red}{01}10\$. But all substrings of length \$ n=3 \$ are distinct, these are in fact (in the order they apppear from left to right) \$ \{ 010, 100, 000, 001, 011, 110 \} \$. This means that \$ n=3 \$ is minimal. [end of example]

Alternatively given some \$ n \$ one might ask to find the longest sequence \$ S \$ such that all substrings \$ T \$ of length \$ n \$ are uniquely locatable.

\$\endgroup\$
  • \$\begingroup\$ Interesting idea, though I think the alternative would create more interesting solutions. \$\endgroup\$ – ბიმო Jul 28 '18 at 15:19
  • \$\begingroup\$ @OMᗺ I think the solution to the "alternative" are the de-Bruijn sequences, which we've covered here. \$\endgroup\$ – flawr Jul 31 '18 at 20:58
  • \$\begingroup\$ Ah true, that would be a dupe. \$\endgroup\$ – ბიმო Jul 31 '18 at 21:07
1
\$\begingroup\$

Order times fully written out in English, alphabetically

A 12h format time of day can be fully written out in English according to the following rules:

  1. a word from one to twelve;

  2. a space;

  3. optionally a word from one to fifty-nine followed by a space;

  4. the "word" AM or PM.

Examples:

 1:31 AM  => "one thirty-one AM"
11:12 PM  => "eleven twelve PM"
 4:00 AM  => "four AM"

Challenge

The challenge is to take a list of 12h format times and order them alphabetically by the way they are fully written out in English.

Input and output format is flexible. Output can either be the times themselves or their fully written out in English versions.

This is . Shortest in bytes for each language wins. Standard loopholes forbidden.

Test cases

[ "1:31 AM", "11:12 PM", "4:00 AM" ]   =>   [ "11:12 PM", "4:00 AM", "1:31 AM" ]

More test cases can be added if there is interest.

I'm mainly concerned this might be a dupe. I couldn't find one.

\$\endgroup\$
  • \$\begingroup\$ There's no real pattern there, so it will most likely be answers sortBy(inputs, key=toEnglishString), I think. Why not just ask for translating it to English? \$\endgroup\$ – ბიმო Aug 3 '18 at 3:46
  • \$\begingroup\$ A dupe of codegolf.stackexchange.com/q/71203/80010 I believe \$\endgroup\$ – JayCe Aug 14 '18 at 20:15
1
\$\begingroup\$

Edit distance for sparse strings

The input to this challenge will be two strings of length one million each. Each string contains only zeros and ones. However each string will contain at most 100 ones and so will be represented by a sorted list of integers. The integers will indicate where the ones are.

Example of input

[ 42394, 108181, 154190, 217161, 301607, 379951, 412651, 623862, 624712, 783863]
[ 42393, 108181, 154189, 267161, 301608, 379951, 412651, 623862, 624713, 783863]

We want to compute the Levenshtein distance between these two strings. However, the standard algorithm will take around 10^12 time which is too slow.

Task

Your code should take in the two inputs and output the edit distance between the two strings. The only restriction is that your code must be fast enough (and not use too much memory) so that it will complete in less than a minute on a standard desktop PC. In case of doubt, I will test the code on my 8GB AMD processer PC using test inputs that I will create.

Small test cases

To test your code here are some small inputs for strings of length 100 with up to 10 ones.

This pair gives edit distance 8.

[18, 23, 30, 40, 47, 53, 60, 73, 89, 94]
[21, 23, 39, 48, 53, 59, 60, 89]

This pair gives edit distance 8

[19, 25, 26, 40, 43, 62, 74, 75, 85, 89]
[10, 26, 27, 28, 44, 70, 74, 75, 76, 86]

This pair gives edit distance 7

[ 9, 17, 18, 29, 45, 50, 57, 64, 80]
[ 2, 16, 23, 27, 32, 43, 49, 56, 63, 79]

This pair gives edit distance 6

[ 3,  9, 12, 33, 39, 49, 55, 72, 84, 94]   
[ 3,  9, 29, 40, 41, 72, 84, 94]

\$\endgroup\$
  • \$\begingroup\$ I don't think they are closely related. \$\endgroup\$ – Anush Aug 5 '18 at 16:18
1
\$\begingroup\$

Make a reversible formula

For the purposes of this question:

  1. a basic formula \$ y = f(x) \$ takes one of the following forms:

$$ x \\ g(x) + c \\ c + g(x) \\ g(x) - c \\ c - g(x) \\ g(x) c \\ c g(x) \\ \frac {g(x)} c \\ \frac c {g(x)} $$

where \$ g(x) \$ is a basic formula;

  1. a reversible formula \$ y = f(x) \$ takes one of the following three forms:

$$ \begin{align} y = x & \implies x = y \\ y = c - g(x) & \implies x = g^{-1}(c - y) \\ y = \frac c {g(x)} & \implies x = g^{-1} \left ( \frac c y \right ) \end{align} $$

where \$ g(x) \$ is a reversible formula whose reverse is \$ g^{-1}(x) \$ according to the above rules and \$ c \$ is a non-negative integer. A simple example of a reversible formula would be the expression \$ y = \frac 1 {1 - x} \$ whose reverse is \$ x = 1 - \frac 1 y \$.

Your challenge is to take a basic formula and express it as a reversible formula. The following transformations are allowed:

$$ \begin{align} \left . \begin{array}r x + c \\ c + x \end{array} \right \} & \implies c - (0 - x) \\ x - c & \implies 0 - (c - x) \\ \left . \begin{array}r x c \\ c x \end{array} \right \} & \implies \frac c {\frac 1 x} \\ \frac x c & \implies \frac 1 {\frac c x} \end {align} $$

(Note that the strict domain of the resulting formula may exclude some values not excluded in the original formula, but the limit of the formula should be equivalent to the original formula.)

Of course we're dealing in string equations so you'll be using * and / instead. Examples:

(x + 1) * 2 => 2 / (1 / (1 - (0 - x)))

x * 2 + 1 => 1 - (0 - 2 / (1 / x))

Do not include extraneous parentheses in your result.

This is , so the shortest submission that breaks no standard loopholes wins!

\$\endgroup\$
  • \$\begingroup\$ What's the associativity of -? \$\endgroup\$ – user202729 Aug 12 '18 at 11:46
  • 1
    \$\begingroup\$ @user202729 Normal left associativity. \$\endgroup\$ – Neil Aug 12 '18 at 12:18
  • \$\begingroup\$ What are the rules for spaces in expresisons? \$\endgroup\$ – user202729 Aug 12 '18 at 14:27
  • \$\begingroup\$ @user202729 You don't need to support spaces. They're just there for legibility. \$\endgroup\$ – Neil Aug 12 '18 at 19:48
  • \$\begingroup\$ @Neil Cool Challenge! Very interesting \$\endgroup\$ – Don Thousand Aug 12 '18 at 21:02
  • \$\begingroup\$ @Rushabh Comments should only be used for improvement/clarification. For other purposes, use different tools, i.e., flags, votes, answers. \$\endgroup\$ – user202729 Aug 13 '18 at 6:50
  • 1
    \$\begingroup\$ I find this rather hard to understand, perhaps because it fails to distinguish equations from expressions, calling both formulae. I'm not even sure whether part 2 is talking about transformations between equations or about Boolean expressions. It would perhaps be clearer if all equations were removed and expressions were defined using a grammar in BNF. \$\endgroup\$ – Peter Taylor Aug 13 '18 at 11:00
1
\$\begingroup\$

Should I index like this or like that?

Challenge

Let's take a 0-indexed array of length \$l\$. You can index into it with \$i\$, where \$-l\le i<l\$, and the returned element is the element in position \$[i<0]\times l+i\$ (\$[\dots]\$ is the Iverson bracket).

In some cases, it's shorter to use a negative index instead of a positive one, counting the minus sign and the digits as bytes. For example, if we want the \$102\$th element of an array with \$104\$ elements, indexing with \$101\$ and \$-3\$ will both give the same result. However, if we write the numbers in code, 101 is 3 bytes long, while -3 is 2 bytes long, so we prefer -4. In other cases, using a negative index is counterproductive (for a code golfer). Such an example is the will to obtain the \$4\$th element of a \$10\$-element array. In this case, we can use \$3\$ and \$-7\$, but -7 is longer than 3, so we'll choose 3 instead.

Given two inputs \$l\$ and \$i\$, where \$l>0\$ (it doesn't make sense to index into an empty array) and \$0\le i<l\$ (or \$-l\le i<0\$, be consistent), your job is to determine whether positive or negative indexing is better for code golfing purposes. In case both are of the same length, you may return either decision, even inconsistently. The returned value must be one of two distinct and consistent values, defined by the answerer.

Of course, using standard loopholes isn't fun, so, if you do use any, then, sorry, your answer isn't valid. ;-)

Test cases

Here, 1 is used for negative indexing and 0 for positive. I also always prefer using positive indices, but you may prefer otherwise.

l     i           (actual index)
----- ----- ----- -----
    1     0     0     0
   10     9     0     9
 1000   999     1    -1
10000  9755     1  -245
  101   100     1    -1
  150   141     1    -9
  150   140     0   140
\$\endgroup\$
  • \$\begingroup\$ Could we output True/False values instead? \$\endgroup\$ – Don Thousand Aug 19 '18 at 0:26
  • \$\begingroup\$ @RushabhMehta True and False are two distinct values; however, outputting "truthy or falsy" but not necessarily consistent values isn't okay. The actual truthiness of the returned value doesn't matter. \$\endgroup\$ – Erik the Outgolfer Aug 19 '18 at 0:38
  • \$\begingroup\$ Ugh...there goes my lean solution \$\endgroup\$ – Don Thousand Aug 19 '18 at 0:39
  • \$\begingroup\$ @RushabhMehta Sorry, but I consider truthiness, as defined by consensus, to be a tad bit unclear, since many languages don't have only one feature you can call an "if construct". \$\endgroup\$ – Erik the Outgolfer Aug 19 '18 at 0:42
1
\$\begingroup\$

Fuzzy Circles

Edit

I don't actually like this challenge all that much. Anyone who wants it can have it, else I'll get rid of it.

Background

For a real number x, let ⌊x⌋ be the greatest integer less than or equal to x.

Challenge

Given an input n, find the minimum radius of the circle such that all points that satisfy the following equation are on its interior or border.

⌊x⌋^2+⌊y⌋^2 = n

Input: A real number n

Output: A real number representing the radius of the smallest circle that contains in its interior or border all points that satisfy ⌊x⌋^2+⌊y⌋^2 = n.

Note: The precision expected in this challenge is two decimal places, both for the input and output.

This is a challenge.

Test Cases (More to be added):

25->5.70

\$\endgroup\$
1
\$\begingroup\$

Knightmare in 1024 bytes of (JavaScript?)


Board

The board is a 16x16 grid of squares. It does not wrap, so the outer edges are an impassable boundary.

Pieces

Each piece is like a Chess knight, and will be referred to as a knight. It moves to a square that is two squares away horizontally and one square vertically, or two squares vertically and one square horizontally.

Chess board showing a knight and its moves

A knight can move to any of these squares, regardless of whether it is occupied. There is no limit to how many knights may occupy the same square at the same time.

Players

This is a 2 player game. Each player has 16 knights. Knights cannot be removed from the board so there will still be 16 knights per player at the end of the game.

Turns

Each turn both players move all 16 of their knights simultaneously (that is, all 32 knights move at the same time).

Costs

Each square has a cost, which is a non-negative integer, initially set to zero. Each time a knight visits a square, the cost of that square is increased by 1. To be explicit, if N knights land on a square in the same turn, that square's cost is increased by N.

Penalties

After each turn, each knight incurs a penalty, which is the cost of the square it occupies, plus the number of other knights occupying the same square (regardless of whether they are friend or foe).

The player's cumulative penalty is zero at the start of a game, and is increased by each knight's penalty each turn (for all 16 of its knights).

Winning

A game ends after 1024 turns. The winner is the player with the lowest cumulative penalty.

Input

The player is supplied with:

  • an array showing the cost for each square
  • an array showing the number of its own knights for each square
  • an array showing the number of its opponent's knights for each square
  • an array showing the total knights for each square
  • an array of coordinates for its own knights
  • an array of coordinates for its opponent's knights
  • its own cumulative penalty
  • its opponent's cumulative penalty
  • the turn number

Output

The player responds with a move for each of its 16 knights. Each move is a number from 0 to 7, indicating the direction to move, numbered clockwise from the top. The response must be received within 5ms.

Invalid moves

Since the edge of the board is impassable, sometimes there will be fewer than 8 valid moves available for a given knight. If an invalid move is given, it will be reflected vertically and/or horizontally to give a valid move, and that move will be made instead. This means every knight will move every turn - none will ever stand still.

Code

Each entry provides the body of a JavaScript function that is no more than 1024 bytes.


Sandbox questions

  • I'm not settled on which language to use yet. I like the idea of using a different language for each KotH. I'm considering maybe Japt or APL for this one. Ideally something terse since golfing is part of the challenge here.
  • Fixed starting configuration (for example, players in a line along opposite edges of the board), or random initial placement?
  • Leaning towards a board that does not wrap. Any reasons to avoid this?
  • I've put placeholder values for the number of bytes, the size of the board, and the number of knights per player. Any feedback on how to improve these values welcome.
  • I'm not sure whether to make staying still a valid move. I'd prefer to keep it simple and have 8 possible moves with no possibility of staying still.
  • I'm currently deciding between the penalty being the cost plus the number of other knights on the same square, or the cost times the number of knights on the square.
  • I need to settle on input and output that are suitable for both golfing the contestant code and keeping things running reasonably quickly.
\$\endgroup\$
  • \$\begingroup\$ "cost plus number of other knights" means other knights aren't that much of a hindrance, since the cost of visiting a square with a knight in it is only one point more than visiting a square that was previously visited. (And I would expect most squares to have been previously visited multiple times.) "cost times number of other knights" makes it very different, as it becomes almost entirely about avoiding other knights, much more than avoiding previously visited squares. I'm not sure which is best, just pointing this out. \$\endgroup\$ – Nathaniel Apr 22 '18 at 15:00
  • \$\begingroup\$ Also: when I read "knightmare", I imagined a child wandering through computer generated rooms wearing a helmet that you can't see out of, guided by Treguard and his sidekick Pickle the Elf. This may be because I am a British person of a certain age. \$\endgroup\$ – Nathaniel Apr 22 '18 at 15:02
  • \$\begingroup\$ Maybe I need something in between then. Will give it some more thought \$\endgroup\$ – trichoplax Apr 22 '18 at 15:08
  • \$\begingroup\$ I am also a British person of a certain age. I may change the title before posting... \$\endgroup\$ – trichoplax Apr 22 '18 at 15:08
  • \$\begingroup\$ I feel like there's very little room for strategy here. Moving to the smallest-cost room will pretty much always be the best strategy, and if it's not, it will only be wrong by a couple of points (and a single-turn look-ahead will greatly mitigate that) I think that there will be too much randomness (in how the enemy moves) to really make this interesting. \$\endgroup\$ – Nathan Merrill Apr 22 '18 at 15:41
  • \$\begingroup\$ I don't personally think challenges should impose a maximum byte count. Is there a reason that only allowing 1kB is important? \$\endgroup\$ – Kamil Drakari Apr 22 '18 at 17:16
  • \$\begingroup\$ I'm against minimum required scores in code golf, agreeing entirely with Martin's arguments. In that context the byte count is the score, and I wouldn't want to exclude anyone, or prevent someone from posting a long answer that can gradually be improved over time. I see this KotH as different. The limit is not intended as a barrier to entry. I want to choose a limit that will allow anyone to post a basic entry, and then gradually improve it over time as they find ways to fit more in. \$\endgroup\$ – trichoplax Apr 22 '18 at 19:06
  • \$\begingroup\$ I want a KotH that has some of the aspects of a code golf challenge. That was the initial idea, and the knights came later. If they are not considered a good fit then I will consider changing the game to something that fits a byte limited challenge better. The other option is to have no byte limit but make the number of bytes somehow penalise the player, whether in increasing their score or restricting their abilities within the game. That seems harder to get right, so I'm going with a byte limit as the simplest way of including short code as a game constraint. \$\endgroup\$ – trichoplax Apr 22 '18 at 19:10
  • \$\begingroup\$ @NathanMerrill I've also worried about this. This is part of why I'm considering a significantly increased penalty when sharing a square with other knights, to allow blocking off the opponent knights from lower cost regions. I feel like that will be one of the most important things to fine tune carefully before posting the challenge \$\endgroup\$ – trichoplax Apr 22 '18 at 19:16
  • \$\begingroup\$ Another way of thinking about the byte limit: Code golf has a single fixed task and the byte count varies. This KotH has a single fixed byte count and what people choose to do with it varies. \$\endgroup\$ – trichoplax Apr 22 '18 at 19:18
  • \$\begingroup\$ Contests like Tweetable Mathematical Art have a byte limit but are too broad. The idea with this KotH is to have a byte limit combined with an objective way of measuring competitors against each other, making the requirement very specific (outcompete the others) while leaving the method open. \$\endgroup\$ – trichoplax Apr 22 '18 at 19:22
  • \$\begingroup\$ @trichoplax Your code-golf goals might be better achieved if you make a custom language for this. If you make a more-or-less "flat" language, and score it by the number of lines, then you have the challenge of "fitting stuff in", without resorting to typical golfing. \$\endgroup\$ – Nathan Merrill Apr 23 '18 at 1:34
  • \$\begingroup\$ I think the limited byte count is a good idea, or could be, as long as optimal solutions to the challenge are much too complicated to fit into the available space. (See Paint Starry Night for an example where this worked well, in my humble opinion). That might not be the case here though, as the challenge might not require very complicated strategies, and 1024 bytes is pretty huge even for Javascript. (In Starry Night most competitive entries used most of that space for data rather than code.) \$\endgroup\$ – Nathaniel Apr 23 '18 at 2:05
  • 1
    \$\begingroup\$ What I don't want is a KotH where you write the same solution you would have without the limit, and then have the extra task of golfing it. I want the limit to lead to innovation, not just extra work \$\endgroup\$ – trichoplax Apr 23 '18 at 6:11
  • 1
    \$\begingroup\$ JS-only? That's a bad enough restriction at the best of times, but when you're also imposing tight time limits it's worse. \$\endgroup\$ – Peter Taylor Apr 25 '18 at 12:01
1
\$\begingroup\$

Golf me some Golf

Write a program to play Golf solitaire!
(I'm somewhat surprised that I haven't seen this pun yet.)

How to play

Golf uses a standard 52 card deck. Play begins with 7 stacks of 5 cards each, one card forming the foundation, and the remaining 16 cards forming the stock. There are two legal moves:

  • Move a card from the top of a stack to the foundation (must be one rank higher or lower)
  • Draw the top card of the stock and place it on the foundation

The number of cards remaining in the tableau when you run out of moves is your score, with zero being a perfect game.

To make things easier, queens may be played on kings, and aces and kings can be played on each other. Also, while the stock is normally face-down, you will be able to read it all at once.

Rules

The input to your program will be 7 lists of 5 cards representing the tableau (with the last cards on top) plus 1 list of 17 representing the stock (the last card being the foundation). These lists can be flattened as desired (you can take 1 list of 35 and 1 list of 17, or just 1 list of 52). Cards are represented as numbers 0-12.

Your program should output a list (or string) of numbers 0-7 representing the moves in a game of Golf. The numbers 0-6 represent playing a card from a column to the foundation, and 7 represents drawing a card from the stock. Any illegal moves (including playing from an empty column or stock) will disqualify your program.

Your score is the number of bytes in your program plus 2 bytes per card left on the stock after running through the 18 games in the scoring set. The program with the lowest score wins.

Test cases

Example output: (coming soon)

Scoring set: (coming soon)

All games in the scoring set are solvable.


Sandbox questions:

  • Is code-golf appropriate for this scoring metric, or would code-challenge be more appropriate?

  • Should I do away with the scoring metric, and just require the games to be solved completely?

  • Would it be more interesting to include some unsolvable games in the scoring set to make programs handle that case gracefully?

\$\endgroup\$
  • 1
    \$\begingroup\$ Honestly, I think code-challenge would be more suitable for this. Code golf usually isn't good for things like this. I'd say best solitaire player wins. \$\endgroup\$ – Redwolf Programs Aug 26 '18 at 15:16
1
\$\begingroup\$

Permutation Encoding

Now posted to the main site. Check the revisions log if you want to see the WIP versions.

\$\endgroup\$
  • \$\begingroup\$ IMO it would improve the question to edit in the part about Discord so that it is a motivated problem rather than an arbitrary challenge. All of the elements of this have already been covered by earlier challenges (bijective bases and permutation indices), but the variation in lengths probably push it out of duplicate territory. \$\endgroup\$ – Peter Taylor Aug 29 '18 at 8:33
  • \$\begingroup\$ I put the backstory at the bottom. I thought it had lower priority than the problem itself. I'm also concerned that if I put it at the top, it'd give the impression that Discord reactions is the problem rather than the actual problem I posted. Even if it's clear they're distinct, it might still be confusing since the actual problem is very different from its inspiration. // Also, there's some room for creativity here, I used a numbering approach but I'm sure more clever encoding methods are possible and golf better. There's 2.16E148 possible original and 2.81E148 possible encoded strings. \$\endgroup\$ – EPICI Aug 29 '18 at 17:32
  • \$\begingroup\$ Ah, I misinterpreted "Extras" as heading some information which you intended to be only for the sandbox. \$\endgroup\$ – Peter Taylor Aug 29 '18 at 17:51
  • 3
    \$\begingroup\$ If you've posted this to main, could you please clear and delete it to clear up clutter? Thanks! \$\endgroup\$ – Jo King Sep 4 '18 at 6:04
  • \$\begingroup\$ Please delete your challenge proposal to remove clutter. \$\endgroup\$ – Jonathan Frech Sep 18 '18 at 21:29
1
\$\begingroup\$

Distinct Dice Sum Algorithm

From a puzzle on Brainden. Paraphrasing,

What is the best set of 8 sided dice, each identical, such that 3 dice can generate 120 distinct sums? "Best" means the minimum highest sided die configuration.

With 7 sided dice, the best possible sides for each (identical) die is: 1, 2, 8, 51, 60, 79, 83.

For the sake of discussion, use sides=s, and dice=d.

Note1: 120 is the maximum number of distinct sums with s=8, d=3. The formula is:

$$ \frac{(s+d-1!)}{(s-1)!(d)!} $$

Similarly, for s=7, d=3, the formula gives 84. And brute force shows that a side of at least 83 is required for this easier problem.

Note2: The lowest numbered side is always 1 for an optimal solution to the original question. (See comments.)

My question is, "What's the fastest algorithm to discover the minimum highest sided die for maximum distinct sums?".

Specifically, is there some existing algorithm, or better yet, formula, for the minimum highest sided die? For determining all sides?

While there are obvious choices for languages, I'm not interested in that. I'm interested in the best algorithm possible in general. A sketch of the algorithm with the best (smallest) Big-O score wins.

Complexity of answers should be expressed by Big-O notation, e.g., M(s) = O(???), with d=3. Ties will be broken according to number of dice, i.e., M(s,d) = O(???).

As a puzzle toy to idle time some years ago, I wrote a brute force solver. Unfortunately, for (s=8, d=3), and even knowing an upper limit, my program never completed the search (uptime was an issue).

\$\endgroup\$
  • 3
    \$\begingroup\$ To turn this into a challenge, you'll have to pick an objective winning criterion. fastest-algorithm would work if you want to minimize asymptotic time complexity, but since the complexity will depend on s and d, you'll have to combine them somehow. \$\endgroup\$ – Dennis Aug 28 '18 at 14:08
  • 1
    \$\begingroup\$ Exactly 120 distinct sums or at least 120 distinct sums? \$\endgroup\$ – Peter Taylor Aug 30 '18 at 10:12
  • 2
    \$\begingroup\$ "it would be preferable to word your challenge more like a challenge and less like a help request." – quote Dennis. \$\endgroup\$ – user202729 Aug 30 '18 at 13:39
  • \$\begingroup\$ The challenge can be trivially solved in linear time in the output (which is optimal time), because note that the largest face need to be at least 41 (otherwise 3 ≤ sum ≤ 120 and there can't be 120 values, assuming all values are positive integers), therefore for all s ≥ 41 just output 1 ... 41 and a bunch of other 1s to fill up the faces. Not interesting. \$\endgroup\$ – user202729 Aug 30 '18 at 13:46
  • \$\begingroup\$ @user202729 I don't think that works. You have 8 faces to work with, which is less than 41. \$\endgroup\$ – Nathan Merrill Aug 30 '18 at 20:46
  • \$\begingroup\$ @NathanMerrill No, you have s faces to work with. If s<41 just brute force it (O(1)). Otherwise use the algorithm above. \$\endgroup\$ – user202729 Aug 30 '18 at 23:54
  • \$\begingroup\$ @user202729 Right, for s>41, it's trivial. What is not trivial is less than 41, which I don't see the algorithm for. Which algorithm are you talking about? \$\endgroup\$ – Nathan Merrill Aug 31 '18 at 0:41
  • \$\begingroup\$ @NathanMerrill Note that the challenge requires smallest asymptotic complexity, not runtime. All (correct) algorithm which only operates on bounded input works in O(1), by the definition of "asymptotic". \$\endgroup\$ – user202729 Aug 31 '18 at 0:52
  • \$\begingroup\$ @user202729 True, but it is trivial to increase 120 as well, to provide a way for measuring the asymptotic nature of the algorithm. \$\endgroup\$ – Nathan Merrill Aug 31 '18 at 0:54
  • \$\begingroup\$ @NathanMerrill Then the challenge needs to be edited to explicitly specify that. \$\endgroup\$ – user202729 Aug 31 '18 at 1:01
  • \$\begingroup\$ @user202729 perhaps, but I could see an argument that the 120 is useful to provide a solid ground for the algorithm, as long as they indicate that it is arbitrary. \$\endgroup\$ – Nathan Merrill Aug 31 '18 at 1:03
  • \$\begingroup\$ 120: For s=8, d=3, 120 is the maximum number of distinct sums. I believe the formula is M=((s-1)+d)!/((s-1)!d!). Not sure how to write that well in a comment, but sCd with repetitions. \$\endgroup\$ – Quantum Mechanic Aug 31 '18 at 15:25
  • \$\begingroup\$ Big-Oh notation does not assume a fixed input. If the input is fixed, any algorithm can be said to be O(1), which is unhelpful. For example, f(a) = O(a^2). It's often harder to describe this with more than one variable, but it might be f(a,b) = O(max(a,b)^2). \$\endgroup\$ – Quantum Mechanic Aug 31 '18 at 16:01
  • \$\begingroup\$ @QuantumMechanic for scoring the algorithms, I think you could assume a constant d, but as a tie-breaker, include d. \$\endgroup\$ – Nathan Merrill Aug 31 '18 at 16:13
  • \$\begingroup\$ I think there's an implicit assumption that the smallest permitted value on the side of a die is 1, but that should be made explicit. \$\endgroup\$ – Peter Taylor Sep 5 '18 at 11:09
1
\$\begingroup\$

What is the simplest reversible circuit that computes conjugacy of transpositions?

,,

Motivation

Reversible computation refers to computation in which little or no information is deleted. Reversible computation a major component of quantum computation, and reversible computation is potentially many times more energy efficient than conventional computation. I want to know how easy it is to compute the conjugacy of transpositions reversibly?

Challenge

Let T5 be the set of all transpositions on the set {1,2,3,4,5}. Let * be the conjugacy operation on T5 defined by x * y=xyx^(-1) (here concatenation denotes the group operation). In other words, the underlying set of T5 consists of all 10 pairs (a,b) of distinct numbers from {1,2,3,4,5} and where we declare (a,b)=(b,a). The operation * is the unique operation on the underlying set that satisfies

  • (a,b) * (c,d)=(c,d),
  • (a,b) * (b,c)=(a,c),
  • (a,b) * (a,b)=(a,b)

whenever a,b,c,d are distinct.

What is the simplest n bit input reversible circuit C along with an injective function R:T5->{0,1}^n such that C(R(x),R(y))=(R(x),R(x*y)) for all x,y in T5?

The gate cost of a reversible circuit shall be the sum of the costs of every individual logic gate in the reversible circuit.

Here is the price chart per logic gate (see this link for a description of the logic gates) along with a description of the reversible gates.

Each SWAP gate (x,y)->(y,x) will have a cost of 0.

Each NOT gate x-> NOT x shall have a cost of 1.

Each CNOT gate (x,y)->(x,x XOR y) shall have a cost of 2.

Each Fredkin gate (x,y,z)->(x,(NOT x AND y) OR (x AND z),(x AND y) OR (NOT x AND z)) shall have a cost of 4 (the Fredkin gate can also be described as the reversible logic gate where (0,x,y)->(0,x,y) and (1,x,y)->(1,y,x)).

Each Toffoli gate (x,y,z)->(x,y,(x AND y) XOR z) shall have a cost of 5.

No other gates are allowed.

Observe that each reversible gate has the same number of inputs as it has outputs (this feature is required for all reversible gates).

The complexity of your circuit will be the product of the gate cost or your circuit with the number n which you choose. The goal of this challenge will be to minimize this measure of complexity.

Format

Complexity: This is your final score. The complexity is the product of the number n with your total gate cost.

Space: State the number n of bits that your circuit C acts on.

Total gate cost: State the sum of the costs of each of the individual gates in your circuit C.

NOT gate count: State the number of NOT gates.

CNOT gate count: State the number of CNOT gates.

Toffoli gate count: How many Toffoli gates are there?

Fredkin gate count: How many Fredkin gates are there?

Legend: Give a description of the function R. For example, you may write

(1,2)->0000,(1,3)->0001,(1,4)->0010,(1,5)->0011,(2,3)->0100, (2,4)->0101,(2,5)->0110,(3,4)->0111,(3,5)->1000,(4,5)->1001.

Gate list: Here list the gates in the circuit C from first to last. Each gate shall be written in the form [Gate type abbreviation,lines where the gates come from]. For this problem, we shall start with the 0th bit. The following list specifies the abbreviations for the type of gates.

T-Toffoli gate S-Swap gate C-CNOT gate F-Fredkin gate N-Not gate.

For example, [T,1,5,3] would denote a Toffoli gate acting on the 1st bit, the 5th bit, and the 3rd bit. For example, [T,2,4,6] produces the transformation 01101010->01101000 and [C,2,1] produces 011->001,010->010 and [N,3] produces 0101->0100. For example, one could write [S,7,3],[N,2],[T,1,2,3],[F,1,2,5],[C,7,5] for the gate list.

The gates act on the bit string from left to right. For example, the gate list [C,0,1],[C,1,0] will produce the transformation 01->11.

Sample answer

Complexity: 80

Space: 5

Total gate cost: 16

NOT gate count: 3

CNOT gate count: 2

Toffoli gate count: 1

Fredkin gate count: 1

Legend: (1,2)->00001,(1,3)->00011,(1,4)->00101,(1,5)->00110,(2,3)->01000,(2,4)->01011,(2,5)->01100,(3,4)->01110,(3,5)->10001,(4,5)->10011

Gate list: [N,1],[N,0],[N,4],[S,1,2],[S,2,3],[C,0,1],[C,2,3],[T,3,2,1],[F,4,3,2,1]

Sandbox

\$\endgroup\$
  • 1
    \$\begingroup\$ It would be helpful to define conjugacy, transposition and the group operation. If the challenge is to write a program that does these things then you should specify that along with desired input/output format and winning criterium (e.g. shortest code, fastest code, custom scoring, etc.) \$\endgroup\$ – dylnan Dec 18 '17 at 21:26
  • \$\begingroup\$ is x^(-1) the inverse of x on the group? \$\endgroup\$ – Sriotchilism O'Zaic Dec 18 '17 at 21:38
  • \$\begingroup\$ Yes. x^(-1) denotes the inverse of x in the group. For transpositions x, we have x^(-1)=x. \$\endgroup\$ – Joseph Van Name Dec 18 '17 at 21:46
  • \$\begingroup\$ It would be helpful if you format the code properly. \$\endgroup\$ – user202729 Dec 19 '17 at 1:22
  • 1
    \$\begingroup\$ "The operation * is the unique operation on the underlying set that satisfies (a,b) * (c,d)=(c,d),(a,b) * (b,c)=(a,c),(a,b) * (a,b) whenever a,b,c,d are distinct." I find that list hard to read with the whitespace as is, but is it incomplete? I think it's missing = (a,b) at the end. For readability, I suggest either using code markup separately for each identity or putting them in an unordered list. \$\endgroup\$ – Peter Taylor Dec 19 '17 at 8:48
  • \$\begingroup\$ I think the C on the right hand side of the condition is wrong. \$\endgroup\$ – Christian Sievers Dec 19 '17 at 21:39
  • 1
    \$\begingroup\$ After reading this a few more times, I find that I'm uncertain as to what branching is allowed. Can I use the same value as input to more than one gate, or is a line "used up" when it goes into a gate? Also, are constant 0 and 1 available, or do they have to be included as extra bits in the output of R? \$\endgroup\$ – Peter Taylor Dec 20 '17 at 11:10
  • \$\begingroup\$ Sorry for being away for a while. I am going to get back to editing this proposed challenge so that it will be up and ready as soon as possible. \$\endgroup\$ – Joseph Van Name Sep 8 '18 at 14:33
  • 1
    \$\begingroup\$ @PeterTaylor. Reversible circuits do not have any branching. Every reversible gate has the same number of input bits as it has output bits. I will clarify this in the post. \$\endgroup\$ – Joseph Van Name Sep 8 '18 at 14:39
1
\$\begingroup\$

Compile Brainbash to BF

Background

BF is an esolang known for it's terseness and small character set. The language operates on a tape of unsigned 8-bit integers, and with a pointer to modify certain values. This pointer starts at the first cell. BF has the following commands available to program with:

+       increment the current cell
-       decrement the current cell
>       move the pointer to the next cell on the right
<       move the pointer to the next cell on the left
.       output the current cell as a character
,       take a character of input
[       begin a loop while the current cell is not zero
]       end that loop

Brainbash is a language similar to BF, but it has two tapes. To deal with this, Brainbash has a "tape focus"; one tape at a time is being worked on. Each tape also has its own pointer. Thus, Brainbash has a few more commands in addition to BF's:

~       swap the tape focus
*       swap tapes and copy the pointer from the previous tape to the next one
{       if the current cell is not zero, execute the code until the next `}` that matches 
}       marks the end an if statement

(There are more commands, but they are not being considered for the purposes of this challenge.)

Challenge

Given a non-empty Brainbash program P, translate that program to BF. That is, output a program Q whose I/O behavior is identical to that of P.

This is a code-golf, so the shortest in program (in bytes) that successfully does this wins.

Specific rules

  • You may assume that each tape is infinite to the right starting at the origin.
  • You may assume that the input is a valid program which has matching { and } and [ and ].

Example Test Cases

(to be introduced)

\$\endgroup\$
  • 1
    \$\begingroup\$ Do the Brainbash tapes wrap, or are they infinite in each direction? Are the Brainfuck commands also Brainbash commands? \$\endgroup\$ – AdmBorkBork Sep 7 '18 at 20:21
  • \$\begingroup\$ What does it mean to translate? Only keep I/O behaviour the same or also some tape structure? \$\endgroup\$ – Jonathan Frech Sep 8 '18 at 9:14
  • \$\begingroup\$ @AdmBorkBork (1) You must support at least 30000 cells to the right of the origin for both tapes (2) Yes \$\endgroup\$ – Conor O'Brien Sep 8 '18 at 16:52
  • \$\begingroup\$ @JonathanFrech Keep I/O behaviour \$\endgroup\$ – Conor O'Brien Sep 8 '18 at 16:53
1
\$\begingroup\$

Make it rotationally-symmetric

(sandbox note: am I using the wrong terminology?)

Background

While looking at this challenge, I notice many some of the answers has 4-fold rotational symmetry. I think it would be convenient to have a program to automatically do it.

Challenge

  • Take input as a string, for which when separated by newlines, all line has equal length. (i.e., the input is rectangular)
  • The output is the smallest square with 4-fold rotational symmetry, where the top-left corner is equal to the rectangle.

Sample input/output

Input:
aba
bab
aba

Output:
aba
bab
aba

Input:
 begin write('left')end.// 
/e .dne)'thgir'(etirw nigeb

Output:
 begin write('left')end.// 
/e .dne)'thgir'(etirw nigeb
/g                        e
.i                       .g
dn                       di
n                        nn
ew                       e 
)r                       )w
'i                       'r
tt                       ti
fe                       ht
e(                       ge
l'                       i(
'r                       r'
(i                       'l
eg                       (e
th                       ef
it                       tt
r'                       i'
w)                       r)
 e                       we
nn                        n
id                       nd
g.                       i.
e                        g/
begin write('right')end. e/
 //.dne)'tfel'(etirw nigeb 

Input:
abc
cde

Output:
abcca
cdedb
ce ec
bdedc
accba

Winning criteria

.

\$\endgroup\$
  • \$\begingroup\$ Could input be a list of strings? \$\endgroup\$ – Kroppeb Sep 13 '18 at 19:39
  • \$\begingroup\$ Do the filler characters have to be spaces? \$\endgroup\$ – dylnan Sep 15 '18 at 0:16
  • \$\begingroup\$ Suggested test case: 'ab\naa' \$\endgroup\$ – dylnan Sep 15 '18 at 0:19
1
\$\begingroup\$

Mini Castle Wars

Note: This is very early draft, and I'll try to develop when I get some time to spare.


Inspired by a previous KOTH based on a card game (but not actually a card game).

Background

This challenge involves a simplified version of the card game Castle Wars.

Game rules

Gameplay

Just like many other card games, Castle Wars is a two-player turn-based game.

Each player starts with 30 units of castle, 5 units of fence, no shield, 2 workers, 8 bricks, 2 magicians, and 8 crystals. Each player is dealt (TBD, 5?) cards from his own deck at start.

Each resource has the following function:

  • Castle: Directly related to the winning condition (see below).
  • Fence: Fences can block the opponent's attack. If the attack would damage the castle by N units, the fence is damaged N units instead. If the fence is less than N units, it becomes zero and the remaining damage is dealt to the castle.
  • Shield: If a castle is shielded, it can nullify any amount of damage to the castle AND the fence, exactly once. Shield can't be stacked.
  • Workers: Each worker produces one brick every turn.
  • Magicians: Each magician produces one crystal every turn.
  • Bricks and Crystals: Every card spends some of these resources to take effect.

Each turn works as follows:

  1. He gets the resources produced by his own workers and magicians.
  2. The player draws a card from his own deck.
  3. He plays a card. If he has enough resources, the card takes effect immediately (including the resources spent). Otherwise, it has no effect whatsoever.
  4. The played card returns to the deck, and the deck is shuffled.

In order to compensate the first-player advantage, resource generation is skipped at the first turn of the game. (TBD)

Cards & deck

A deck consists of at least (TBD) cards, and may include at most (TBD) copies of the same card.

Here is the full list of cards.

  • (TBD, will reflect the actual cards in the game)

Winning condition

A player wins if the opponent's castle is destroyed (0 units or below), or his own castle grows to 100 units or higher. If 100 turns are passed without a player winning, the one with higher castle is declared the winner. Same castle height after 100 turns is a draw.

Tournament

Every bot will have (TBD, even number) matches with every other bot, alternating the first turn.

Controller

TBD. This will ideally be implemented in KOTH-Webplayer.

Submission guide

A submission will look like this:

Deck

'AAAAABBBBBCCDDEXYZ'

Bot

return hand[Math.random()*hand.length|0];

The Deck is a string literal that describes the list of cards your bot will use. The Bot is a snippet that will fit into the following function's body:

function play(hand, myResources, opResources, opPlayed, storage) {
    // function body here
}

The description of parameters:

  • hand is an Array of (TBD) cards in your bot's hand. Your bot's job is to choose a card to play.
  • myResources and opResources are two Objects that have the information of all the resources (the bot's and the opponent's, respectively). Available keys are castle, fence, worker, brick, magician, crystal, shield. (shield is a Boolean indicating whether the player's castle is shielded or not; others are simple numbers.)
  • opPlayed is the card played at the opponent's last turn.
  • storage is an Object you can freely use to store information between turns. It is initially empty ({}).

Meta

  • I originally planned to have a simplified version of the original Castle Wars, but on second thought, the rules are not that complicated and removing some resource types may break the balance of the game (as some interesting cards have to be revised). Would it be good to implement the full game instead?
\$\endgroup\$
  • \$\begingroup\$ Fantastic to see this brewing in the sandbox! Here are a couple pieces of criticism and some potential solutions: a) No tournament type is specified - I'm assuming it's round-robin. This should be added to the spec. a) Is there a need to compensate for the first-player advantage? Surely, a two-way round-robin would be fair enough, no? I'm not sure how large the first-player advantage is, though, so I could be wrong here. c) I've found that there's a handy way to handle persistent storage of things in JavaScript - closures. \$\endgroup\$ – Alion Sep 20 '18 at 9:30
  • \$\begingroup\$ cont. c) I would recommend that all future JS KOTHs required a function factory pattern from players. Here's an example of how that can be useful for entries. Here's how that looks without the closure pattern, and how it negatively affects entries. \$\endgroup\$ – Alion Sep 20 '18 at 9:49
  • \$\begingroup\$ cont. c) For this challenge, this could be additionally useful, since you require players to choose a deck for themselves. The bots could return a {deck, func} object during setup that way. \$\endgroup\$ – Alion Sep 20 '18 at 9:56
1
\$\begingroup\$

Prettify Pixiedust


So Pixiedust is a new esolang I've created. One of the primary points is that it should look like pixie dust—exactly the things that your programs should fix.

Input

The input will be a program written in Pixiedust. Since this is not a challenge to parse the language, it won't be in raw code, but a list of numbers and the strings separating them. The numbers can be taken as the number itself, or their representation in the program.

Randomizing the Literals

For each numeric literal, there are many ways to represent them:

  • Randomly pad the beginning with . characters. It should be an even distribution between padding it to 32 bits and padding it to the base length.
  • If the number is at the end of the line, then take an even split between including and excluding the terminating *.

Scattering

At this point, you should have the lines calculated—let's call this the half-pretty program. For each line of output:

  • Start with a line of pure spaces 4 times the length of the longest half-pretty line.
  • Randomly select spaces from it to replace with program characters. Every combination of spaces should have an equal chance.
  • Replace those spaces with the corresponding characters, without changing the order that they appear in.
  • (Optional) trim off trailing spaces.

Scoring

The winner will be the shortest answer in bytes. Additionally, there will be a 50-rep bounty for the first answer written in Pixiedust.


Examples will be coming once I finish the interpreter and make some submissions to other challenges in Pixiedust.

\$\endgroup\$
  • \$\begingroup\$ Since this is not a challenge to parse the language, I mean, it's not that hard. \$\endgroup\$ – RamenChef Sep 29 '18 at 0:20
1
\$\begingroup\$

Iteration Hierarchy

This is based on the m(n) map. mk takes in k functions and one natural input n, and iterates the first function n times onto the next argument, and then fills in the rest of the arguments.

\$m_1=f_0\mapsto n\mapsto f_0^n(n)\$

\$m_2=f_1\mapsto f_0\mapsto n\mapsto f_1^n(f_0)(n)\$

\$m_3=f_2\mapsto f_1\mapsto f_0\mapsto n\mapsto f_2^n(f_1)(f_0)(n)\$

etc. where \$f^n(x)=f(f(f(\dots f(x)\dots)))\$ with \$n\$ calls to \$f\$ (a.k.a. function iteration).

Note particularly that \$m_2(f_1)(f_0)(2)=f_1(f_1(f_0))(2)\ne f_1(f_1(f_0(2)))\$ i.e. it iterates the first argument over the second argument and then applies the remaining arguments afterwards.


Examples:

Let \$s(n)=n+1\$.

m1(s)(5)

m₁(s)(5)
= s(s(s(s(s(5)))))                                x5 iterations of s
= 10

m1(m1(s))(4)

m₁(m₁(s))(4)
= m₁(s)(m₁(s)(m₁(s)(m₁(s)(4))))                   x4 iterations of m₁(s)
= m₁(s)(m₁(s)(m₁(s)(s(s(s(s(4)))))))              x4 iterations of s
= m₁(s)(m₁(s)(m₁(s)(8)))
= m₁(s)(m₁(s)(s(s(s(s(s(s(s(s(8))))))))))         x8 iterations of s
= m₁(s)(m₁(s)(16))
= ...
= m₁(s)(32)
= ...
= 64

m2(m1)(s)(3)

m₂(m₁)(s)(3)
= m₁(m₁(m₁(s)))(3)                                x3 iterations of m₁
= m₁(m₁(s))(m₁(m₁(s))(m₁(m₁(s))(3)))              x3 iterations of m₁(m₁(s))
= m₁(m₁(s))(m₁(m₁(s))(m₁(s)(m₁(s)(m₁(s)(3)))))    x3 iterations of m₁(s)
= m₁(m₁(s))(m₁(m₁(s))(m₁(s)(m₁(s)(s(s(s(3)))))))  x3 iterations of s
= m₁(m₁(s))(m₁(m₁(s))(m₁(s)(m₁(s)(6))))
= ...
= m₁(m₁(s))(m₁(m₁(s))(24))
= m₁(m₁(s))(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(m₁(s)(24)))))))))))))))))))))))))
= ...
= m₁(m₁(s))(402653184)
= ...
= ???

m3(m2)(m1)(s)(2)

m₃(m₂)(m₁)(s)(2)
= m₂(m₂(m₁))(s)(2)                                x2 iterations of m₂
= m₂(m₁)(m₂(m₁)(s))(2)                            x2 iterations of m₂(m₁)
= m₁(m₁(m₂(m₁)(s)))(2)                            x2 iterations of m₁
= m₁(m₂(m₁)(s))(m₁(m₂(m₁)(s))(2))                 x2 iterations of m₁(m₂(m₁)(s))
= m₁(m₂(m₁)(s))(m₂(m₁)(s)(m₂(m₁)(s)(2)))          x2 iterations of m₂(m₁)(s)
= m₁(m₂(m₁)(s))(m₂(m₁)(s)(m₁(m₁(s))(2)))          x2 iterations of m₁
= m₁(m₂(m₁)(s))(m₂(m₁)(s)(m₁(s)(m₁(s)(2))))       x2 iterations of m₁(s)
= m₁(m₂(m₁)(s))(m₂(m₁)(s)(m₁(s)(s(s(2)))))        x2 iterations of s
= m₁(m₂(m₁)(s))(m₂(m₁)(s)(m₁(s)(4)))
= m₁(m₂(m₁)(s))(m₂(m₁)(s)(8))
= m₁(m₂(m₁)(s))(m₁(m₁(m₁(m₁(m₁(m₁(m₁(m₁(s))))))))(8))
= ...
= ???

Aside:

This hierarchy is closely related to the fast-growing hiearchy when using a base function of s.

In fact, the last example is already much larger than Graham's number, and \$m_n(m_{n-1})\dots(m_1)(s)(n)\approx f_{\varepsilon_0}(n)\$ in the fast-growing hierarchy.

Code Golf Challenge:

Write the shortest possible function subprogram for \$m_k\$. Code size is measured in bytes.

Here's an example program (Ruby, I can golf this down to about 140 bytes):

iterate=->f,n{->g{
    i=g
    n.times{i=f[i]}
    i}}

m=->k{
    x="->n{y=iterate[f#{k-1},n]; (0...#{k-1}).map{|l| y=eval(\"y[f\#{l}]\")}; y[n]}"
    (0...k).map{|l| x="->f#{l}{"+x+"}"}
    eval(x)}

NB: As noted above, the growth rate of \$m_n(m_{n-1})\dots(m_1)(s)(n)\$ is comparable to \$f_{\varepsilon_0}(n)\$. If this can be golfed far enough below 100 bytes, it could well place in the top 5 of the Largest Number Printable question.

\$\endgroup\$
1
\$\begingroup\$

Challenge

Max Sum String

Given an input string, return the max word based on the sum of each word's unicode characters.

Rules

  • The input should be seperated by whitespace
  • The value of each word is based on the sum of each character in the word's UTF-16 code
  • The output should be the word

Examples

Input: "a b c d e"
Output: "e"

Input: "this is a test"
Output: "test"

Input: "test Test"
Output: "test"

Input: "hello world"
Output: "world"

Input: "💀 👻 🤡 🦇 🕷️ 🍬 🎃"
Output: "🕷️"

I doubt it's optimal at all, but here's the code I came up with to accomplish this challenge:

let str = "hello world";
Object.keys(str.split(' ').map(w => {return {[w]: [...w].map(c => c.charCodeAt(0)).reduce((a, b) => a + b, 0)}}).reduce((a, b) => { return Object.values(a)[0] > Object.values(b)[0] ? a : b}))[0];
\$\endgroup\$
  • \$\begingroup\$ Will all words be unique, or can there be duplicated words? For example, is "testing testing this is a test" a valid input? I would advice to keep all words unique, but it's your choice. If duplicated words are possible, would this test case result in "testing", ["testing", "testing"], or either is allowed? \$\endgroup\$ – Kevin Cruijssen Oct 4 '18 at 12:50
  • 1
    \$\begingroup\$ Also, even if duplicated words aren't allowed, what if the sum of two words have equal values, and are the max? Do we output either of the possible words, both of them, or either of these options is allowed? (I would suggest allowing both, and add a test case like that. For example "àà as a test" resulting in ["àà", "test"].) Other than that it's a nice challenge, so +1 from me. Already prepared an 8-bytes solution for it. :) \$\endgroup\$ – Kevin Cruijssen Oct 4 '18 at 12:54
  • \$\begingroup\$ I thought it should print out the first word, that's an easy fix to my js code. Thank you for the feedback, I'll post it soon! \$\endgroup\$ – GammaGames Oct 5 '18 at 15:31
1
\$\begingroup\$

Converting a number from Zeckendorf Representation to Decimal

moved to main

\$\endgroup\$
  • \$\begingroup\$ Questions should try to be self-contained so that people don't have to go off-site, and so links don't end up being dead. \$\endgroup\$ – Jo King Oct 7 '18 at 7:37
1
\$\begingroup\$

Be there, for the square

\$\endgroup\$
  • \$\begingroup\$ Same idea, but extended to a cube: codegolf.stackexchange.com/q/92410/56433 \$\endgroup\$ – Laikoni Oct 6 '18 at 1:16
  • \$\begingroup\$ Good catch! I think that the cube challenge is different enough that the answers won't just be taken from there. My challenge skips a lot of the special cases, which could make for some optimization. \$\endgroup\$ – maxb Oct 6 '18 at 7:07
1
\$\begingroup\$

Ascii Table to UTF-8

When I write documentation, comments, etc. I love making ASCII tables. They usually end up looking pretty good, but I always feel that they could look even better - especially since UTF-8/Unicode includes the box drawing characters. However, these characters are very burdensome to use, requiring several key presses to insert. Your task? Write a program or a function that can automatically convert ASCII tables to the UTF-8/Unicode equivalent.

Challenge

Write a program, that given an ASCII table as an input string, outputs the table redrawn with the Unicode/UTF-8 box drawing characters. Specifically, the characters that are a part of the table should be translated as follows:

(Unicode)
- to ─ (\u2500)
| to │ (\u2502)
= to ═ (\u2550)

and + to one of:
   ┌ (\u250C), ┐ (\u2510), └ (\u2514), ┘ (\u2518),
   ├ (\u251C), ┤ (\u2524), ┬ (\u252C), ┴ (\u2534),
   ┼ (\u253C)
or, if '=' on either side:
   ╒ (\u2552), ╕ (\u2555), ╘ (\u2558), ╛ (\u255D),
   ╞ (\u255E), ╡ (\u2561), ╤ (\u2564), ╧ (\u2567),
   ╪ (\u256A)

Details

I/O:

  • Default I/O is allowed
  • You may take a path to a file instead of the table as a string.
  • You may output to a file and take the file name as an additional argument.
    • However, you may not modify the input file. (It should be retained for ease of future editing)

Input:

  • You may assume that every row of input has been padded to be the same length with .
  • You may not assume that the first character after a newline is a part of the table borders (as it may be whitespace).
  • Input is considered a valid table if all characters (that are a part of the table) -=| are connected to exactly two characters and + are connected to at least one character both horizontally and vertically.
  • Your program may not produce any errors with valid inputs.
  • If the input is not valid the behavior is undefined and you may produce any output.

Output:

  • Any of the characters -=|+ that are not a part of the table must be left as-is.
  • Similarly, any other characters must be left as-is.
  • A single leading and/or trailing newline is allowed.

Other:

  • Standard loopholes are forbidden, as per usual.
  • If your preferred language has a built-in that solves this problem, you may not use it.
    • This means programs, functions, subroutines or instructions that would be valid submissions for this challenge with no additions.

Connected characters:

A character is connected to another, if:

  • It is | and is directly above or below + or |;
  • It is - and is directly before or after + or -;
  • It is = and is directly before or after + or =;
  • It is + and is directly above or below | or +, or is directly before or after -, = or +.

A character is considered a part of the table, if it is connected to any character that is a part of the table. By definition, the first + in the input is a part of the table.

Examples

Examples available here as a copy-pastable version.

 Input:                    Output:
+------------------+      ┌──────────────────┐
|   Hello+World!   |      │   Hello+World!   │
+==================+      ╞══════════════════╡
| This is+my first |  ->  │ This is+my first │
|+-+ code|golf  +-+|      │+-+ code|golf  +-+│
|+-+chall|enge! +-+|      │+-+chall|enge! +-+│
+------------------+      └──────────────────┘

     +===+===+===+             ╒═══╤═══╤═══╕
     | 1 | 2 | 3 |             │ 1 │ 2 │ 3 │
 +---+===+===+===+         ┌───╪═══╪═══╪═══╡
 | 1 | 1 | 2 | 3 |         │ 1 │ 1 │ 2 │ 3 │
 +---+---+---+---+    ->   ├───┼───┼───┼───┤
 | 2 | 2 | 4 | 6 |         │ 2 │ 2 │ 4 │ 6 │
 +---+---+---+---+         ├───┼───┼───┼───┤
 |-3 |-3 |-6 |-9 |         │-3 │-3 │-6 │-9 │
 +===+---+---+---+         ╘═══╧───┴───┴───┘

      +-----+         ->      <Undefined>

      +-----+         ->      ┌─────┐
      +-----+                 └─────┘

+-----------------+
|  Hello, World!  |
| This is invalid |   ->      <Undefined>
|      input      |
 -----------------+

       ++++                      ┌┬┬┐
       ++++           ->         ├┼┼┤
       ++++                      └┴┴┘

       +--+
       ++++           ->      <Undefined>
       +--+

Finally...

This is , so the least amount of bytes wins. Happy golfing!

\$\endgroup\$
  • \$\begingroup\$ This is a solid first challenge, nice job. The test cases are good as well. 1. What should happen on the input + (all by itself?), or the input +---+? \$\endgroup\$ – Nathan Merrill Oct 8 '18 at 17:04
  • \$\begingroup\$ @NathanMerrill Good question. I'll clarify. \$\endgroup\$ – user77406 Oct 8 '18 at 18:02
1
\$\begingroup\$

One line keyboard

\$\endgroup\$
  • 1
    \$\begingroup\$ Some questions: What happened to the tab key? Why are there no upper-cased letters in the alternate section? I think it would be a bit more clear if you'd wrap the actual characters in `. OT: This challenge remind me a bit of this :) \$\endgroup\$ – ბიმო Oct 8 '18 at 16:20
  • \$\begingroup\$ Another thing: I can't think of a language/algorithm rn, but someone might struggle with the empty string and it doesn't really add much to the core of the challenge. You might want to loosen that requirement to only allow non-empty inputs, but it's your call and either way is fine. \$\endgroup\$ – ბიმო Oct 8 '18 at 16:24
  • \$\begingroup\$ @BMO I've excluded the tab key as it will never appear in the input (not in ascii range 32-126) and as far as I'm aware it can't be used to input other special characters. I didn't include the upper cased letters in the alternate section as they're always the same key as their lowercase counterpart (although am happy to edit if it makes it clearer). Finally, I wanted to wrap the characters in a backtick but was unsure how to escape it in the first line :) \$\endgroup\$ – Luke Stevens Oct 8 '18 at 16:25
  • 1
    \$\begingroup\$ Ah forgot about the printable range, makes sense. It wouldn't hurt to add them and would make it more complete, but it is not really essential to the challenge. I think using <code>...</code> is the easiest way or you can use double backticks. \$\endgroup\$ – ბიმო Oct 8 '18 at 16:32
  • \$\begingroup\$ Why does {} matters, as you can't access Shift key on that line anyway? \$\endgroup\$ – user202729 Oct 8 '18 at 16:39
  • \$\begingroup\$ @user202729 Originally I just typed out all the keys to leave it up to each person to work out what they could use, but thinking about it that seems unecessary so I'll change it to just characters \$\endgroup\$ – Luke Stevens Oct 8 '18 at 17:12
  • \$\begingroup\$ please delete this now that this has been posted. Thanks! :) \$\endgroup\$ – Giuseppe Oct 15 '18 at 17:33
1
\$\begingroup\$

Idolize Me! - JS idol simulation KotH

Introduction

There are quite a lot of ACG titles featuring idols in Japan. Inspired by different kinds of such games, I decided to make up my idol simulation game.

What is "Idolize Me!™"?

Idolize Me!™ (tentative) is based on an idol training facility featuring a monthly tournament, in which all idols compete for fame. Every idol has the following 4 kinds of attributes (or abilities):

  • Eloquence (How well you speak)
  • Singing (How well you sing)
  • Dance (How well you dance)
  • Performance (How well you act)

Also, every idol has the corresponding improvisation level (affects on-stage performance) and specialized skills. There are training courses to upgrade these abilities and skills, and idols can also "learn" from rivals during monthly tournaments to gain abilities and improvisation.

The tournament is a Swiss-system tournament, idols gain and lose fame during 1-on-1 performance battles, and gain fame according to their overall tournament results. Each battle consists of 3 rounds, selected from the 4 types of performances with different focusing attributes:

  • Stand-up comedy battle (Eloquence)
  • Duet battle (Singing)
  • Dance battle (Dance)
  • Drama battle (Performance)

Each idol can choose to ban one type he/she does not want to participate, and can choose to specify one type he/she want to participate. Other rounds will be selected randomly, and after 3 rounds, the idol who wins more rounds wins the battle. It is possible to end up with a draw, but this is very rare.

Every one starts with the same amount of fame. After 3 years of training and competitions, the most famous idol will become the Super Idol!

Algorithmic Explanation

  • Each idol starts with 2500 units of fame, 10000 units of ability to be allotted to the 4 attributes by yourself, and 20 units of improvisation and 10 units of skill per attribute.
  • The main loop consists of the following components, and will be run for 36 rounds (=3 years):
    • Training (4 rounds per round): Each idol will be given 100 units of ability and 5 units of improvisation. You can allot however you wish, but beware that improvisation caps at 50 units per attribute. After allotment you can learn some skills or to strengthen your abilities at the cost of losing some improvisation. Every unit of improvisation can be converted to 5 units of ability or 0.2 units of skill. Beware that skill also caps at 50 units per attribute.
    • Tournament: After 4 rounds of training there will be the tournament. The tournament will be a Swiss-system tournament, and consist of \$\lceil log_2(n+1) \rceil\$ rounds, where \$n\$ is the number of idols. Each round will be run in the following manner:
      1. Group the idols into a group of 2 according to their running rankings.
      2. For each group, each idol chooses one attribute from the 4 attributes, and discloses its corresponding ability.
      3. Then, being told the attributes and abilities, each idol decides one attribute to ban. Giving up the chance to ban is allowed.
      4. Next, being told the choice of ban, each idols decides one round to battle. They can still choose the banned choice, but the choice will be replaced by random rounds.
      5. Fill the remaining rounds with random rounds not being banned until there are 3 rounds.
      6. In each round, each idol can choose whether to use skill of the attribute of the round. There is only one chance of using skills per idol per a 3-round battle. Then the final score of each idol will be calculated with the following formula:

$$ score=\sum_{attr}{\Biggl\lfloor ability_{attr}\times multiplier_{type,attr}\times\left[0.7+r\times \left(0.3+\frac{improvisation_{attr}}{100}\right)\right]\times\left(1+\frac{skill_{attr}}{100}\right)\Biggr\rfloor} $$

Where \$ability_{attr}\$ is your ability, \$improvisation_{attr}\$ is your improvisation, \$skill_{attr}\$ is your skill, all of the attribute \$attr\$, and \$r\$ is a random number in the range\$[0, 1)\$, with a slightly larger probability near \$1\$. The value of \$multiplier_{type,attr}\$ is in the table below:

      type   | Stand-up comedy     Duet Battle  Dance Battle  Drama Battle
attr         | Battle (Eloquence)  (Singing)    (Dance)       (Performance)
-------------+-------------------------------------------------------------
Eloquence    | 1.5                 0.8          0.5           1.2
Singing      | 0.8                 1.5          1.2           0.5
Dance        | 0.5                 1.2          1.5           0.8
Performance  | 1.2                 0.5          0.8           1.5   
  • (contd)
    • (contd)
      1. The idol with higher score wins the round, and idol who wins more rounds wins the battle.
      2. Winner of the battle will be award 2 points, loser 0 points, and in the case of a draw, 1 point each.
      3. Winner gets extra 10 units of ability and 1 unit of improvisation. For each losing round, the defeated idol gets 20 units of ability and 2 unit of improvisation, and for each draw round, each idol gets 30 units of ability and 3 unit of improvisation, to be allotted at the same time (Beware again that improvisation caps at 50 units per attribute.) -- This is the core of so-called "learning from rivals".
      4. The delta fame is calculated as \$\lfloor10\times diff\times\frac{fame_{loser}}{fame_{winner}}\rfloor\$, where \$diff\$ is the difference of winning rounds in the battle. Winner gets this amount and loser loses this amount of fame.
      5. If the number of idols is odd, the idol who ranked the last will be consider a 0-battle win automatically, so fame, ability and improvisation are not affected.
      6. Sort the idols according to the following order, with the one at the top having the highest priority, all in descending order:
        1. Tournament points (TP)
        2. Number of battles won
        3. Battle difference (BD) (Number of rounds won - Number of rounds lost)
        4. Number of rounds won (BF)
        5. Score difference (PD) (Total score got - Total score lost)
        6. Total score got (PF)
        7. Drawing lots
    • After all rounds, fame will be awarded by the following formula:

$$ increase_{fame_{idol}}=\Biggl\lfloor\left[\left(\frac{n - rank + 1}{n}\right)^{1.5}\times 80+20\right]\times\frac{fame_{average}}{fame_{idol}}\Biggr\rfloor $$

Where \$n\$ is the number of idols.

Submission requirements:

Your bot must be a JS function with a name, prefably a human name (because the idol theme), distinct from other bots, that accepts an integer argument id (you must not change this argument name) and returns an object with 2 fields and 8 functions. The 2 fields are id and name (please don't change the id, line in the template). The 8 function are as follows:

  1. allot(type, amount): Allotment of amount units of type.

    • Arguments:
      • type: one of "ability" or "improvisation", the type to be allotted
      • amount: an integer, the amount to be allotted
    • Return values:
      • An object with 4 numbers named E, S, D and P, denoting your decision of the allotment of the 4 attributes. The 4 numbers must sum up to amount, otherwise your decision will be voided.
  2. review(ranking, battles): Your bot can review the battle results and adjust your plans.

    • Arguments:
      • ranking: an array of objects of the following entries, in ascending order of the bots' ranking, the running ranking during the tournament:
        • id: an integer, the ID of the bot
        • W: an integer, battle wins
        • D: an integer, battle draws
        • L: an integer, battle losses
        • BF: an integer, rounds won
        • BA: an integer, rounds lost
        • BD: an integer, BF - BA
        • PF: an integer, total score won by the bot
        • PA: an integer, total score won by opponent
        • PD: an integer, PF - PA
        • pts: an integer, tournament points
      • battles: an array of objects of the following entries, the details of all battles:
        • aID: an integer, the ID of idol A
        • aWin: an integer, rounds idol A won
        • aPtTotal: an integer, total score idol A got
        • bID: an integer, the ID of idol B. -1 stands for no opponent
        • bWin: an integer, rounds idol B won
        • bPtTotal: an integer, total score idol B got
        • result: an array of the following entries, the details of the sub-rounds of the battle:
          • attribute: one of "E", "S", "D" or "P", the attribute of the round
          • aTotal: an integer, the score of idol A
          • bTotal: an integer, the score of idol B
    • Return values:
      • None.
  3. learn(): Your bot can learn one type of skill at the cost of the improvisation of that attribute.

    • Arguments:
      • None.
    • Return values:
      • null, or an object of the following entries, the decision:
        • attribute: one of "E", "S", "D" or "P", the skill you want to learn
        • unit: a positive number, the amount you want to learn. You cannot learn more than your improvisation of that attribute allows.
  4. convert(): Your bot can strengthen one type of ability at the cost of the improvisation of that attribute.

    • Arguments:
      • None.
    • Return values:
      • null, or an object of the following entries, the decision:
        • attribute: one of "E", "S", "D" or "P", the ability you want to strengthen
        • unit: a positive number, the amount you want to strengthen. You cannot strengthen more than your improvisation of that attribute allows.
  5. disclose(rival): Disclose your attribute during battle.

    • Arguments:
      • rival: an integer, rival's ID
    • Return values:
      • one of "E", "S", "D" or "P", the attribute you want to disclose
  6. forbid(rival, attribute, value): Bans an attribute during battle.

    • Arguments:
      • rival: an integer, rival's ID
      • attribute: one of "E", "S", "D" or "P", the attribute rival discloses
      • value: an integer, the ability of that attribute rival discloses
    • Return values:
      • one of "E", "S", "D" or "P", the attribute you want to ban
  7. choose(attribute, value, forbidden): Chooses an attribute during battle.

    • Arguments:
      • attribute: one of "E", "S", "D" or "P", the attribute rival discloses
      • value: an integer, the ability of that attribute rival discloses
      • forbidden: one of "E", "S", "D" or "P", the attribute rival bans
    • Return values:
      • one of "E", "S", "D" or "P", the round you want to choose
  8. skill(attribute): Decides whether to use skill.

    • Arguments:
      • attribute: one of "E", "S", "D" or "P", the attribute of the round
    • Return values:
      • true or false, the decision whether to use skill of the attribute of the round.

enter image description here

Here is a template to use:

function YourIdolBot(id) {
    // Your local storage
    
    return {
        id, // Don't change this line
        name: "", // Your bot's name
        allot(type, amount) {
            // Your logic
            
            // Your return value
            return {
                E: 0,
                S: 0,
                D: 0,
                P: 0
            };
        },
        review(ranking, battles) {
            // Your logic
            
        },
        learn() {
            // Your logic
            
            // Your return value
            return {
                attribute: "",
                unit: 0
            };
        },
        convert() {
            // Your logic
            
            // Your return value
            return {
                attribute: "",
                unit: 0
            };
        },
        disclose(rival) {
            // Your logic
            
            // Your return value
            return "";
        },
        forbid(rival, attribute, value) {
            // Your logic
            
            // Your return value
            return "";
        },
        choose(attribute, value, forbidden) {
            // Your logic
            
            // Your return value
            return "";
        },
        skill(attribute) {
            // Your logic
            
            // Your return value
            return false;
        }
    }
}

Your submissions must not:

  • Corrupt the simulation;
  • Return values beyond requirements;
  • Call IdolizeMeAPI.query() with other bot's ID (see below);
  • Affect other bots' code;
  • Fetch external sources;
  • Define and use new global variables;
  • Has expletive inside the code (Beware of idols' image)

Violations will render the bot invalid and thus be disqualified and excluded from the simulation.

API

Idolize Me! provides an API that lets your idol bot query the current stats of its own. By calling IdolizeMeAPI.query(id) with your bot's ID. YOU MUST NOT CALL IdolizeMeAPI.query() WITH OTHER BOT'S ID. THIS WILL LEAD TO DISQUALIFICATION. This method returns an object with the following entries, which is the details of your bot:

  • id: an integer, your bot's id
  • name: a string, your bot's name
  • ability: an object with 4 numbers named E, S, D and P, your bot's ability of each attribute
  • improvisation: an object with 4 numbers named E, S, D and P, your bot's improvisation of each attribute
  • skill: an object with 4 numbers named E, S, D and P, your bot's skill of each attribute
  • fame: a number, your bot's fame

Test Area

Here is a snippet that allows test on the bots:

function log(msg) {
  $("#log").html($("#log").html() + msg + "\n\n");
}

function cls() {
  $("#log").html("");
}

function startIdolizeMeAPI(bots, seed, loopRounds, logBattles) {
	const ALLOT_LIMIT = {
		ability: Infinity,
		improvisation: 50,
		skill: 50
	};
	const MULTIPLIER = {
		E: {E: 1.5, S: 0.8, D: 0.5, P: 1.2},
		S: {E: 0.8, S: 1.5, D: 1.2, P: 0.5},
		D: {E: 0.5, S: 1.2, D: 1.5, P: 0.8},
		P: {E: 1.2, S: 0.5, D: 0.8, P: 1.5}
	};

	function checkAllot(idol, type, amount, add) {
		var values = idol.idol.allot(type, amount);
		var total = 0;
		for (var i of "ESDP")
			total += values[i];
		if (Math.abs(total - amount) < 1e-10) {
			if (add) {
				for (var i of "ESDP") {
					idol[type][i] += values[i];
					if (idol[type][i] > ALLOT_LIMIT[type])
						idol[type][i] = ALLOT_LIMIT[type];
				}
			}
			else {
				for (var i of "ESDP") {
					if (values[i] > ALLOT_LIMIT[type])
						values[i] = ALLOT_LIMIT[type];
				}
				return values;
			}
		}
		else if (!add)
			return {E: 0, S: 0, D: 0, P: 0};
	}
	var Random = (function(randomSeed) {
		function next() {
			return Math.random();
		}
		function nextInt(n) {
			return next() * n |0;
		}
		return {
			next,
			nextInt,
			pick: a => a[nextInt(a.length)],
			shuffle: function(a) {
				for (var l = a.length; l > 1;) {
					var o = nextInt(l--);
					[a[l], a[o]] = [a[o], a[l]];
				}
				return a;
			}
		};
	})(seed);

	var idols = bots.map(x => ({
		id: x.id,
		name: x.name,
		idol: x,
		ability: checkAllot({idol: x}, "ability", 10000, false),
		improvisation: {E: 20, S: 20, D: 20, P: 20},
		skill: {E: 10, S: 10, D: 10, P: 10},
		fame: 2500
	}));
	var numIdols = bots.length;

	function calcTotal(attr, idol, skill) {
		var total = 0;
		for (var i of "ESDP")
			total += idol.ability[i] * MULTIPLIER[attr][i] * (70 + Math.pow(Random.next(), 0.8) * (30 + idol.improvisation[i]) + skill * idol.skill[i]) / 100 |0;
		return total;
	}

	function battle(a, b) {
		var aDis = a.idol.disclose(b.id), bDis = b.idol.disclose(a.id), aSkill = false, bSkill = false, aWin = 0, bWin = 0, aAllot = 0, bAllot = 0;
		var aForbid = a.idol.forbid(b.id, bDis, b.ability[bDis]), bForbid = b.idol.forbid(a.id, aDis, a.ability[aDis]);
		
		var rounds = [Random.pick("ESDP"), a.idol.choose(bDis, b.ability[bDis], bForbid), b.idol.choose(aDis, a.ability[aDis], aForbid)].filter(x => x != aForbid && x != bForbid);
		while (rounds.length < 3) {
			var round = Random.pick("ESDP");
			if (round != aForbid && round != bForbid)
				rounds.push(round);
		}
		Random.shuffle(rounds);
		var result = rounds.map(function (x) {
			var aUseSkill = a.idol.skill(x), bUseSkill = b.idol.skill(x);
			var aTotal = calcTotal(x, a, !aSkill && aUseSkill), bTotal = calcTotal(x, b, !bSkill && bUseSkill);
			aSkill |= aUseSkill;
			bSkill |= bUseSkill;
			if (aTotal > bTotal) {
				aWin++;
				bAllot += 20 * aTotal / bTotal |0;
			}
			else if (bTotal > aTotal) {
				bWin++;
				aAllot += 20 * bTotal / aTotal |0;
			}
			else {
				aAllot += 30;
				bAllot += 30;
			}
			return {
				attribute: x, 
				aTotal, 
				bTotal
			};
		});
		if (aWin > bWin) {
			aAllot += 10;
			var deltaFame = 10 * Math.abs(aWin - bWin) * b.fame / a.fame |0;
			a.fame += deltaFame;
			b.fame -= deltaFame;
		}
		else if (bWin > aWin) {
			bAllot += 10;
			var deltaFame = 10 * Math.abs(aWin - bWin) * a.fame / b.fame |0;
			a.fame -= deltaFame;
			b.fame += deltaFame;
		}

		if (aAllot > 0) {
			checkAllot(b, "ability", aAllot, true);
			if (aAllot >= 10)
				checkAllot(b, "improvisation", aAllot / 10 |0, true);
		}
		if (bAllot > 0) {
			checkAllot(b, "ability", bAllot, true);
			if (bAllot >= 10)
				checkAllot(b, "improvisation", bAllot / 10 |0, true);
		}
		var aPtTotal = 0, bPtTotal = 0;
		for (var i of result) {
			aPtTotal += i.aTotal;
			bPtTotal += i.bTotal;
		}

		return {
			aID: a.id,
			bID: b.id,
			result, 
			aWin, 
			bWin,
			aPtTotal, 
			bPtTotal
		};
	}

	var totalBattleResult = {};
	idols.map(x => totalBattleResult[x.id] = {
		W: 0,
		D: 0,
		L: 0,
		BF: 0,
		BA: 0,
		BD: 0,
		PF: 0,
		PA: 0,
		PD: 0,
		pts: 0,
		rankings: []
	});

	function swissBattle() {
		var idolRanking = idols.map(x => ({
			idol: x,
			W: 0,
			D: 0,
			L: 0,
			BF: 0,
			BA: 0,
			BD: 0,
			PF: 0,
			PA: 0,
			PD: 0,
			pts: 0
		}));
		function sortRanking() {
			for (var idol of idolRanking)
				idol.lots = Random.next();
			idolRanking.sort((a, b) => b.pts - a.pts || b.W - a.W || b.BD - a.BD || b.BF - a.BF || b.PD - a.PD || b.PF - a.PF || b.lots - a.lots);
		}
		sortRanking();

		for (var i = numIdols; i > 0; i >>= 1) {
			var battles = [];
			for (var j = 0; j < numIdols - 1; j += 2) {
				var a = idolRanking[j], b = idolRanking[j + 1]
				var result = battle(a.idol, b.idol);
				battles.push(result);
				if (result.aWin > result.bWin) {
					a.W++;
					b.L++;
				}
				else if (result.bWin > result.aWin) {
					a.L++;
					b.W++;
				}
				else {
					a.D++;
					b.D++;
				}
				a.pts = a.W * 2 + a.D;
				b.pts = b.W * 2 + b.D;
				a.BF += result.aWin;
				a.BA += result.bWin;
				b.BF += result.bWin;
				b.BA += result.aWin;
				a.PF += result.aPtTotal;
				a.PA += result.bPtTotal;
				b.PF += result.bPtTotal;
				b.PA += result.aPtTotal;
				a.BD = a.BF - a.BA;
				b.BD = b.BF - b.BA;
				a.PD = a.PF - a.PA;
				b.PD = b.PF - b.PA;
			}
			if (numIdols % 2 == 1) {
				idolRanking[numIdols - 1].W++;
				idolRanking[numIdols - 1].pts += 2;
				battles.push({
					aID: idolRanking[numIdols - 1].idol.id, 
					bID: -1, 
					result: [], 
					aWin: 0, 
					bWin: 0
				});
			}
			sortRanking();
			var publicRanking = idolRanking.map(function(x) {
				var l = {};
				for (var i in x) {
					if (i == "idol")
						l.id = x.idol.id;
					else if (i != "lots")
						l[i] = x[i];
				}
				return l;
			});
			for (var idol of idols)
				idol.idol.review(publicRanking, battles);
			if (logBattles) {
        log("Battle Results:\n" + JSON.stringify(battles, null, 2));
        log("Ranking:\n" + JSON.stringify(publicRanking, null, 2));
      }
		}
		var averageFame = idols.reduce((a, b) => a + b.fame, 0) / numIdols;
		for (var i = 0; i < numIdols; i++)
			idolRanking[i].idol.fame += (Math.pow((numIdols - i) / numIdols, 1.5) * 80 + 20) * averageFame / idolRanking[i].idol.fame |0; 

		var r = 0;
		for (var p of idolRanking) {
			for (var q in p) {
				if (q != "idol" && q != "lots")
					totalBattleResult[p.idol.id][q] += p[q];
			}
			totalBattleResult[p.idol.id].rankings.push(++r);
		}
	}

	function showResult(round) {
		var temp = [...idols].sort((a, b) => b.fame - a.fame);
		var a =        " ID                 | Name                        | Fame  | Win  | Lose | Draw | BF   | BA   | BD   | Pts For   | Pts Aga.  | Pts Diff. | TP   | Tournament Rankings                                                                                         \n"
		      +        "--------------------+-----------------------------+-------+------+------+------+------+------+------+-----------+-----------+-----------+------+-" + "-".repeat(Math.max(20, loopRounds * 3));
		for (var i of temp) {
			a += `\n ${("" + i.id).padStart(18)} | ${i.name.padEnd(27) } | ` + ("" + i.fame).padStart(5);
			for (var j of ["W", "L", "D", "BF", "BA", "BD", "PF", "PA", "PD", "pts"])
				a += " | " + ("" + totalBattleResult[i.id][j]).padStart(j[0] == "P" ? 9 : 4);
			a += " | " + totalBattleResult[i.id].rankings.map(x => ("" + x).padStart(2)).join` `;
		}
		log("Round " + round + " results:\n" + a);
    return a;
	}

	function loop() {
		for (var i = 0; i < loopRounds; i++) {
			for (var j = 0; j < 4; j++) {
				for (var k of idols) {
					checkAllot(k, "ability", 100, true);
					checkAllot(k, "improvisation", 5, true);
					var convertPlan = k.idol.convert();
					if (convertPlan) {
						var {attribute, unit} = convertPlan;
						var converted = Math.min(unit, k.improvisation[attribute] * 5);
						k.improvisation[attribute] -= converted / 5;
						k.ability[attribute] += converted;
					}
					var learnPlan = k.idol.learn();
					if (learnPlan) {
						var {attribute, unit} = learnPlan;
						var learnt = Math.min(unit, k.improvisation[attribute] / 5);
						k.improvisation[attribute] -= learnt * 5;
						k.skill[attribute] += learnt;
						if (k.skill[attribute] > ALLOT_LIMIT.skill)
							k.skill[attribute] = ALLOT_LIMIT.skill;
					}
				}
			}
			swissBattle();
			showResult(i + 1);
		}
	}

	return {
		loop,
		query(id) {
			var idol = idols.filter(x => x.id == id)[0];
			if (idol) {
				var publicIdol = {};
				for (var i in idol) {
					if (i != "idol")
						publicIdol[i] = idol[i];
				}
				return publicIdol;
			}
			else 
				return null;
		},
		showResult
	};
}

var players = 0;
function addPlayer() {
  var id = Math.random() * Math.pow(2, 53);
  $("#players").append(`
    <div class="bot" id="bot-${id}">
      <textarea cols="100" rows="10"></textarea> ${++players > 2 ? `<input type="button" value="Delete this bot" onclick="deletePlayer(${id})">` : ""}
    </div>
  `);
}

function deletePlayer(id) {
  $("#bot-" + id).remove();
  players--;
}
/*
$("#run").on("click", function(e) {
  e.preventDefault();
  e.stopPropagation();
  e.target.checkValidity();
  console.log("test");
});*/
var IdolizeMeAPI;
$(document).on("submit", "form", function(e) {
  e.preventDefault();
  cls();
  var bots = [], submissions = {};
  $(".bot").each(function(s) {
    var code = $(this).find("textarea").val();
    var botFunctionName = /function (\w+) *\(id\) *{/.exec(code);
    if (botFunctionName) {
      botFunctionName = botFunctionName[1];
      code = code.replace(/function (\w+) *\(id\) *{/, `submissions["$1"] = function(id) {`);
      eval(code);
      bots.push(new submissions[botFunctionName](+$(this).attr("id").slice(4)));
    }
  });
  IdolizeMeAPI = startIdolizeMeAPI(bots, "whatever it is we don't use seeds at all", +$("#rounds").val(), $("#logbattle").prop("checked"));
  IdolizeMeAPI.loop();
  return false;
});

addPlayer();
addPlayer();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  Rounds: <input id="rounds" pattern="\d+" value="6" required/><br>
  Log battle results: <input type="checkbox" id="logbattle"><br>
  Player Bots:
  <div id="players">
  </div>
  <input type="button" value="Add a bot" onclick="addPlayer()"><br>
  <input id="run" type="submit" value="Run simulation">
</form>
<pre id="log">
</pre>

You may want to open the snippet in a new page.

Demo Bots

2 simple demo bots will be in the same contest with submitted bots, of exactly the same implementation, but with different names: One called Yamada Ransu (山田 乱數) and one called Sato Midare (佐藤 乱).

function TheTwoSimpleDemoBotsYouAreCompetingWith(id) {
    return {
        id: id,
        name: "???",
        allot(type, amount) {        
            return {
                E: amount/4,
                S: amount/4,
                D: amount/4,
                P: amount/4
            };
        },
        review(ranking, battles) {},
        learn() {
            return {
                attribute: "ESDP"[Math.random() * 4 |0],
                unit: Math.random() * 5 |0
            };
        },
        convert() {
            return null;
        },
        disclose(rival) {
            return "ESDP"[Math.random() * 4 |0];
        },
        forbid(rival, attribute, value) {
            return "ESDP"[Math.random() * 4 |0];
        },
        choose(attribute, value, forbidden) {
            return "ESDP"[Math.random() * 4 |0];
        },
        skill(attribute) {
            return Math.random() < 0.5;
        }
    }
}

Winning Criteria

Submission is open for 2 weeks from the posting day, until 15:00 GMT on the end day, or until there are more than 20 submissions, whichever is later. You are welcomed to submit multiple entries during the period. After the the submission period ends, the 36 rounds will be simulated within 3 days. After the 36 rounds, the bot with the highest fame wins, and the corresponding submission will be accepted as "best answer". The simulation result will be posted.

\$\endgroup\$
  • \$\begingroup\$ Will we have access to the controller? \$\endgroup\$ – Alion Oct 9 '18 at 9:06
  • \$\begingroup\$ @Alion If by "controller" you mean the function which runs the rounds, sorry but no, except the IdolizeMeAPI.query(id). However the data you'll need will be passed into your functions (e.g. the rankings and battle history). Please make good use of the review() function. You can't define global storage, but you can define local storage inside the function. I hope this may help you. \$\endgroup\$ – Shieru Asakoto Oct 9 '18 at 9:25
  • \$\begingroup\$ As a footnote: all 8 functions are called actively by the controller during the loop. Maybe I should add a diagram to explain this. \$\endgroup\$ – Shieru Asakoto Oct 9 '18 at 9:34
  • \$\begingroup\$ Sorry, that wasn't what I meant. I was wondering if a runner for the game will be available for testing our bots - to debug, improve, compare against others, etc. Sort of how one was provided in this or that challenge. \$\endgroup\$ – Alion Oct 9 '18 at 9:34
  • \$\begingroup\$ @Alion Oh I see. I didn't consider that when I was writing the KotH, but I think I'd like to make a test snippet simulating several rounds for a smaller group of players, if the post isn't too long yet. \$\endgroup\$ – Shieru Asakoto Oct 9 '18 at 10:13
  • \$\begingroup\$ BTW may I ask how long can my post be? I checked the markdown and it's now @14.4kB \$\endgroup\$ – Shieru Asakoto Oct 9 '18 at 10:15
  • \$\begingroup\$ IIRC, the post length is capped at 65536 characters. If you plan on providing a controller for players to use to test their bots, I would highly recommend Dave's JS KotH Framework. It takes a while to get used to, but it does quite a lot of work for you, without restricting your challenge too much. \$\endgroup\$ – Alion Oct 9 '18 at 11:12
  • \$\begingroup\$ @Alion Oh thanks, I'll go and have a look. And it seems there is still quite a bunch of vacancy, so I'll add the test drive into the sandbox first. \$\endgroup\$ – Shieru Asakoto Oct 9 '18 at 11:20
  • \$\begingroup\$ @Alion I've added the snippet to the post. \$\endgroup\$ – Shieru Asakoto Oct 10 '18 at 2:50
1
\$\begingroup\$

Posted: Is this number secretly Fibonacci?

\$\endgroup\$
1
\$\begingroup\$

Toy floating point coprocessor: ceil

Summary: implement the ceiling function for 16-bit IEEE 754 floating point numbers in logic gates, using as few gates as you can.

16-bit IEEE 754 floating point

For a more detailed description, see Wikipedia:Half-precision floating-point format.

The 16 bits are divided into three chunks: sign (1 bit), exponent (5 bits), mantissa (10 bits).

  • The sign is 0 for positive numbers and 1 for negative numbers.
  • The exponent is biased: interpret as an unsigned 5-bit number and subtract 15 to get the true exponent. Special cases are described below.
  • The mantissa is an unsigned 10-bit number with an implicit leading 11th bit which depends on the exponent.

If the exponent is 00000 (corresponding to -15), the number is subnormal. The implicit leading bit of the mantissa is 0, but there's a bonus factor of two, so the interpreted value is \$(-1)^{\textrm{sign}}\; 2^{-14}\; 0.\textrm{mantissa}\$, or (expanding the \$0.\textrm{mantissa}\$ binary notation) \$(-1)^{\textrm{sign}}\; 2^{-24}\; \textrm{mantissa}\$.

If the exponent is 11111 (corresponding to 16), the number is either infinite (if the mantissa is 0000000000) or a NaN.

For all other exponents, the implicit leading bit of the mantissa is 1, so the interpreted value is \$(-1)^{\textrm{sign}}\; 2^{\textrm{exponent}-15}\; 1.\textrm{mantissa}\$, expanded to \$(-1)^{\textrm{sign}}\; 2^{\textrm{exponent}-25}\; (2^{10} + \textrm{mantissa})\$

Ceiling function

The ceiling function maps real numbers to integers, rounding up. So if the input value is an integer, the output value is unchanged; if the input value is not an integer, the output value is the smallest integer greater than the input value.

Examples:

$$\begin{array}{c|c} x & \textrm{ceil}(x) \\ \hline -1 & -1 \\ -0.5 & 0 \\ 0 & 0 \\ 0.00001 & 1 \\ 1 & 1 \\ 1.8 & 2 \\ \end{array}$$

Corner cases

Given an infinity, the output must be the same infinity.

Given a NaN, the output must be a NaN, but it can be any NaN.

IEEE 754 floating point systems have signed zeroes. Given a zero, the output must be the same zero.

Gates and scoring

You must implement a logic gate with 16 inputs and 16 outputs. You may use any two-input logic gates and you may mix different types of logic gates. We idealise the gates: don't worry about things like fan-out limitations or propagation delays. The score is the number of gates, and the fewer the better. If you choose to explain your design by giving code which uses bitwise operation on integers, be sure to document clearly how many bits are being processed by each operation.

Test cases

TODO, but will cover both infinities, both signed zeroes, positive and negative subnormals, positive and negative integer values, positive and negative non-integer values, and a NaN.

\$\endgroup\$
  • \$\begingroup\$ I assume 2-to-1 gate, or 2-to-any? \$\endgroup\$ – l4m2 Nov 16 '18 at 15:21
1
\$\begingroup\$

Minimize your standard deviation


The standard deviation of a collection of numbers is calculated in the following manner:

  1. Find the arithmetic mean of the collection.
  2. Find the difference of each item from the mean.
  3. Square each difference and sum them.
  4. Divide by the number of items in the collection minus 1.
  5. Take the square root.

Or, expressed mathematically:

$$ s = \sqrt{ \frac{ \sum^N_{i=1} (x_i - \bar x)^2 }{N - 1} }, $$

where \$N\$ is the number of items, \$x_i\$ is the \$i\$th item, and \$\bar x\$ is the arithmetic mean.

Challenge

Your challenge is to write a program or function in your language of choice that, given an array of bytes, calculates the standard deviation of the array. The catch: the standard deviation of the bytes in your code will be added to your score.

Rules

  • Input may be in any reasonable format (e.g. numbers separated by newlines or commas, an actual array or buffer, etc.)
  • You may assume that the items in the input are all integers \$0 \le n < 256\$.
  • You may assume that there are at least two integers in the input.
  • The output or return value must be the standard deviation of the array as calculated above, accurate to at least 2 decimal places (i.e. \$ \pm 0.005 \$)

Test cases

(test cases to come)

Scoring

The score of your code is its length in bytes, plus the standard deviation of its bytes (i.e. \$N + s\$). The code with the lowest score in each language wins.

(If you somehow find a language with a 1-byte built-in that fulfills the challenge, your score will just be 1. In the impossible case of a 0-byte built-in, your score will be \$0 + \frac{0}{-1} = 0\$.)

Sandbox questions

  • Is this too similar to the vanilla standard deviation challenge?
  • For non-golfing languages that primarily use ASCII, the standard deviation will likely be much lower than the byte count, leading to golfing the code being significantly more important than reducing \$s\$. How could this best be combated? \$\sqrt N + s\$? \$N + s^2\$? (where \$N\$ is the length of the code) Obviously I wouldn't want to just use \$s\$, as you could just append one byte (e.g. ; in many languages) over and over to lower it arbitrarily.
\$\endgroup\$
  • \$\begingroup\$ Standard deviation was my enemy in algebra. \$\endgroup\$ – MilkyWay90 Nov 11 '18 at 1:19
  • \$\begingroup\$ It seems difficult to create a scoring that penalizes appending redundant bytes and that the shortest solution wouldn't always win. \$\endgroup\$ – lirtosiast Nov 20 '18 at 1:48
1
\$\begingroup\$

Calculate your Icy Score

\$\endgroup\$
1
\$\begingroup\$

Classify arity of verbs inside trains in J

Related: Clearly parenthesize APL trains

Background

J is an APL-family language. While it inherits the basic train syntax from APL (take a look at the linked challenge above), J is more versatile with the introduction of [:, & and @ among many others. But the problem is, the more features a tacit expression has, the harder it is to read and understand what it does. Even worse, most of the built-in verbs have both monadic and dyadic usage, and some of them have two completely different meanings! So let's build a helper to classify the arity of verbs.

Notations

  • # is a monadic verb.
  • + is a dyadic verb.
  • [ is a special symbol called "cap" which can appear at specific positions inside a train.
  • @ and & are conjunctions, which take two verbs on both sides and form a single verb.
  • x and y are left and right arguments to a given train, respectively. If x is missing, the train is called monadically (with one argument y); otherwise, dyadically (with both arguments).

Basics

  • In a train of verbs, the last 3 verbs are recursively grouped.
  • Conjunctions bind from left to right.

Rules

Monadic
(# + #) y   =>  (# y) + (# y)
(+ #) y     =>  y + (# y)
([ # #) y   =>  # (# y)
(+ # + #) y =>  (+ (# + #)) y
(# + # + # + #) y => (# + (# + (# + #))) y
(# + [ # # + #) y => (# + ([ # (# + #))) y

Dyadic
x (+ + +) y   =>  (x + y) + (x + y)
x (+ #) y     =>  x + (# y)
x ([ # +) y   =>  # (x + y)
x (+ # + #) y =>  x (+ (# + #)) y    <= the 3-group is run monadically
x (+ + + + + + +) y => x (+ + (+ + (+ + +))) y
x (+ + [ # + + +) y => x (+ + ([ # (+ + +))) y

Conjunction &
(#&#) y   => # (# y)
x (+&#) y => (# x) + (# y)

Conjunction @
(#@#) y   => # (# y)
x (#@+) y => # (x + y)

How to determine arity of each verb

   (?  (? ?&?@?    ?) ?) y
=> (# d(? ?&?@?    ?) #) y    monadic 3-train: # + #
=> (#  (+ d?&?@?   +) #) y    dyadic 3-train:  + + +
=> (#  (+ d(?&?)@? +) #) y    conjunction binds from left; arity is determined from right
=> (#  (+ m(?&?)@+ +) #) y    dyadic `@`:  #@+
=> (#  (+  (#&#)@+ +) #) y    monadic `&`: #&#

Challenge

Given an expression that represents the structure of a J train, determine the arity of every verb in the expression.

Input & output

TBD

Test cases

TBD

Scoring & winning criterion

Standard rules apply. The shortest valid program or function in each language wins.

\$\endgroup\$
1
\$\begingroup\$

How fast can I Flood-It?

There's a one-player game called Flood-It, in which the player must flood the whole board with one color within a certain number of moves.

  • The board is a two-dimensional square grid of size n.
  • At the start, each square in the grid is one of k colors.
  • A move consists of selecting a color, and doing a 4-connected flood fill with that color starting in the top left corner.

For example, selecting Red on this size-3 board with 4 colors:

GGE
RGB
RDE

causes the board to change to this—now the two already-red squares are connected to the top left:

RRE
RRB
RDE

After the further moves DBE, all squares are colored Emerald, and the game has been won in an optimal 4 moves.

Challenge

Given two integers n and k, output the number of moves required to win the game of Flood-It with those parameters, in the worst case over all possible arrangements of colors.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .