22
\$\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\$
10
  • 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\$ 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
  • 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\$ Aug 9 '14 at 17:33
  • 1
    \$\begingroup\$ I just wanted to say this challenge is awesome and I really appreciate that you made it. \$\endgroup\$
    – AJFaraday
    Jun 3 '20 at 14:30
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\$
1
  • \$\begingroup\$ Noticed you use lowercase Os. \$\endgroup\$
    – Phil Hord
    Aug 19 '14 at 17:08
3
\$\begingroup\$

C, 418 414 404

−10 bytes thanks to ceilingcat

Example input:

stickwar.exe IVMMWWWS SWM

Example output:


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

Golfed code:

char*s,d[8][999],*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;t-4-o||strcpy(d[5]+p-1,"'."),p+=l&-o,f^*++a?p+=2:0)for(t=f%27%5,l=t*3%12%5+4,p+=l&o,y=6,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++;d[y][p+o*x]="/\\|O*'A."[c&7])x=c/16-2+(c&8?--y*0:x),c^=o-1&&!(c&6);for(y=!memset(d[6],45,p-=4);*(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\$
3
  • \$\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
  • \$\begingroup\$ 402 bytes \$\endgroup\$
    – ceilingcat
    Jun 7 '20 at 19:08
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\$
2
  • 1
    \$\begingroup\$ I didn't test, but according to your sample output you forgot to mirror the characters on the right side \$\endgroup\$ 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\$
4
  • \$\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
1
\$\begingroup\$

05AB1E, 120 bytes

εU•1ĆÊLî˜₅ÉÈ«-—gí"Mª§ÚÇGäÒ²ĀÛNYE™Eæ]Ç€Š–ôTú™<C₄+i*∍.[½P•" 
|/\.O*'0A"ÅвJ0¡ε.B€S¸XNèиJøðý€S}õζJð3×ýNiεº2äθðÜ]øð8×ý¤'-s∍ª»

Input is similar as in the example, except it's paired together (i.e. [[1,1,2,3,1],[0,0,1,1,1]]).

Try it online.

Explanation:

ε                 # Map both inner lists of the (implicit) input to:
 U                #  Pop and store the list in variable `X`
  •1ĆÊLî˜₅ÉÈ«-—gí"Mª§ÚÇGäÒ²ĀÛNYE™Eæ]Ç€Š–ôTú™<C₄+i*∍.[½P•
                 "#  Push compressed integer 842496640498468305486897242730433696271358810529289612091214532817389449608887173562606281130145674459118763657187307135640
" 
|/\.O*'0A"        #  Push string " \n|/\.O*'0A"
          Åв      #  Convert the integer to this custom base-" \n|/\.O*'0A",
                  #  (short for converting it to base-length and indexing each into the string)
            J     #  Join this list of characters together to a single string
             0¡   #  And split it on "0"s

We now have a list of stick figures. I've generated the stick figures string with this program, which is a slightly modified version of this 05AB1E tip.

 ε                #  Map each stick figure to:
  .B              #   Box it (split on newlines, and append spaces to make all lines of equal length)
    €S            #   Convert each line to a list of characters
      ¸           #   Wrap the entire thing into a list
       X          #   Push input-sublist `X`
        Nè        #   Index the map-index into it
          и       #   Repeat the stick figure that many times as list
           J      #   Join each innermost list of characters together to a string
            ø     #   Zip/transpose; swapping rows/columns
             ðý   #   Join each line with a single space delimiter
               €S #   And convert each line back to a character list again
 }                #  After the inner map:
   ζ              #  Zip/transpose the list of stick figures,
  õ               #  with an empty string as filler (in case the input contained a 0)
    J             #  Join each inner list together to a string
     ð3×ý         #  Join each line with 3 spaces as delimiter
 Ni               #  If the map-index is 1 (thus the left army):
   ε              #   Map each line to:
    º             #    Mirror-reflect the line
     2ä           #    Split it into 2 equal-sized parts
       θ          #    Pop and only leave the last (mirrored) part
        ðÜ        #    Remove any trailing spaces
                  #    (necessary if the amount of infants in the left army is 0)
]                 # Close all maps and if-statements
 ø                # Zip/transpose; swapping rows/columns
  ð8×ý            # Join each line together with 8 spaces as delimiter
      ¤           # Push the last line (without popping the list itself)
       '-        '# Push string "-"
         s        # Swap so the last line is at the top of the stack
          ∍       # Extend the "-" to a length equal to that line
           ª      # Append it to the list
            »     # And join the lines by newlines
                  # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why •1ĆÊLî˜₅ÉÈ«-—gí"Mª§ÚÇGäÒ²ĀÛNYE™Eæ]Ç€Š–ôTú™<C₄+i*∍.[½P• is 842496640498468305486897242730433696271358810529289612091214532817389449608887173562606281130145674459118763657187307135640.

\$\endgroup\$
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.