25
\$\begingroup\$

I was just playing the board game Sorry! with some people, and I realized that I could base a few interesting challenges off of it. This one is pretty simple.

You task is simply to output an version of a sorry board, placing pieces where I tell you to.

Specs

First, here is an image of an actual Sorry! board for reference:

Sorry! Board

The empty board looks like:

# > - - o # # # # > - - - o # #
#   #   S                     v
o   #             H # # # # # |
|   #                         |
|   #                       S o
|   #                         #
^   H                         #
#                             #
#                             #
#                         H   v
#                         #   |
o S                       #   |
|                         #   |
| # # # # # H             #   o
^                     S   #   #
# # o - - - < # # # # o - - < #

Notice a few features.

  • The #'s are empty squares.
  • The S's and H's are Start's and Home's respectively.
  • The >v<^'s are the start of the slides, depending on which direction they face.
  • The |'s and -'s are the middles of slides, depending on if they're horizontal or vertical.
  • The o's are the end's of slides.
  • Each column is separated by a column of spaces to make it look more square-like.

Now here is what you have to do:

  • Your input is a list of coordinates of various pieces that have been placed on the board.
  • The coordinates start at 0 at the square outside the Start of the bottom color (yellow in the picture), and increase by one per square clockwise.
  • After these 60 squares, the safe zones have the next and last 20 coordinates, starting from the one on the bottom (which gets 60-64), then going clockwise.
  • You will have to place star's(*'s) on the correct coordinate, replacing the character underneath for all players.
  • Additionally, if any of the players are on the start square of a slider, move them to the end of the slider before placing them.
  • You can assume that there will be no collisions, before or after resolving sliders.
  • You con't need to worry about the Home's or Start's.
  • You can be 1-indexed if you want, but the test cases are 0-indexed.

Test Cases

[0, 20] ->

# > - - o # # # # > - - - o # #
#   #   S                     v
*   #             H # # # # # |
|   #                         |
|   #                       S o
|   #                         #
^   H                         #
#                             #
#                             #
#                         H   v
#                         #   |
o S                       #   |
|                         #   |
| # # # # # H             #   o
^                     S   #   #
# # o - - - < # # # # * - - < #

[2, 7, 66] ->

# > - - o # # # # > - - - o # #
#   #   S                     v
o   #             H # # # # # |
|   #                         |
|   #                       S o
|   #                         #
^   H                         #
#                             #
#                             #
#                         H   v
#                         #   |
o S                       #   |
|                         #   |
| # * # # # H             #   o
^                     S   #   #
# # o - * - < # # * # o - - < #
\$\endgroup\$
  • 1
    \$\begingroup\$ I would have thought this would be more interesting if the values were given as distances from the respective start squares (so for instance the first test case might be 0, 5 and the second might be 2, 60, 37). \$\endgroup\$ – Neil Dec 7 '16 at 10:20
  • \$\begingroup\$ @Neil how would you know which start square to use? \$\endgroup\$ – Maltysen Dec 7 '16 at 12:24
  • \$\begingroup\$ Sorry, I assumed that you used the squares in clockwise order, but I guess that wouldn't be very fair for a 2-player game. \$\endgroup\$ – Neil Dec 7 '16 at 12:26
  • \$\begingroup\$ @Closevoters: What's unclear about this? If you identify some specific concerns, it will make it easier to fix them so that this can stay open. \$\endgroup\$ – James Dec 7 '16 at 17:30
  • \$\begingroup\$ My confusion is about the indexing, before and after 60 has been reached and when to mark locations in the home section. I think if you clarified your examples more it would make more sense. Otherwise it looks pretty cool. \$\endgroup\$ – jacksonecac Dec 7 '16 at 20:34
4
+200
\$\begingroup\$

APL (Dyalog Unicode), 204 bytes

(~2|⍳31)\'H'@(g⊂2 9)⊢'S'@(g⊂4 14)⊢('*'@({(60>⍵)⊃⍵,60|⍵+4 3+.×5 12=15|⍵}¨⎕)⊢'o####<---o##^||o####^|||o##>--o####>---o##v||o####v|||o##<--',20⍴'#')@((4⌽g 15,⍨¨⍳15),(g←(15∘-,⊢)(|15 0-⌽)¨,⊢)2,¨14-⍳5)⊢16 16⍴''

Try it online!

It is very likely possible to compress the hardcoded length-60 string, but I'm too lazy :P

A full program that takes a vector of numbers from stdin and prints the board to stdout. Uses lots of @ to place various things at various places, starting from an empty board. This is an interesting use case for an otherwise seldom used built-in @.

Ungolfed with comments

⍝ Hardcoded string of the 80 positions that can be occupied by players
s←'o####<---o##^||o####^|||o##>--o####>---o##v||o####v|||o##<--',20⍴'#'

⍝ Place '*' for actual players' positions
s←'*'@({(60>⍵)⊃⍵,60|⍵+4 3+.×5 12=15|⍵}¨⎕)⊢s
      ({                             }¨⎕)  ⍝ Take input and slide the positions
                    ⍵+4.3+.×5 12=15|⍵      ⍝ If n%15=5, add 4; if n%15=12, add 3
                 60|                       ⍝ Wrap 60 to 0
        (60>⍵)⊃⍵,                          ⍝ Discard change if n is 60 or higher
  '*'@ ... ⊢s  ⍝ Overwrite '*' at players' positions on s

⍝ Helper function to generate positions on 2D board
g←(15∘-,⊢)(|15 0-⌽)¨,⊢  ⍝ Take a vector of coordinates on the right side
                    ,⊢  ⍝ Prepend to self...
          (|15 0-⌽)¨    ⍝   abs((15-y,x)); 90 degrees counterclockwise
  (15∘-,⊢)              ⍝ Take the above and prepend 180 degrees rotation

⍝ Main result
(~2|⍳31)\'H'@(g⊂2 9)⊢'S'@(g⊂4 14)⊢s@((4⌽g 15,⍨¨⍳15),g 2,¨14-⍳5)⊢16 16⍴''
16 16⍴''  ⍝ Empty 16×16 board
s@((4⌽g 15,⍨¨⍳15),g 2,¨14-⍳5)  ⍝ Place the 80 chars around the board
   (4⌽g 15,⍨¨⍳15)              ⍝   First 60 positions on the boundaries
                 ,g 2,¨14-⍳5   ⍝   and the other 20 positions inside
'S'@(g⊂4 14)  ⍝ Place S's
'H'@(g⊂2 9)  ⍝ Place H's
(~2|⍳31)\  ⍝ Insert blank columns
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Python 2, 476 bytes

Short 3-line solution (Try it online)

s=map(list,''.join(b if b in'#^v<>-|oSH~'else' '*int(b,16)for b in "#>--o####>---o##~#1#1SAv~o1#6H#####|~|1#C|~|1#BSo~|1#C#~^1HC#~#E#~#E#~#CH1v~#C#1|~oSB#1|~|C#1|~|#####H6#1o~^AS1#1#~##o---<####o--<#").split('~'))
for i in input():x,y=(lambda n:([11-n,15]*12+[0,26-n]*14+[n-26,0]*16+[15,n-41]*14+[71-n,15]*4+[13,n-50]*5+[70-n,13]*5+[2,75-n]*5+[n-65,2]*5)[2*n:2*n+2])((lambda n:4if n in[5,20,35,50]else 3if n in[12,27,42,57]else 0)(i)+i);s[y][x]='*'
for r in s:print' '.join(r)

One-liner in 534 (Try it online):

for r in(lambda B,I:[[[i,j]in map(lambda n:([11-n,15]*12+[0,26-n]*14+[n-26,0]*16+[15,n-41]*14+[71-n,15]*4+[13,n-50]*5+[n-64,13]*5+[2,75-n]*5+[n-65,2]*5)[2*n:2*n+2],map(lambda n:n+4if n in[5,20,35,50]else n+3if n in[12,27,42,57]else n,I))and'*'or b for i,b in enumerate(a)]for j,a in enumerate(B)])(map(list,''.join(b if b in'#^v<>-|oSH~'else' '*int(b,16)for b in"#>--o####>---o##~#1#1SAv~o1#6H#####|~|1#C|~|1#BSo~|1#C#~^1HC#~#E#~#E#~#CH1v~#C#1|~oSB#1|~|C#1|~|#####H6#1o~^AS1#1#~##o---<####o--<#").split('~')),input()):print' '.join(r)

I assume indices of safe zone this way:

#  >  -  -  o  #  #  #  #  >  -  -  -  o  #  #
#     74    S                                v
o     73                   H 75 76 77 78 79  |
|     72                                     |
|     71                                  S  o
|     70                                     #
^     H                                      #
#                                            #
#                                            #
#                                      H     v
#                                      60    |
o  S                                   61    |
|                                      62    |
|  69 68 67 66 65 H                    63    o
^                                S     64    #
#  #  o  -  -  -  <  #  #  #  #  o  -  -  <  #

Explanation (lines are separated a bit for better understanding):

# Hardcode board. Spaces are changed to their number in hex (as there are up to 14 spaces in row)
# Unfortunatly v^<> characters made board non-symmetrical and replacing chars costs too much in python, so I had to hardcode it all
B="#>--o####>---o##~#1#1SAv~o1#6H#####|~|1#C|~|1#BSo~|1#C#~^1HC#~#E#~#E#~#CH1v~#C#1|~oSB#1|~|C#1|~|#####H6#1o~^AS1#1#~##o---<####o--<#"

# Encode board to list of lists of characters
s=map(list,''.join(b if b in'#^v<>-|oSH~'else' '*int(b,16)for b in B).split('~'))

# Map coordinates, based on n (awfully long)
# Creates long list (lenght of 80) with values based on n and only one valid, which occures under index n
l=lambda n:([11-n,15]*12+[0,26-n]*14+[n-26,0]*16+[15,n-41]*14+[71-n,15]*4+[13,n-50]*5+[70-n,13]*5+[2,75-n]*5+[n-65,2]*5)[2*n:2*n+2]

# Returns additional move of n if it appers to be on slide start
j=lambda n:4if n in[5,20,35,50]else 3if n in[12,27,42,57]else 0

# Here takes input as list of numbers, get coordinates for them and update board with *
for i in input():x,y=l(j(i)+i);s[y][x]='*'

# Print board, spacing characters with one whitespace
for r in s:print' '.join(r)
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 169 bytes

11Ý₅+R14L17*R15ݤDL17*+¤3Lα4Ý©17*DƵ—αs19+®Ƶ_+s®48α)˜•1ŠΓ;Ü|má•Ƶªв•5–à†@1δ!•Ƶ§в‡Iè'*•3‡Ù¬¨èˆ‚1æ°þBÚ•" #
0o1HS"ÅвJ.BD€SøíJ‚øJ»∊2ä`¶¡í»«8Å120Å0«">>v^v^<<"„-|S5×Jº«S.;rǝS¶¡»

Try it online or verify all test cases.

Explanation:

We start by creating a list of all possible coordinates of the * on the finished board.
The list we want to create for the 0-based indices is:

[266,265,264,263,262,257,260,259,258,257,256,255,187,221,204,187,170,153,136,119,34,85,68,51,34,17,0,4,2,3,4,5,6,7,8,13,10,11,12,13,14,15,83,49,66,83,100,117,236,151,168,185,202,219,236,253,270,266,268,267,251,234,217,200,183,222,223,224,225,226,19,36,53,70,87,48,47,46,45,44]

The duplicated coordinates are for the positions that are on the start of a slider, which end up at the end of the slider.

Using a straight-forward compressed list would be 86 bytes:

•€l:å–£²voùäÉÿ¢º(ºT≠εÁ~нΣûÑ‚Ćδ·нäVø<:‘.IWÚC¯ht;t∍W₂zþ#6÷(›ǝé$)‚ιô.!=É/g=Ë₁Ìjh:½~₃Y•Ƶ«в

But instead, we create the list manually in 79 bytes:

11Ý           # Push a list in the range [0,11]
   ₅+         # Add 255 to each
     R        # And reverse it
14L           # Push a list in the range [1,14]
   17*        # Multiply each by 17
      R       # And reverse it
15Ý           # Push a list in the range [0,15]
¤             # Push its last value (15) (without popping the list itself)
 D            # Duplicate it
  L           # Create a list in the range [1,15]
   17*        # Multiply each by 17
      +       # And add the 15 to each
¤             # Push its last value (270) without popping the list itself)
 3L           # Push a list in the range [1,3]
   α          # Take the absolute difference of each value with 270
4Ý            # Push a list in the range [0,4]
  ©           # Store it in variable `®` (without popping)
   17*        # Multiply each by 17
      D       # Duplicate this list
       Ƶ—     # Push compressed integer 251
         α    # And take the absolute difference of each value with this 251
s             # Swap so the duplicated list of [0,4] * 17 is at the top again
 19+          # Add 19 to each
®             # Push the list in the range [0,4] again from variable `®`
 Ƶ_           # Push compressed integer 222
   +          # Add it to each
s             # Swap the two lists at the top of the stack
®             # Push the list in the range [0,4] once again from variable `®`
 48α          # Take the absolute difference of each value with 48
)             # Now wrap all lists on the stack into a list
 ˜            # And flatten it to a single list

# And finally adjust this list with the slider positions:
•1ŠΓ;Ü|má•    # Push compressed integer 108136777658162939
          Ƶª  # Push compressed integer 270
            в # Convert the larger integer to base-270 as list:
              #  [1,9,32,102,134,238,261,269]
•5–à†@1δ!•    # Push compressed integer 391758411553146080
          Ƶ§  # Push compressed integer 267
            в # Convert the larger integer to base-267 as list
              #  [4,13,83,34,236,187,257,266]
‡             # Transliterate; replace all values of the first list with the values of
              # the second list in the big list we created earlier

Now that we have this list of coordinates for the *, we use the input to get the positions:

I             # Push the input-list
 è            # Index it into the list we created
'*           '# Push a "*" (which we will use later on)

Now we are going to create the empty board (without the space columns for now). We do this as follows:

•3‡Ù¬¨èˆ‚1æ°þBÚ•
              # Push compressed integer 68098022849564198525854900638097
 " #\n0o1HS"  # Push this string
  Åв          # Convert the large integer to base-" #\n0o1HS", which means it's converted
              # to base-length, and then indexed into the string
    J         # And join the entire list of characters to a string

We now have a quarter of the board as template (without trailing spaces):

#100o###
# # S
o #
0 #
0 #
0 #
1 H
#

Which we'll use to create the entire board:

.B            # Box it. This will split on newlines, but also make all lines of equal
              # length by adding trailing spaces
  D           # Duplicate this list of lines
€S            # Convert each line to a list of characters
  ø           # Zip/transpose; swapping rows/columns
   í          # Reverse each row
              # (`øí` basically rotates a character-matrix once clockwise)
    J         # Join each inner list together to a string
‚             # Pair it with the list of strings we duplicated
 ø            # Zip/transpose; swapping rows/columns
  J           # Join the pair of lines together
   »          # And join the lines by newlines

We now have halve the board:

#100o####1000o##
# # S          1
o #      H#####0
0 #            0
0 #           So
0 #            #
1 H            #
#              #

And we'll continue:

∊             # Mirror vertically
 2ä           # Split it into two halves
   `          # Pop and push both halves separated to the stack
¶¡            # Split the top list on newlines again
  í           # Reverse each row
   »          # Join it by newlines
«             # And then merge it back to the first halve

# And now we'll fix the arrows and lines:
8Å1           # Push a list of 8 1s
   20Å0       # Push a list of 20 0s
       «      # Merge those two together
">>v^v^<<"    # Push this string
„-|           # Push string "-|"
   S          # Convert it to a pair of characters: ["-","|"]
    5×        # Repeat each 5 times: ["-----","|||||"]
      J       # Join it together to a string "-----|||||"
       º      # Mirror it horizontally: "-----||||||||||-----"
        «     # Append it to the arrows-string
          S   # Convert it to a list of characters
.;            # Replace each of the 1s/0s one-by-one with these characters in the board

So we end up with our completed empty board (without space columns):

#>--o####>---o##
# # S          v
o #      H#####|
| #            |
| #           So
| #            #
^ H            #
#              #
#              #
#            H v
#            # |
oS           # |
|            # |
|#####H      # o
^          S # #
##o---<####o--<#

Then we'll place the "*" we pushed earlier at the positions we calculated earlier:

r             # Reverse the values on the stack
 ǝ            # Insert the "*" at the position of the list in the board-string

And finally we fix the space-columns, and output the result:

S             # Convert the entire board to a list of characters
 ¶¡           # Split it on newlines
   »          # Join each inner list by spaces, and then each line by newlines
              # (after which the result is output implicitly)

See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand how the compression works.
I've used this 05AB1E tip to generate the quarter board.

| improve this answer | |
\$\endgroup\$

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