Factorio is a ridiculously addictive game in which, having crash-landed on an alien planet, you start mining ore and building machines until you can build a rocket and leave. Amongst the items you can build are various components of logic circuits. Long story short, you can write programs with them.
I'm trying to build a smart train system (i.e., one which uses circuit logic to determine when/where a train is needed and send it there), and that involves a timer. I wanted to make a nice display for that timer. Specifically, I want to display the digits of the minutes and seconds with lights, like on a calculator.
Step 1 is to make a clock. For my test clock, I set an Arithmetic Combinator to calculate T (for time, or tick) plus 1, and output the new value of T. The output is then fed into a Decider combinator. The Decider outputs the input value of T as long as T does not equal 300, and is linked back into the Arithmetic Combinator.
This means T will count upwards for 10 seconds of real time, and then the Decider Combinator will send '0' instead of 300 and the count will start over. To see how many actual seconds have passed, the output of the Arithmetic combinator is fed into a second Arithmetic Combinator which divides T by 30 and outputs S (for 'seconds').
The 'tick rate' of Factorio is 60 per second. In other words, if you fed that first Combinator directly into itself, T would increase by 60 per second. But, I've fed my count through two combinators. Half the ticks are going into having the Decider Combinator check if we've met the limit or not. With this system, T only actually increases by 30 per second, hence 300 recorded ticks equalling 10 seconds.
(The alternative is to put T=1 on a Constant combinator, and feed that into the Decider. Attach the output back to the Constant Combinator, creating a loop. Have the Decider output the input value of T as long as T does not equal whatever you want to count up to, and then divide the output by 60 to see the value in seconds. This kind of clock will start counting at 1 instead of 0, which is very unlikely to matter).
Once you have a clock, it's time to work on the display. With a 3x5 light display, there are three options for how to do the
numbers, based on whether you put '1' on the left, in the middle, or on
the right.
I started building this with '1' on the right because, tbh, it did not occur to me to do anything else. On reflection, 1 in the middle has a lot to recommend it, and might be simpler. On the other hand, I already figured out most of 1-on-the right, so I'm sticking with it.
Lights can only be enabed or disabled by a single condition. That condition can be "if anything is equal to/less than/more than" a variable or a constant, but it can't be an 'And' or an 'Or' condition. So, I need to use more combinators to turn my S signal into whatever it is I want the lights to respond to. I want to use as few combinators as possible to do this.
I did quite a bit of experimenting with modulo, but the easiest way I found - which I think Dosh Doddington also relies on in this video - is by multiplying.
You will need the following combination of combinators:
For testing, you can also use a Constant Combinator with S set to whatever digit you want to see in place of the clock. You can also attach the LEDs to the input of another Arithmetic or Decider combinator. If you hover over it, it will display the inputs the LEDs are receiving.
The basic logic was to find values that, when multiplied by S, would have the same values for all the numbers I wanted a specific light to turn off for, but with that value not appearing for any other number. I could then set the light to turn off if everything did not equal that value. In human-speak, that's equivalent to if anything = x.
I used the above settings for each light.
Always On
The Decider Combinator is what lets the always-on lights work. When S is 0, it emits the colour at input value, so there are never zero inputs. This also means the colour is continuous; if you use a different symbol, the lights will be uncoloured when S is 0. If you want to use a different colour, remember to change it in both the Constant and the Decider.
Off for 1
S*S=1 when S=1, so this light is enabled only when S does not equal 1.
Off for 2
SxS=4 when S=2, so this light is enabled only when S does not equal 4.
Off for 0, 1, 7
The colour is set to 70, so, when S=0, a value of 70 is emitted. Since we're multiplying S by everything, 70 blue is also emitted at S=1. Now we need something that equals 70 when S=7. That's the White 10 is for. At S=10, White = 70 and this light goes off.
Off for 1, 4, 7
1400 Iron Ore is emitted at 1, 4x350 Iron Plates are emitted when S=4, and 7x200 Steel are emitted when S=7. This light is only enabled as long as nothing = 1400, so it switches off at 1, 4, and 7.
I initially tried 140, but 2x70 Blue appears when S=2, so this light was turning off for 2 as well, which we don't want. I just multiplied everything by 10 to stop them overlapping.
Off for 1, 7
Copper is at 490, so S*Copper=490 when S=1. S*Blue=490 when S=7.
Off for 1, 4
S*S=16 whenS=4. Fish is set to 16, so S*Fish=16 when S=1.
Off for 5, 6
Water is set to 20, so S*Water=120 when S=60. Oil is set to 24, so S*Oil=120 when S=5.
Off for 1, 2, 3, 7
Various power poles at 12, 24, 48, and 84 = 84 when S is 1, 2, 3, or 7.
Off for 1, 3, 4, 5, 7, 9
I used the letter symbols for 3780, 1260, 945, 540, and 420, which create 3780 when S is 1, 3, 4, 5, 7 and 9.
I picked 3780 because that's when you get when you multiple 1, 3, 4, 5, 7 and 9 together, and whatever number you use needs to be divisible by all of those.
Blueprint String
Attach the clock/counter to the Constant with green wire.
Once you have seconds, you can use %60 to get how many seconds through the minute you are, and then use /10 and %10 to get the tens/units of that number. If you're counting over a minute, divide your total secons by 60, and use /10 and %10 on that number to gets 10 and units. You can then line up the digits and attach them in the right order.
0eNrdmVuO2zYUhrci8Kkt5IEu1M1AAxTpS5+bS9FmYNASbRGQSIGixjEGXkB2kbVlJaGk8YiWzZhWnDHSF8OUyZ88H8+Foh/BsmhwxQkVYP4IMlynnFSCMArm4A8hUJpbW9ZwK2UNFdYvGyJy6wHJMbXlzJJfLcEskWPrNaO1QLLHa1YuCUWCcavri6w1x5jKBsd3H+gH+teqFbQ2bWc5OM0RXeNOI2VFOxNbda2CrHNR2/sORFiMWksmJQ/mQzTrHvyJU5JhfgdsQFL5I5j/9whqsqaoaA0T2wpLi4jApexBUdm26hIVxaxAZQV2chjN8Ecwd3f22YGIS9NKLEg6S5/tVTS83b0NMBVEENyvpGtsF7Qpl5jLSU6twQYVq0nP/hFImRl0wrvABlv51Y/kVzmDtE1wViyWOEcPRM4qu6aEpw0RC/lb9jx+RXgtFkeGPBAuGvlkWEDXY4YfMN+KnNA16Gfp8MqVhm2rrBDvbJyDL58+tz2aGi/aDePSPsEb3A+iOG3nr9sJ3faD40y1n2QtHPug7e/udzvl2Z6RZ8ooeilGf4/QXJuMOyITasj4pmSClyKD6CnfcUaAXl0XT6TBAycEF7xJcEXOtV0oGDGKNYyCCcF1G0YwuTokeBRnh23X1VALJ1ALbkIthj86bQcaRtGE5HQbRq53dc/yDcMvngAJ/vwZPBrhGQei62l4JRNSuncbp4LO1b3KdcacdGcm15mQof4/oBLTRO66Ezj5N+HkR/EPPyVIB9Nw8iYkKv8lD+FXr3OxcaxNOYZ7P38ST46T9uhB+8r4ZE1/ctAAhGdeqM8keFdDchAbYNZTPa3GrcYFYYzSvB3HKix59/cov8lerBFVIy7V2Wm2pbtTOSoTwZmNaLOhDTxdlTHdtuHdYe9j5zZNSaJuFwAZ4b1JTwF8vIkrUgjMNdc4OmjtXVbv+83+9eqbtzqropGWDubwJsMzRgpFw4PKrY6BxgbJZavjhzX4BjdLfSbBhaTDZTBUrFANiofFQAOxEmekKbVq0HtWCwzUlmStlfLiZ6nQxMpmKf2m2/9Bwx2WE5loCIyLWVVI3ge4B96xgQrhjB6J+MEgkpiKMK5K9KebvfM5J0V0XrzJycFyXEXJ5HYyZag4vTeuZzCco81sRepcXUE4SPhGK6hk+hsh6V7k9yrwIiJvDrxWkQkuknmryARQkQkvknmnpphAQRNdJPNekUlgMMjEF8n8cxBCoWJVcpHOv2oAdGfOfdpzurJhXobgcdU5WUeG25Ssv7w/V0aC87X/SekKhV9/fvp9QjkfKlO1XXSUFyvOygWhUubpBPa9kL9R2uG4tJ88497bfRzPlT+FbCDfS+puG7zYhVHiRXEch4lMJbuvONbs/g==