19
\$\begingroup\$


Picture of me drafting this challenge with my advanced drawing skills.

Background

The Stickman wars happened long ago, when Earth's dominant species was made of nothing but sticks. Historians regret the fact that there were no painters or cameras back then, we could use some pictures of that war in today's history books. That's where your coding powers become useful. Stickmen are very easily drawed and Historians managed to find some data about how many stickmen fought the wars¹. Now it's up to you to recreate an image of the moment right before the war began!

Here are the brave stickmen involved in the war:

  O  /
|/|\/
| |
 / \  Swordsman

 O A
/|\|
 | |
/ \| Spearman

   . 
 .' *.
 ' O *  
' \|/ .
.  |  *
'./ \*. Mage

 O
/|\
 |
/ \ Villager

 O
/|\
/ \ Infant

Input

Receive via stdin or equivalent a representation of every stickman who appeared on each side of the battlefield. For example, if two Swordmen fought on the right side and two spearmen on the left side, your input can be {Sword: 2}, {Spear: 2}, [2,0,0,0,0], [0,2,0,0,0] or a "WW", "SS".

Output

A representation of every brave stickmen in a battle field, according to the rules below. It can be shown on stdout or saved to a file, whatever rocks your boat.

Rules

  1. On the left side will be every stickmen of the first array/string/object your program received.
  2. Those stickmen must look exactly like the ones shown before on this question.
  3. The order of the left side army must be Infants Villagers Mages Swordsmen Spearmen.
  4. The right side army will behave just the same, but with the characters and the order mirrored.
  5. Each stickman will be separated by 1 space.
  6. Each class will be separated by 3 spaces.
  7. The armies will be separated by 8 spaces.
  8. Since stickmen don't fly, you must draw the ground using hyphen-minuses -.
  9. The ground must end on the same column the last stickman of the right army ends.

Example

Let's assume my program expects two arrays with length 5 and each value in the array represents, in order, Infants Villagers Mages Swordsmen Spearmen.

Input: [1,1,2,3,1] [0,0,1,1,1]

               .       .                                                           . 
             .' *.   .' *.                                                       .* '.
       O     ' O *   ' O *      O  /   O  /   O  /    O A        A O   \  O      * O ' 
 O    /|\   ' \|/ . ' \|/ .   |/|\/  |/|\/  |/|\/    /|\|        |/|\   \/|\|   . \|/ '
/|\    |    .  |  * .  |  *   | |    | |    | |       | |        | |      | |   *  |  .
/ \   / \   './ \*. './ \*.    / \    / \    / \     / \|        |/ \    / \    .*/ \'.
---------------------------------------------------------------------------------------

Final Considerations

Please note that standard loopholes apply and that the mage is completely asymmetrical just because.

The result of most upvoted answer will be the "cover image" of this challenge. The shortest answer by the end of the month (08/31/2014) will be selected as the winner.

This is , so the shortest code, in bytes, wins.


¹Citation needed

\$\endgroup\$
  • 7
    \$\begingroup\$ "the mage is completely asymmetrical just because" ... twitch... you just had to, didn't you? :P \$\endgroup\$ – Doorknob Aug 9 '14 at 12:15
  • 4
    \$\begingroup\$ @Doorknob ¯\ _(ツ)_/¯ \$\endgroup\$ – William Barbosa Aug 9 '14 at 12:26
  • \$\begingroup\$ Is ok a function with 2 array arguments or you require input parsing from a string? \$\endgroup\$ – edc65 Aug 9 '14 at 15:58
  • \$\begingroup\$ TIL about overscores. Can unicode-challenged languages use dashes instead, please? \$\endgroup\$ – John Dvorak Aug 9 '14 at 16:07
  • 1
    \$\begingroup\$ There's a column missing between the villager and the mage. Also would a representation like IVMMWWWS SWM be within the limit of "anything that helps you"? \$\endgroup\$ – Martin Ender Aug 9 '14 at 17:33
7
+50
\$\begingroup\$

JavaScript (E6) 336 344 356 369 424 478 522 570

Edit 6 Last edit was buggy. Bug fix and shortened. That's all I hope.

Edit 5 Finally found a way to get rid of multiply by 23 - bothered me from start. Plus another change to the input (@William shout when it's too much). Now the function expects one array parameter, containing 2 subarrays. Without this change it's 349 - still an improvement

Edit 4 Shaved some more bytes and a little change to input format. With the new input format a missing class is represented as an empty array element. So D([1,,2,3,1],[,3,1,1,2]) instead of D([1,0,2,3,1],[0,3,1,1,2]). I think it still obeys the rules.

Edit 3 Golfed more. No changes to the algorithm, but abusing a lot of array.map and local functions to avoid for loops.

Edit 2 String compression, the right way ...

Edit Added string compression, a lot of work and not much gained. Now the mirror stickmen are generated from a template, not stored.

Made a few tries, first running. To be golfed. NB Kolmogorow-business still to be tackled.

Test In FireFox console. Change 'return' with Add 'alert(...)' to have an output statement (albeit not useful at all)

console.log(D([[1,,2,3,1],[,3,1,1,2]]))

Output

         .       .                                                                 .                 
       .' *.   .' *.                                                             .* '.               
       ' O *   ' O *      O  /   O  /   O  /    O A        A O  A O    \  O      * O '     O   O   O 
 O    ' \|/ . ' \|/ .   |/|\/  |/|\/  |/|\/    /|\|        |/|\ |/|\    \/|\|   . \|/ '   /|\ /|\ /|\
/|\   .  |  * .  |  *   | |    | |    | |       | |        | |  | |       | |   *  |  .    |   |   | 
/ \   './ \*. './ \*.    / \    / \    / \     / \|        |/ \ |/ \     / \    .*/ \.'   / \ / \ / \
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Golfed Code

D=a=>
  (J=v=>v.join(''))((l=[r=n=' ',3,6,13,19,23]).map(_=>f=(F=f=>J(a[f].map((c,q)=>
  ("9.299.' *.87O2' O *3O21 O A O 1|0' 0|1 .|1|01 1|0|1|0 | .2|2*| |4| |1 01 0'.1 0*. 1 021 0|"[R='replace'](/[2-9]/g,x=>n.repeat(x))
   .slice(l[q]-r,l[q+1]-r)[R](/\d/g,x=>'\\/'[x^f])+n).repeat(c)+n+n
  ))+n)(0)+J([...F(1)].reverse(r-=23))+'\n'))+f[R](/./g,'¯')

Code (edit 2)

D=(a,b)=>{
  F=(s,f)=>(s=s[R](/\d/g,x=>'/\\'[x^f]),f?s:[...s].reverse().join('')),
  v="9.299.' *.87O2' O *3O21 O A O 1|0' 0|1 .|1|01 1|0|1|0 | .2|2*| |4| |1 01 0'.1 0*. 1 021 0|"
    [R='replace'](/\d/g,x=>x>1?' '.repeat(x):x),
  l=[0,3,6,13,19,23];
  for(o='',r=0;v[r];r+=23,f=F(z,1)+'  '+F(w,0),o+=f+'\n',f=f[R](/./g,'¯'))
    for(z=w=p='';p<10;++p)
      if(c=(p<5?a:b)[q=p%5])x=(v.slice(r+l[q],r+l[q+1])+' ').repeat(c)+'  ',p<5?z+=x:w+=x
  return o+f
}

Ungolfed code (1st version)

D=(a,b)=>{
  v="         .                .                    .' *.            .* '.               O  ' O *   O  / O A * O ' \\  O  A O  O /|\\' \\|/ .|/|\\/ /|\\|. \\|/ ' \\/|\\||/|\\/|\\ | .  |  *| |    | |*  |  .   | || | / \\/ \\'./ \\*. / \\  / \\|.*/ \\'.  / \\ |/ \\"
  l=[0,3,6,13,19,23,30,36,40]
  o=''
  for(r=0;r<6;++r)
  {
    z=w=''
    for(p=0;p<10;p++)
    {
      c=a[p]||b[p-5];
      if (c)
      {
        q = p<7 ? p%5 : p-2
        x = (v.slice(r*40+l[q],r*40+l[q+1])+' ').repeat(c)
        if (p<5) 
          z+=x+'  ';
        else 
          w=x+'  '+w
      }
    }
    f = z + '     ' + w
    o += f + '\n'
    f = '¯'.repeat(f.length-3)
  }
  return o+f
}
\$\endgroup\$
4
\$\begingroup\$

Python 362 353

Edit: Removing one for-loop and using the exec statement saved 9 bytes

z,x,t,j=" ",input(),str.replace,0
w=0,3,6,13,19,23
a=9*z+"."+20*z+".' *."+15*z+"o  ' o *   o  a o A o a|b' b|a .|a|ba a|b|a|b | .  |  *| |    | |a ba b'.a b*. a b  a b|"
exec"b=''\nfor c in 0,1:b+=z*8*c+t(t('   '.join([z.join([a[w[k]+j:w[k+1]+j]]*v)for k,v in enumerate(x[c])if v])[::1-2*c],'a','\/'[c<1]),'b','\/'[c])\nprint b;j+=23;"*6
print'-'*len(b)

Input:

[0,0,2,1,1],[1,0,2,1,2]

Output:

   .       .                                                   .       .         
 .' *.   .' *.                                               .* '.   .* '.       
 ' o *   ' o *      o  /    o A        A o  A o    \  o      * o '   * o '       
' \|/ . ' \|/ .   |/|\/    /|\|        |/|\ |/|\    \/|\|   . \|/ ' . \|/ '    o 
.  |  * .  |  *   | |       | |        | |  | |       | |   *  |  . *  |  .   /|\
'./ \*. './ \*.    / \     / \|        |/ \ |/ \     / \    .*/ \.' .*/ \.'   / \
---------------------------------------------------------------------------------
\$\endgroup\$
  • \$\begingroup\$ Noticed you use lowercase Os. \$\endgroup\$ – phord Aug 19 '14 at 17:08
3
\$\begingroup\$

C, 418 414

Example input:

stickwar.exe IVMMWWWS SWM

Example output:


               .       .                                                            .   
             .' *.   .' *.                                                        .* '. 
       O     ' O *   ' O *      O  /   O  /   O  /    O A        A O    \  O      * O ' 
 O    /|\   ' \|/ . ' \|/ .   |/|\/  |/|\/  |/|\/    /|\|        |/|\    \/|\|   . \|/ '
/|\    |    .  |  * .  |  *   | |    | |    | |       | |        | |       | |   *  |  .
/ \   / \   './ \*. './ \*.    / \    / \    / \     / \|        |/ \     / \    .*/ \'.
----------------------------------------------------------------------------------------

Golfed code (linebreaks are only for readability; it should be one long line of code):

char d[8][999],*s,*a;p,f,t,x,y,c,l;main(o,g)char**g;{for(memset(d,32,6993);o-=
2,a=*++g;p+=3)for(;f=*a;f^*++a?p+=2:0){t=f%27%5;l=t*3%12%5+4;p+=l&o;y=6;for(s=
"(A(21;\0(A2:B(212;F\08A*B*0210KP\0-70A47/RT-A20G=CD?5D7_\0(A:(21;"+"V3'? "[t]
-32;c=*s++;)c&8?x=0*--y:0,x+=c/16-2,c^=o-1&&!(c&6),d[y][p+o*x]="/\\|O*'A."[c&7
];t^3|~o||(s=d[5]+p,*s--=46,*s=39);p+=l&-o;}memset(d[6],45,p-=4);for(y=0;*(s=d
[y++]);s[p]=0,puts(s));}

Maximal width of the battlefield is 999 (I could save 2 chars by limiting it to 99). I used a control structure of 1 byte per output character (non-space), drawing the figures from the bottom up.

  • 1 bit for y-coordinate (either "stay" or "go up")
  • 3 bits for x-coordinate displacement (0...4)
  • 3 bits for output char (fortunately, there are only 8 different chars)

There are 5 offsets into the control structure.

Some other obscure bits:

  • The code f%27%5 translates the characters VWSMI to numbers 0, 1, 2, 3, 4
  • The code t*3%12%5+4 calculates the width of the stickman of type t
  • The code t^3|~o||(s=d[5]+p,*s--=46,*s=39) accounts for the left/right asymmetry
  • I use the fact that argc=3 to generate drawing direction flags 1 and -1

Ungolfed code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char k[] = "(A(21;\0(A2:B(212;F\08A*B*0210KP\0-70A47/RT-A20G=CD?5D7_\0(A:(21;";

char d[8][999], // data of the battlefield
*s, // control string
*a; // cmdline argument
p, // position in the battlefield
f, // figure (char)
t, // type of the figure (0...4)
x,y, // coordinates while drawing the stickman
c; // control char, specifying what to draw

main(o, g) char**g; // o means "orientation" (+1, then -1)
{
    freopen("out.txt", "w", stdout);
    memset(d, ' ', 6993);

    for (; o -= 2, a=*++g;)
    {
        for (; f=*a;)
        {
            t = f%27%5;

            if (o<0)
                p += t*3%12%5+4; // go to the next stickman

            y = 6;
            for (s=k+"V3'? "[t]-32; c = *s++;) // loop over the control
            {
                if (c & 8) // bit 3: next line; set x to 0
                    --y, x = 0;
                x += c / 16 - 2; // bits 6...4: x coordinate
                if (o == -1 && !(c & 6)) // mirror \ <-> /
                    c ^= 1;
                d[y][p + o * x] = "/\\|O*'A."[c & 7];
            }
            if (t == 3 && o<0) // fix the asymmetrical mage
            {
                s=d[5]+p;
                *s--='.';
                *s='\'';
            }

            if (o>0)
                p += t*3%12%5+4; // go to the next stickman
            if (f != *++a) // is next stickman of different type?
                p += 2;
        }
        p += 3; // separate the armies
    }

    p -= 4;
    memset(d[6], '-', p); // draw the ground

    for (y = 0; *(s=d[y++]); ) // print the battle field
    {
        s[p] = 0;
        puts(s);
    }
}
\$\endgroup\$
  • \$\begingroup\$ Why are you able to not have the includes in the golfed version? Also why not change the semi-colon after *a to a comma? That gets rid of a warning and has the same number of bytes. \$\endgroup\$ – Fsmv Aug 19 '14 at 15:11
  • 1
    \$\begingroup\$ C has the "implicit declaration" rule; it's unsafe to rely on it but it works in practice so it's pretty standard in golfing. As for the semi-colon: I use the expression f=*a as the stopping condition; compiler may complain but I mean it. I cannot remove it because there should be two semicolons in the for-loop syntax. \$\endgroup\$ – anatolyg Aug 19 '14 at 15:19
2
\$\begingroup\$

Haskell, 556

Input Format

([1,1,2,3,1],[0,1,1,0,1])

Order: [Infant, Villager, Mage, Swordsman, Spearman], [Spearman, Swordsman, Mage, Villager, Infant]

Sample Output

               .        .                                                       .      
             .' *.    .' *.                                                   .* '.    
       O     ' O *    ' O *       O  /   O  /   O  /    O A        \  O       * O '    
 O    /|\   ' \|/ .  ' \|/ .    |/|\/  |/|\/  |/|\/    /|\|         \/|\|    . \|/ '    O
/|\    |    .  |  *  .  |  *    | |    | |    | |       | |           | |    *  |  .   /|\
/ \   / \   './ \*.  './ \*.     / \    / \    / \     / \|          / \     .*/ \.'   / \
------------------------------------------------------------------------------------------

Code

(?)=replicate
v=reverse
g=map
e=length
s=foldr1
p=zip[3,3,8,6,4]$g lines[" O\n/|\\\n/ \\"," O\n/|\\\n |\n/ \\","   . \n .' *.\n ' O *  \n' \\|/ .\n.  |  *\n'./ \\*.","  O  /\n|/|\\/\n| |\n / \\"," O A\n/|\\|\n | |\n/ \\|"]
r n x a=a++(n-e a)?x
x '\\'='/';x '/'='\\';x c=c
y(w,p)=(w,g(v.dropWhile(==' ').g x.r w ' ')p)
m n(a,p)(b,q)=(a+b+n,[r(a+n)' ' c++d|(c,d)<-zip(h p)(h q)])where h=v.r(max(e p)(e q))[].v
p%c|sum c==0=(0,[])|1<2=s(m 3)[s(m 1)$d?(p!!i)|(i,d)<-zip[0..]c,d>0]
f(w,p)=p++[w?'-']
main=interact((\(a,b)->unlines.f$m 8(p%a)((g y.v$p)%b)).read)

Ungolfed

type Pic = (Int, [String])

pics :: [Pic]
pics = zip[3,3,8,6,4]$map lines[" O\n/|\\\n/ \\"," O\n/|\\\n |\n/ \\","   . \n .' *.\n ' O *  \n' \\|/ .\n.  |  *\n'./ \\*.","  O  /\n|/|\\/\n| |\n / \\"," O A\n/|\\|\n | |\n/ \\|"]

mirrorChar '\\' = '/'
mirrorChar '/' = '\\'
mirrorChar c = c

padL, padR :: Int -> a -> [a] -> [a]
padL n x a = replicate (n - length a) x ++ a
padR n x a = a ++ replicate (n - length a) x

mirrorPic :: Pic -> Pic
mirrorPic (w, pic) = (w, map (reverse . dropWhile (==' ') . map mirrorChar . padR w ' ') pic)

merge n (w1, pic1) (w2, pic2) =
  let h = max (length pic1) (length pic2)
  in (w1 + n + w2, [padR (w1 + n) ' ' line1 ++ line2 | (line1, line2) <- zip (padL h [] pic1) (padL h [] pic2)])

makeArmy :: [Pic] -> [Int] -> Pic
makeArmy pics counts | sum counts == 0 = (0, []) | otherwise = foldr1 (merge 3) [ foldr1 (merge 1) . replicate count $ pics !! i | (i, count) <- zip [0..] counts, count > 0]

addField :: Pic -> [String]
addField (w, pic) = pic ++ [replicate w '-']

main = do
  (counts1, counts2)<- return . read =<< getLine
  putStr . unlines . addField $ merge 8 (makeArmy pics counts1) (makeArmy (map mirrorPic . reverse $ pics) counts2)
\$\endgroup\$
  • 1
    \$\begingroup\$ I didn't test, but according to your sample output you forgot to mirror the characters on the right side \$\endgroup\$ – William Barbosa Aug 9 '14 at 23:22
  • \$\begingroup\$ @WilliamBarbosa Fixed with a totally different solution. \$\endgroup\$ – Ray Aug 10 '14 at 21:11
1
\$\begingroup\$

Haskell (736 733 720 Bytes)

import System.Environment
import Data.List
a=1<2
h="   "
n="      "
o="    "
b (x:y)|x<0=[]|a=x:(b y)
c (x:y)|x>=0=c y|a=y
d [] _=[]
d (x:y)z|z/=x=[-5,x]++(d y x)|a=[x]++(d y x)
e x y|x< -5="        "|x<0=h|a=(([[h,h,"   .   ",n,o],[h,h," .' *. ",n,o],[h," o "," ' O * ","  O  /"," O A"],[" o ","/|\\", "' \\|/ .","|/|\\/ ","/|\\|"],["/|\\"," | ",".  |  *","| |   "," | |"],["/ \\","/ \\","'./ \\*."," / \\  ","/ \\|"]]!!(div z 5))!!(mod z 5))++" "where z=5*y+x
(§)=map
g=putStrLn
m=concat
main=do
    z<-getArgs
    let y=read§z::[Int]
    let w=sort(b y)
    let v=reverse(sort(c y))
    let u=(\(t,i)->(\s->e s i)§t)§(zip(take 6(cycle[((d w (w!!0))++[-9]++(d v (v!!0)))]))[0..5])
    mapM(\x->g(m x))u
    g(replicate(length(m(u!!0)))'-')

Call with ./stickmanwars 2 3 1 3 4 -1 3 2 4 1 0 4 2 1. The -1 marks the delimiter for the two arrays. I hope that is okay.

Well, my first code golf challenge and the first time I've used haskell for a real application after I learned it this semester at my university. Probably not even close to being the best or shortest solution but I had fun creating it and it was a good exercise :) Critique and feedback is highly appreciated.

Golfed it out of this:

import System.Environment
import Data.List

layers = [
    ["   ", "   ",  "   .   ",  "      ",  "    "],
    ["   ", "   ",  " .' *. ",  "      ",  "    "],
    ["   ", " o ",  " ' O * ",  "  O  /",  " O A"],
    [" o ", "/|\\", "' \\|/ .", "|/|\\/ ", "/|\\|"],
    ["/|\\"," | ",  ".  |  *",  "| |   "," | |"],
    ["/ \\","/ \\", "'./ \\*.", " / \\  ","/ \\|"],
    ["¯¯¯", "¯¯¯",  "¯¯¯¯¯¯¯",  "¯¯¯¯¯¯", "¯¯¯¯"]]

getLeftSide :: [Int] -> [Int]
getLeftSide (x:xs) | x < 0 = []
                   | otherwise = x : (getLeftSide xs)

getRightSide :: [Int] -> [Int]
getRightSide (x:xs) | x >= 0 = getRightSide xs 
                    | otherwise = xs

addSpacing :: [Int] -> Int -> [Int]
addSpacing [] _ = []
addSpacing (x:xs) old | old /= x = [(-50),x] ++ (addSpacing xs x)
                      | otherwise = [x] ++ (addSpacing xs x)

getLayerStr :: Int -> Int -> String
getLayerStr item dimension | item < (-50) = "        "
getLayerStr item dimension | item < 0  = "   "
                           | otherwise = ((layers !! i) !! j) ++ " "
    where
        value = (item + (5 * dimension))
        i = div value 5
        j = mod value 5

main = do
    -- Read Arguments from command line
    a <- getArgs
    -- Convert command line arguments to Int array
    let args = map read a :: [Int]
    -- Get left side of the array and sort it
    let frstArray = sort $ getLeftSide args 
    -- Get right side of the array and sort it mirrored
    let scndArray = reverse $ sort $ getRightSide args
    -- Concat the two sides and put a delimiter in between them
    let finalArray = (addSpacing frstArray (frstArray !! 0)) ++ [-99] ++ (addSpacing scndArray (scndArray !! 0))
    -- Create the matrix by 
    -- 1. Duplicating the final array 6 times (one for each level)
    -- 2. Pair each of those 6 arrays with its level (= index)
    -- 3. Create a matrix like below:
    --
    -- 1  1  2  2  3  4  4  5 -  1  1  2  2  2  4
    -- 6  6  7  7  8  9  9 10 -  6  6  7  7  7  9
    -- 11 11 12 12 13 14 14 15 - 11 11 12 12 12 14
    -- 16 16 17 17 18 19 19 20 - 16 16 17 17 17 19
    -- 21 21 22 22 23 24 24 25 - 21 21 22 22 22 24
    -- 26 26 27 27 28 29 29 20 - 26 26 27 27 27 29
    --
    -- 4. Convert the newly calculated indices to their respective strings
    let matrix = map (\(list,i) -> map (\item -> getLayerStr item i) list) (zip (take 6 $ cycle [finalArray]) [0..5])
    -- Finaly output the matrix by concating the elements ...
    mapM (\x -> putStrLn (concat x)) matrix
    -- ... and print the ground level.
    putStrLn (replicate (length $ concat $ matrix !! 0) '¯')
    -- Exit with a new line
    putStrLn ""
\$\endgroup\$
  • \$\begingroup\$ Spaces around parentheses is not necessary. That seems to save you a lot. \$\endgroup\$ – Ray Aug 9 '14 at 21:35
  • \$\begingroup\$ ah okay, saved me 3 bytes, thx :) \$\endgroup\$ – Ke Vin Aug 10 '14 at 1:19
  • \$\begingroup\$ No, a lot more. \$\endgroup\$ – Ray Aug 10 '14 at 3:50
  • \$\begingroup\$ you are right, I got a lot more just now. \$\endgroup\$ – Ke Vin Aug 10 '14 at 4:08
0
\$\begingroup\$

Haskell, 450

import Data.List
s=["      -"]
c=["    //-":"   O| -":"    \\\\-":s,"   / /-":"  O|| -":"   \\ \\-":s,"   '.'-":" .'  .-":" ' \\ /-":". O|| -":" * / \\-":" .*  *-":"   .*.-":s,"   || -":"   / /-":"  O|| -":"   \\ \\-":"   /  -":"  /   -":s,"   / /-":"  O|| -":"   \\ \\-":"  A|||-":s]
m '\\'='/'
m '/'='\\'
m x=x
u[]=[]
u x=x++[s,s]
f x=zipWith replicate x c>>=concat.u
k(a,b)=unlines.transpose$f a++s++s++map(map$m)(reverse$f b)
main=interact$k.read

Cool challenge! I might be able to golf that down a bit more. Basically I'm storing the figures column wise so I can append them to each other easily, and then flip the whole array of Strings arround using Haskell's transpose.

The input format is ([Infants,Villagers,Mages,Swordsmen,Spearmen],[Infants,Villagers,Mages,Swordsmen,Spearmen])

Here is the example from the OP:

>>>echo ([1,1,2,3,1],[0,0,1,1,1]) | cg2
               .       .                                                            .
             .' *.   .' *.                                                        .* '.
       O     ' O *   ' O *      O  /   O  /   O  /    O A        A O    \  O      * O '
 O    /|\   ' \|/ . ' \|/ .   |/|\/  |/|\/  |/|\/    /|\|        |/|\    \/|\|   . \|/ '
/|\    |    .  |  * .  |  *   | |    | |    | |       | |        | |       | |   *  |  .
/ \   / \   './ \*. './ \*.    / \    / \    / \     / \|        |/ \     / \    .*/ \.'
----------------------------------------------------------------------------------------

And here is my favourite depiction of the infamous ritual infanticide during the second era!

>>>echo ([0,0,0,1,0],[5,0,0,0,0]) | cg2


  O  /
|/|\/          O   O   O   O   O
| |           /|\ /|\ /|\ /|\ /|\
 / \          / \ / \ / \ / \ / \
---------------------------------
\$\endgroup\$
0
\$\begingroup\$

Python (612,522,460,440)

  • Rev1: Rudimentary compression and base64-encoding
  • Rev2: Removed compression/encoding; got smaller
  • Rev3: More byte count reduction by inlining
  • Rev4: Removed unneeded input reversal on 2nd army; swapped swordsman and spearman to match spec

Each "line" is trimmed of right-padding, and this is added back in when reconstructing.

I pre-reversed the stickmen in my internal encoding because it saved me having to reverse them individually when rendering them in the code.

Sample run:

$ echo "[1,1,2,3,1],[0,0,1,1,1]"|python /tmp/g2.py 
               .       .                                                            .   
             .' *.   .' *.                                                        .* '. 
       O     ' O *   ' O *      O  /   O  /   O  /    O A        A O    \  O      * O ' 
 O    /|\   ' \|/ . ' \|/ .   |/|\/  |/|\/  |/|\/    /|\|        |/|\    \/|\|   . \|/ '
/|\    |    .  |  * .  |  *   | |    | |    | |       | |        | |       | |   *  |  .
/ \   / \   './ \*. './ \*.    / \    / \    / \     / \|        |/ \     / \    .*/ \.'
----------------------------------------------------------------------------------------

Code:

c=",,A O,|/|\\,| |,|/ \\,,,\\  O, \\/|\\|,   | |,  / \\,   .  , .* '., * O ',. \\|/ ',*  |  .,.*/ \\.',,, O,/|\\, |,/ \\,,,, O,/|\\,/ \\".split(',')
r=['']*6
for b in input():
    for e,f in '/$ \\/ $\\'.split():r=[x.replace(e,f)[::-1] for x in r]
    if r[0]:r=[x+'  ' for x in r]
    for n,a in enumerate(b[::-1]):
        m=c[n*6:n*6+6]
        if a:r=[x+'   '+(' '.join([y.ljust(max(map(len,m)))]*a)) for x,y in zip(r,m)] 
print '\n'.join(r+['-'*len(r[0])])
\$\endgroup\$
0
\$\begingroup\$

Python (476)

A different solver from my previous one; longer, but more functional.

$ echo "[1,1,2,3,1],[0,0,1,1,1]"|python g3.py
               .       .                                                            .   
             .' *.   .' *.                                                        .* '. 
       O     ' O *   ' O *      O  /   O  /   O  /    O A        A O    \  O      * O ' 
 O    /|\   ' \|/ . ' \|/ .   |/|\/  |/|\/  |/|\/    /|\|        |/|\    \/|\|   . \|/ '
/|\    |    .  |  * .  |  *   | |    | |    | |       | |        | |       | |   *  |  .
/ \   / \   './ \*. './ \*.    / \    / \    / \     / \|        |/ \     / \    .*/ \.'
----------------------------------------------------------------------------------------

Code:

c=",,A O,|L|R,| |,|L R,,,R  O, RL|R|,   | |,  L R,   .  , .* '., * O ',. R|L ',*  |  .,.*L R.',,, O,L|R, |,L R,,,, O,L|R,L R".split(',')+['']*12
s=[sum([[4-n,5]*a+[6] for n,a in enumerate(b) if a]+[[5]],[])[::-1] for b in input()]
t=[[''.join([c[a*6+n].ljust([4,6,7,3,3,1,2][a]) for a in x]) for x in s] for n in range(0,6)]
for d,e,f in 'RL/ LR\\'.split():t=[[x[0].replace(d,f),x[1].replace(e,f)] for x in t]
t=[x[0][::-1]+x[1] for x in t]
print '\n'.join(t+['-'*len(t[0])])
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.