In the game Factorio, you transport items around the map using transport belts.
Transport belts are 1x1 tiles, can go in any cardinal direction, and have 2 parallel lanes.
You can also use splitters to split a single belt into 2 belts, a splitter is 2x1 tiles and can receive input from either (or both) of its rear sides, and splits output evenly between both of its front sides. If one side is blocked, items will only be output to the other side.
Finally, you can use underground belts. These have an entrance and an exit, both 1x1 tiles, which must be directly facing each other, with no more than 8 tiles between them.
As we will be outputting in ASCII art, we'll use
>^<v to represent regular transport belts, with the arrow pointing in the direction of the belt.
As belts have 2 lanes, we'll represent each tile with a 2x2 chunk of ASCII art.
For example a simple belt would look like this:
Corners are simple, if a belt intersects another belt at a right angle, it creates a corner.
Would operate like this:
However may be represented as either, for simplicity.
However, there is a caveat to this corner functionality. If there is another belt that affects the direction of the corner piece, a corner is not formed.
In this case, the center belt remains straight. All items coming from the left belt will be output onto the left lane of the center belt, whilst all items coming from the right belt will be output onto the right lane of the center belt.
In this case, as the "corner piece" is not the start of a belt, it does not form a corner, and all items coming from the left belt will be output to the left lane of the center belt.
Splitters are an important part of belt systems.
A splitter is 2 tiles wide, and so will be 2x4 in ASCII art.
We will represent a splitter using the following symbols:
The straight line is the input side, whilst the arrows are the output side.
A splitter will attempt to evenly balance items it receives between it's 2 outputs. A splitter cannot accept any input from its sides, only its back.
In this example, the input belt is split between 2 belts, one continuing to the right, but a tile down, the other going up
As the belt going up meets the criteria to form a corner, it does so, and lanes are preserved.
A splitter can receive inputs from both of its input sides simultaneously, the input lane is preserved in the output (For example an item received on the left lane of whichever input belt will be placed on the left lane of whichever output belt)
Each individual item received by the splitter will alternate which output belt it is given to, regardless of where the input is pulled from.
For example, given this setup:
If item 1 is received from the left belt, and is outputted to the right side. The next item will be output to the left side, regardless of which belt it was received from.
Again, lanes are preserved, so if Item 1 is received from the left lane of the left belt, it will be output to the left lane of the right belt.
The exception, of course, is with a setup like such:
In this instance, the downward facing belt at the top prevents the right output from forming a corner, meaning regardless of which lane the splitter attempts to output to on the right, it will be placed on the bottom lane of the right belt.
Splitters always output their first item to their left.
Underground belts are vital for intertwining your belts.
We will represent them with the following 2x2 ASCII art tiles:
The arrows represent the input or output side (depending on the direction of the arrow), while the curve represents where the belt goes underground.
If an Underground entrance (tile with an input, rather than an output, ie arrows pointing towards the curve) does not have a corresponding exit, any items input to it will simply stop at the entrance.
However if an Underground exit does not have a corresponding entrance, items can still be side-loaded onto the exit (see below).
An entrance is connected to an exit by having the curves facing eachother within 8 tiles, in a straight line.
For example: (dots used to more easily highlight empty tiles)
>).. .. .. .. (>
>) .. .. .. ..(>
These 2 are connected. There may also be any other tiles in the gap between an entrance and exit, like such:
As there are still 8 tiles between these, they are connected.
However it's important to note that Underground belts use naive connection, meaning this setup causes problems:
>).. >) .. (>
>) ..>).. ..(>
A B C
In this case I've labelled the entrances and exit. The issue here is that B is the closer entrance that is a valid connection to C, and so A is left without an exit (Each entrance can only have 1 exit, and each exit can only have 1 entrance)
The same of course applies with exits:
>).. (> .. (>
>) ..(>.. ..(>
A B C
In this example, A and B connect, and as there is no free Entrance for C, it remains disconnected.
Unlike splitters, Underground belts support input from the side. This is useful, as they will only pull from 1 lane
>).. (>>> D
>) ..(>>> C
As underground belts cannot form corners, this creates a 1-lane sideload.
The left lane from the belt in the bottom left is loaded onto the right lane of the underground belt, meaning the output belt to the right will have only items from the left lane (Labelled A) of the input, on only its right lane (Labelled C).
The right lane of the input belt (Labelled B) becomes blocked, as the curved section of an underground belt cannot accept any input, and the left lane of the output belt (Labelled D) remains empty, provided there isn't another belt also loading items elsewhere.
This mechanic allows you to split individual lanes from your belts and perform more precise balancing.
Backlogs and Blocking
If a belt becomes blocked, its items will stop moving. This can cause problems if not done properly.
If a Splitter's output is blocked, the splitter will output all of its items to its other output. This is lane specific, so if the right lane of a splitter's right output is blocked, any input it receives on the right lane will be output to the right lane of the left belt.
If items reach the end of a belt, they will stop, creating a backlog.
If a belt hits the side of a splitter, it will stop, creating a backlog.
If a lane hits the curved half of an underground belt (entrance or exit) it will stop, creating a backlog.
If a belt hits the curved side of an underground belt, it will stop, creating a backlog.
The game includes 3 different belt tiers, however for our purposes, we will only use the highest tier.
Each lane of a belt can transport 20 items per second. This means a belt using both lanes can transport 40 items per second.
Due to this, it is possible to create a backlog by overloading a belt.
Assuming both side input belts are full and transporting their maximum of 40 items per second, the center belt will be receiving 80 items per second, which is too much.
In practice what this means is that the bottom lane of both input belts will continue moving at max throughput, while the top lanes will stop completely, only moving when the bottom lane dips below 20 items per second, creating a gap for an item from the top lane to squeeze in.
Now that you (hopefully) understand the basics of belts, let's get to the challenge!
Your code should, given 2 positive integers; an input
i and an output
o, create a layout for a belt balancer that will evenly distribute
i input belts among
o output belts. In this case, evenly means all
i*2 lanes must be split evenly among all
You can assume both inputs will always be lower than 17 and greater than 0
The orientation of your layout does not matter, provided it has the correct number of inputs, the correct number of outputs, correctly evenly balances all lanes, and all inputs are outputs are at the edges of the layout
All inputs must begin with a 2x2 tile of
is, like so:
With arrows pointing in the direction the tile is outputting items to
All outputs must terminate with a 2x2 tile of
os, like so:
With arrows pointing in the direction the tile is receiving items from
These special I/O tiles can be thought of unique straight belts.
An input tile cannot receive any input, and will output maximum belt throughput (20 items per second per lane) in the direction of the arrows
An output tile cannot give any output, and will consume maximum belt throughput (20 items per second per lane) from input given directly to the arrows (side-loading not supported)
Your program's score is in 2 parts:
n is your primary score, and is the number of input permutations your program outputs a valid, balanced layout for.
The maximum possible
n score is 256, as both
o can be any integer between 1 and 16, making
16^2 possible inputs, which is 256
s is used as a tiebreaker, and is the sum of the total area (in "game" tiles) of each of your program's valid outputs, where the area is calculated as: `(charwidth / 2) * (charheight / 2)
In the event that 2 solutions reach a tie on both the
s scores, most likely by reaching the same solutions for all possible input pairs, tie breaker is time of posting, with the earlier posted answer winning.
Note these examples may not be the optimal layout for the given inputs in terms of area, but are all correctly balanced
area: (6 / 2) * (14 / 2) = 3 * 7 = 21
area: (10 / 2) * (16 / 2) = 5 * 8 = 40
- This challenge is too complex, isn't it?
- Is the scoring okay?
- Are belts explained well enough?
- Did I miss any edge cases?