J, 126 124 121 119 116 115 113 105 116 115 112 characters
'|'s":(' 's[:,.(_6[\' || (__)'){~(,-.))&.>,.(|:@(1,.<&5);((i.5)</5|]))".,.1!:1[1[(s=:[,.~,.)9!:7'\=/<=>/=\|='
Takes input from the keyboard. Example:
'|'s":(' 's[:,.(_6[\' || (__)'){~(,-.))&.>,.(|:@(1,.<&5);((i.5)</5|]))".,.1!:1[1[(s=:[,.~,.)9!:7'\=/<=>/=\|='
6302715408
|\==============================================================/|
|| (__) (__) (__) (__) (__) (__) (__) (__) (__) (__) ||
|| || (__) (__) (__) || (__) || (__) (__) || ||
|| || || || || || || || || || || ||
|| (__) || || || (__) || (__) || || (__) ||
|<==============================================================>|
|| (__) (__) || (__) (__) (__) || (__) || (__) ||
|| || (__) || (__) (__) || || (__) || (__) ||
|| || (__) || || || || || (__) || (__) ||
|| || || || || || || || (__) || || ||
|| || || || || || || || || || || ||
|| || || (__) || || || (__) || (__) || ||
|| (__) || (__) || || (__) (__) || (__) || ||
|| (__) || (__) (__) (__) (__) (__) || (__) || ||
|| (__) (__) (__) (__) (__) (__) (__) || (__) (__) ||
|| (__) (__) (__) (__) (__) (__) (__) (__) (__) (__) ||
|/==============================================================\|
The main trick here is the abuse of J's boxing by redefining the characters it uses. It uses a global parameter - 9!:7
- to do this. There may be room for further golfing, but to be honest I was just glad to get something working that should compensate for my last attempt at this question.
Fits in a tweet with enough characters left to say 'Gaz made this' :-).
Edit: 3 characters of savings are due to borrowing the 2 6$' || (__)'
from Jesse Millikan's answer.
Further edit: Lost 11 characters adding extra spaces at either side that I hadn't noticed were not present.
Explanation:
The code is in three main sections:
1) Setup
[(s=:[,.~,.)9!:7'\=/<=>/=\|='
This is itself in two parts.
9!:7'\=/<=>/=\|='
redefines the characters that J will use to display boxes. J's boxing normally looks like this:
2 2$<"0[1 2 3 4
┌─┬─┐
│1│2│
├─┼─┤
│3│4│
└─┴─┘
but after redefining it looks like this:
2 2$<"0[1 2 3 4
\===/
|1|2|
<===>
|3|4|
/===\
(s=:[,.~,.)
defines a verb I'm going to be using a couple of times later. This turns out to be the best place to declare it. It takes a character on the left and an array of characters on the right and sandwiches the array between the character. For example:
3 5$'abcdefghijklmno'
abcde
fghij
klmno
'-' s 3 5$'abcdefghijklmno'
-abcde-
-fghij-
-klmno-
The final [
just serves to separate the setup from the next part.
2) Input and Representation
,.(|:@(1,.<&5);((i.5)</5|]))".,.1!:1[1
".,.1!:1[1
takes the input from the keyboard and separates it into individual digits:
".,.1!:1[1
314159
3 1 4 1 5 9
((i.5)</5|])
creates a zeros and ones representation of the bottom part of the abacus:
((i.5)</5|]) 3 1 4 1 5 9
1 1 1 1 0 1
1 0 1 0 0 1
1 0 1 0 0 1
0 0 1 0 0 1
0 0 0 0 0 0
|:@(1,.<&5)
creates a zeroes and ones representation of the top part of the abacus:
|:@(1,.<&5) 3 1 4 1 5 9
1 1 1 1 1 1
1 1 1 1 0 0
These two parts are boxed together using ;
:
(|:@(1,.<&5);((i.5)</5|])) 3 1 4 1 5 9
\=======================/
|1 1 1 1 1 1|1 1 1 1 0 1|
|1 1 1 1 0 0|1 0 1 0 0 1|
| |1 0 1 0 0 1|
| |0 0 1 0 0 1|
| |0 0 0 0 0 0|
/=======================\
Then the boxes are placed one on top of the other to form the basis of the abacus, giving:
,.(|:@(1,.<&5);((i.5)</5|]))".,.1!:1[1
314159
\===========/
|1 1 1 1 1 1|
|1 1 1 1 0 0|
<===========>
|1 1 1 1 0 1|
|1 0 1 0 0 1|
|1 0 1 0 0 1|
|0 0 1 0 0 1|
|0 0 0 0 0 0|
/===========\
3) Output
'|'s":(' 's[:,.(_6[\' || (__)'){~(,-.))&.>
&.>
means that what follows will operate on both boxes in turn.
(,-.)
this is a hook which will negate the input and then add it to the end of the original:
2 5$1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
(,-.) 2 5$1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
0 1 0 1 0
0 1 0 1 0
This is really part of the representation, but for golfing purposes it's better to have it in this section. Applied to the previous input:
(,-.)&.>,.(|:@(1,.<&5);((i.5)</5|]))".,.1!:1[1
314159
\===========/
|1 1 1 1 1 1|
|1 1 1 1 0 0|
|0 0 0 0 0 0|
|0 0 0 0 1 1|
<===========>
|1 1 1 1 0 1|
|1 0 1 0 0 1|
|1 0 1 0 0 1|
|0 0 1 0 0 1|
|0 0 0 0 0 0|
|0 0 0 0 1 0|
|0 1 0 1 1 0|
|0 1 0 1 1 0|
|1 1 0 1 1 0|
|1 1 1 1 1 1|
/===========\
[:,.(_6[\' || (__)'){~
The zeroes and ones are now used to select a string to represent a bead or the absence of one:
([:,.(_6[\' || (__)'){~(,-.))&.>,.(|:@(1,.<&5);((i.5)</5|]))".,.1!:1[1
314159
\====================================/
| (__) (__) (__) (__) (__) (__) |
| (__) (__) (__) (__) || || |
| || || || || || || |
| || || || || (__) (__) |
<====================================>
| (__) (__) (__) (__) || (__) |
| (__) || (__) || || (__) |
| (__) || (__) || || (__) |
| || || (__) || || (__) |
| || || || || || || |
| || || || || (__) || |
| || (__) || (__) (__) || |
| || (__) || (__) (__) || |
| (__) (__) || (__) (__) || |
| (__) (__) (__) (__) (__) (__) |
/====================================\
But now, as Howard pointed out to me, there is one space short on either side of the beads. So we use the predefined s
verb to sandwich the contents of each box between two columns of spaces:
(' 's[:,.(_6[\' || (__)'){~(,-.))&.>,.(|:@(1,.<&5);((i.5)</5|]))".,.1!:1[1
314159
\======================================/
| (__) (__) (__) (__) (__) (__) |
| (__) (__) (__) (__) || || |
| || || || || || || |
| || || || || (__) (__) |
<======================================>
| (__) (__) (__) (__) || (__) |
| (__) || (__) || || (__) |
| (__) || (__) || || (__) |
| || || (__) || || (__) |
| || || || || || || |
| || || || || (__) || |
| || (__) || (__) (__) || |
| || (__) || (__) (__) || |
| (__) (__) || (__) (__) || |
| (__) (__) (__) (__) (__) (__) |
/======================================\
Having done that, all that's left is to convert this into a string using ":
so that we can sandwich it between two columns of |
:
'|'s":(' 's[:,.(_6[\' || (__)'){~(,-.))&.>,.(|:@(1,.<&5);((i.5)</5|]))".,.1!:1[1
314159
|\======================================/|
|| (__) (__) (__) (__) (__) (__) ||
|| (__) (__) (__) (__) || || ||
|| || || || || || || ||
|| || || || || (__) (__) ||
|<======================================>|
|| (__) (__) (__) (__) || (__) ||
|| (__) || (__) || || (__) ||
|| (__) || (__) || || (__) ||
|| || || (__) || || (__) ||
|| || || || || || || ||
|| || || || || (__) || ||
|| || (__) || (__) (__) || ||
|| || (__) || (__) (__) || ||
|| (__) (__) || (__) (__) || ||
|| (__) (__) (__) (__) (__) (__) ||
|/======================================\|