Counting icons for Innovation splays

11

Innovation is a card game where players battle through the ages, from prehistory to modern times, in an attempt to earn achievements faster than their opponents.

Each card in Innovation is unique, and provides a player with a number of icons. If we treat each card as a 2x3 grid, then three of the four slots on the left and bottom edges will always been taken up by icons (the symbols in black hexagons are not counted).

enter image description here

The game has 6 types of icons (castles, crowns, leaves, lightbulbs, factories and clocks), which we will represent arbitrarily using the chars 012345. Using # to represent the black hexagon, we can use four chars to represent the icons on each card. For example, the cards above are

0.. #.. 3.. 1..  -> 03#0 #331 355# 144#
3#0 331 55# 44#

Now, in Innovation, cards in the play area are grouped into piles* which are splayed in one of four ways. For each example we'll use the cards above, assuming the leftmost card, 03#0, is at the top of the pile.

No splay: only the top card is visible

0..
3#0

Splay left: the top card is fully visible, as well as the right third of all cards below

0..|.|.|.|
3#0|1|#|#|

Splay right: the top card is fully visible, as well as the left third of all cards below

1|3|#|0..
4|5|3|3#0

Splay up: the top card is fully visible, as well as the bottom half of all cards below.

0..
3#0
---
331
---
55#
---
44#

The challenge

Input will be a single space-separated string consisting of two parts:

  • A splay direction, which is one of !<>^, representing no splay, splay left, splay right or splay up respectively.
  • A non-empty list of cards, each of which is 4 characters long and consisting of the chars 012345#. The leftmost card is at the top of the pile, and each card contains exactly one #.

Answers may be functions, full programs or equivalent. You may choose whether the splay direction is first or last, i.e. choose one of the two formats below:

> 03#0 #331 355# 144#
03#0 #331 355# 144# >

Output will be a list of six numbers representing the count for each icon, e.g. for the example cards above:

! 03#0 #331 355# 144#  ->  2 0 0 1 0 0
< 03#0 #331 355# 144#  ->  2 1 0 1 0 0
> 03#0 #331 355# 144#  ->  2 1 0 3 1 1
^ 03#0 #331 355# 144#  ->  2 1 0 3 2 2

For instance, the no splay case had two 0 icons and one 3 icon showing, giving the first line. Note that we don't count #s, since the black hexagons aren't icons.

You may choose any reasonable and non-ambiguous way of representing the list, e.g. delimiter-separated or using your language's natural list representation.

Test cases

! 113#  ->  0 2 0 1 0 0
< 113#  ->  0 2 0 1 0 0
> 113#  ->  0 2 0 1 0 0
^ 113#  ->  0 2 0 1 0 0
! 000# 12#2  ->  3 0 0 0 0 0
< 000# 12#2  ->  3 0 1 0 0 0
> 000# 12#2  ->  3 1 1 0 0 0
^ 000# 12#2  ->  3 0 2 0 0 0
! 000# 111# 222#  ->  3 0 0 0 0 0
< 000# 111# 222#  ->  3 0 0 0 0 0
> 000# 111# 222#  ->  3 2 2 0 0 0
^ 000# 111# 222#  ->  3 2 2 0 0 0
! 335# #101 21#2 333# 2#20 3#33 4#54 #133 3#33 32#2  ->  0 0 0 2 0 1
< 335# #101 21#2 333# 2#20 3#33 4#54 #133 3#33 32#2  ->  1 1 2 5 1 1
> 335# #101 21#2 333# 2#20 3#33 4#54 #133 3#33 32#2  ->  0 3 3 7 1 1
^ 335# #101 21#2 333# 2#20 3#33 4#54 #133 3#33 32#2  ->  2 4 4 10 1 2

Note that something like ! is invalid input, since the list is guaranteed to be non-empty.


* For the purposes of this challenge, we're ignoring pile colours.

Sp3000

Posted 2015-12-08T13:23:26.290

Reputation: 58 729

Answers

5

CJam, 44 37 36 bytes

Thanks to Sp3000 for reminding me that I'm overcomplicating things and saving 7 bytes.

rci7%"3>0<2<1>"2/=6,slS%{W$~+}*fe=p;

Test it here.

Explanation

Some observations:

  • We always want to count the entire first card.
  • All splays will result in either a prefix or a suffix of the icons removed. ! removes all of them (which is either a prefix or a suffix of four characters), < removes the first three characters, > removes the last two characters, ^ removes the first character.

So all we need is a short way to map the splay mode to the correct truncation:

rci   e# Read the splay mode and convert to its character code.
7%    e# Take modulo 7. This maps "<!>^" to [4 5 6 3], respectively. Modulo 4 those are
      e# are all distinct (namely [0 1 2 3], respectively).
"3>0<2<1>"
      e# Push this string.
2/    e# Split it into chunks of 2, ["3>" "0<" "2<" "1>"]. Each chunk is CJam code which
      e# performs one of the truncations.
=     e# Select the correct snippet. This works, because array indexing is cyclic in CJam.
6,s   e# Push the string "012345".
lS%   e# Read the remainder of the input and split into space-separated tokens.
{     e# Now we're abusing the fold operation to apply our snippet to every card except
      e# the first, while also combining them all back into a single string.
  W%  e#   Copy the bottom of the stack (the truncation snippet).
  ~   e#   Evaluate it.
  +   e#   Append it the string we're building.
}*
fe=   e# For each character in "012345", count the occurrences in our new string.
p     e# Pretty-print the array.
;     e# Discard the truncation snippet which was still at the bottom of the stack.

We can notice that the truncation snippets actually have a lot of structure. Each splay mode maps to one number in [0 1 2 3] (specifically, in order "!^><"), and two of them have > and two have <. I was hoping to find two hashes which magically produce these parts separately, as that would save a bunch of bytes, but so far I wasn't able to find anything. I can map "!^><" to numbers of alternating parity with 31% (to select the correct character from "<>"), but I haven't found anything which neatly maps them [0 1 2 3] in that order. (Except the naive solution of "!^><"# which unfortunately doesn't save any bytes.)

Also note that it's actually a bit more flexible. ! can also be implemented as n> for any n > 3 (discarding everything as a prefix). Unfortunately, I haven't been able to find any simple function for such a map either.

Martin Ender

Posted 2015-12-08T13:23:26.290

Reputation: 184 808

0

Pyth, 39 36 33 31 bytes

Jtczdm/s+hJm@yk%*%Chz33T19tJ`d6

Try it online. Test suite.

Explanation

  • Jtczd: split input by spaces, remove the first part, and save the rest to J.
  • m6: repeat the following for numbers 0 to 5.
    • mtJ: repeat the following for all cards except for the first one.
      • Chz: get the code point of the first character in the input.
      • %*%33T19: map the code points of !<>^ (33, 60, 62, 94) to the numbers 0, 4, 5, 14. The exact calculation performed is cp % 33 * 10 % 19.
      • yk: get the powerset of the current card. This is a list of all subsequences of the card.
      • @: get the item of the powerset corresponding to the index calculated before.
    • +hJ: append the first card to the result.
    • s: concatenate the processed cards together.
    • /`d: count the occurrences of the current number in the result.

PurkkaKoodari

Posted 2015-12-08T13:23:26.290

Reputation: 16 699