The Saltine Challenge
JavaScript (E6) 249 259 289 304 345
Not so confident about the string compression.
Found a good compression for the strings. The simple 1 cracker case seems difficult to manage. There may be a better way...
F=n=>{
for(B=",|4.,|1.2,|1.4.4.1|,|5,|4.4.4|, 9|5, 87 ,|87|".replace(/\d/g,c=>' _'[c>4|0][R='repeat'](-~c)).split(','),
O=(c,b=0,a=0)=>console.log(' '[R](y)+B[a]+B[b][R](x)+B[c]),
r=x=y=0,
O(7);
O(3,2),
!(z=++r>2)|x;)
x+=(v=r<n)-z,O(v+5,1,z*4),y+=z*7;
O(8)
}
Ungolfed more or less
That is the basic code, before I started golfing. It's not exactly the same and works only for n > 2
F=n=>{
O=t=>console.log(t)
r=0
x=0
y=0
O(' _________________')
O(' '.repeat(y)+'| . '.repeat(x)+'| . . . |')
while (++r<n)
{
x++;
if (r>2)
{
x--;
O(' '.repeat(y)+'|______'+'| .'.repeat(x)+' __________|______')
y+=7;
O(' '.repeat(y)+'| . '.repeat(x)+'| . . |')
}
else
{
O(' '.repeat(y)+'| .'.repeat(x)+' __________|______')
O(' '.repeat(y)+'| . '.repeat(x)+'| . . . |')
}
}
while(x--)
{
O(' '.repeat(y)+'|______'+'| .'.repeat(x)+'| . . . |')
y+=7;
O(' '.repeat(y)+'| . '.repeat(x)+'| . . |')
}
O(' '.repeat(y)+'|_________________|')
}
Test In FireFox/FireBug console
F(4)
Output
_________________
| . . . |
| . __________|______
| . | . . . |
| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . . |
| . | . . . |
|______| . . |
| . . . |
|_________________|
Python, 252 241 characters
s="eJxTiIeDGgiloBBRo6CgpwACcLIGJKaAKlxDmbp4dFADAL+oIFI=".decode('base64').decode('zip').split('X')
N=input()
R=range
G=map(list,[' '*(7*N+12)]*(2*N+5))
for n in R(N):
for y in R(7):G[2*n+y][7*n:]=s[y]
G[0][11]='_'
for g in G:print''.join(g)
Thanks to FryAmTheEggman and Vincent for snipping off 11 characters.
A preponderance of crackers:
$ echo 17 | python saltines.py
_________________
| . . . |
| . __________|______
| . | . . . |
| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . __________|______
| . | . | . . . |
|______| .| . . |
| . | . . . |
|______| . . |
| . . . |
|_________________|
This code seems really inefficient, but other answers will tell. It just copies and pastes the saltine cracker into an array at the right spot, accounts for the bottom-most cracker being 1-character off, then prints it all.
I can get it down to 230 characters if I use an external file (202 code + 38 file size + 1 file name).
Perl 189
Stealing some string compression ideas from choroba, I got it down to:
echo 4 | perl -E 's/\d/($&<8?$":_)x$&/ge for@l=("|2.5.5.2|"," 98","|5.5.5|","|98|",7)[102020344=~/./g];map{say for@l[0,1];$l[$_]=substr($l[$_+2],0,7).$l[$_]for 0..6;substr$l[0],-7,1,"|"}2..<>;say for@l[0..6]'
For easier viewing in your browser:
s/\d/($&<8?$":_)x$&/ge for@l=
("|2.5.5.2|"," 98","|5.5.5|","|98|",7)[102020344=~/./g];map{
say for@l[0,1];
$l[$_]=substr($l[$_+2],0,7).$l[$_]for 0..6;
substr$l[0],-7,1,"|"
}2..<>;say for@l[0..6]
For context, my best before that:
Perl 207
$u='_'x11;s/:/ . /g,s/.(.)/$&$1/g,$_.=$/for@l=("|:: . |"," $u","| :: |","|$u|",$"x5)[102020344=~/./g];map{print@l[0,1];$l[$_]=substr($l[$_+2],0,7).$l[$_]for 0..6;substr$l[0],-8,1,'|'}2..pop;print@l[0..6]
Adding newlines and indentation for ease of reading in your browser:
$u="_"x11;
s/:/ . /g,s/.(.)/$&$1/g,$_.=$/for@l=
("|:: . |"," $u","| :: |","|$u|",$"x5)[102020344=~/./g];
map{
print@l[0,1];
$l[$_]=substr($l[$_+2],0,7).$l[$_]for 0..6;
substr$l[0],-8,1,"|"
}2..pop;
print@l[0..6]
You can replace "pop" with "<>" to take the count from STDIN instead of as a command-line parameter and get to 206 bytes. Going to STDERR would drop it to 204 bytes.
If I could enable the 'say' feature without a byte penalty, then I could get to 202.
$u="_"x11;s/:/ . /g,s/.(.)/$&$1/g for@l=("|:: . |"," $u","| :: |","|$u|",$"x5)[102020344=~/./g];map{say for@l[0,1];$l[$_]=substr($l[$_+2],0,7).$l[$_]for 0..6;substr$l[0],-7,1,"|"}2..<>;say for@l[0..6]
invoked as:
echo 4 | perl -E '$u="_"x11;s/:/ . /g,s/.(.)/$&$1/g for@l=("|:: . |"," $u","| :: |","|$u|",$"x5)[102020344=~/./g];map{say for@l[0,1];$l[$_]=substr($l[$_+2],0,7).$l[$_]for 0..6;substr$l[0],-7,1,"|"}2..<>;say for@l[0..6]'