Codegolf - Распечатать Доску Извинений

  • Автор темы Pavelkogan
  • Обновлено
  • 17, Oct 2024
  • #1

Я просто играл в настольную игру Извини! с некоторыми людьми, и я понял, что могу построить на этом несколько интересных задач. Это довольно просто.

Ваша задача — просто вывести версию жалкой доски, размещая части там, где я вам скажу.

Характеристики

Во-первых, вот изображение реального Извини! доска для справки:

Пустая доска выглядит так:

 
 [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 - - < #
 

Обратите внимание на несколько особенностей.

  • * 's are empty squares.
  • 0 's and o - это Start и Home соответственно.
  • - 's are the start of the slides, depending on which direction they face.
  • | 's and >v<^ — это середина слайдов, в зависимости от того, горизонтальны они или вертикальны.
  • H 's are the end's of slides.
  • Каждый столбец разделен столбцом пробелов, чтобы он выглядел более квадратным.

Теперь вот что ты нужно сделать:

  • Ваши входные данные — это список координат различных фигур, размещенных на доске.
  • Координаты начинаются с S at the square outside the Start of the bottom color (yellow in the picture), and increase by one per square clockwise.
  • После этих 60 квадратов безопасные зоны имеют следующие и последние 20 координат, начиная с нижней (которая получает 60-64), а затем идя по часовой стрелке.
  • Вам нужно будет разместить звезды( # 's) on the correct coordinate, replacing the character underneath for all players.
  • Кроме того, если кто-либо из игроков находится на начальной клетке ползунка, перед размещением переместите его в конец ползунка.
  • Вы можете предположить, что коллизий не будет ни до, ни после разрешения ползунков.
  • Вам не нужно беспокоиться о Home или Start.
  • Если хотите, вы можете иметь 1-индекс, но тестовые примеры имеют 0-индекс.

Тестовые случаи

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

#ascii-art #code-golf #ascii-art #kolmogorov-complexity #board-game

Pavelkogan


Рег
06 Mar, 2014

Тем
82

Постов
193

Баллов
633
  • 26, Oct 2024
  • #2

APL (Диалог Юникод), 204 байты

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 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)
 

Попробуйте онлайн!

Очень вероятно, что можно сжать жестко закодированную строку длиной 60, но я слишком ленив: P

Полная программа, которая принимает вектор чисел со стандартного ввода и выводит плату на стандартный вывод. Использует много r # Reverse the values on the stack ǝ # Insert the "*" at the position of the list in the board-string 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 с комментариями

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

Питон 2, 476 байт

Короткое трехстрочное решение (Попробуйте онлайн)

∊ # 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

Однострочник в 534 (Попробуйте онлайн):

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

Я предполагаю индексы безопасной зоны следующим образом:

.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

Пояснение (строки немного разделены для лучшего понимания):

#100o### # # S o # 0 # 0 # 0 # 1 H # ||answer||

05AB1E, 169 байты

•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

Попробуйте онлайн или проверить все тестовые случаи.

Объяснение:

Начнем с создания списка всех возможных координат I # Push the input-list è # Index it into the list we created '* '# Push a "*" (which we will use later on) on the finished board.
Список, который мы хотим создать для индексов, отсчитываемых от 0:

*

Дублированные координаты предназначены для позиций, находящихся в начале ползунка и заканчивающихся в конце ползунка.

Использование прямого сжатого списка составит 86 байт:

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

Но вместо этого мы создаём список вручную в 79 байт:

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

Теперь, когда у нас есть список координат для [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] , we use the input to get the positions:

*

Теперь мы собираемся создать пустую доску (пока без пробелов). Мы делаем это следующим образом:

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¶¡»

Теперь у нас есть четверть доски в качестве шаблона (без конечных пробелов):

# 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)

Который мы будем использовать для создания всей доски:

# > - - 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 - - < #

Теперь у нас есть половина доски:

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)

И мы продолжим:

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)

В итоге мы имеем заполненную пустую доску (без пробелов):

⍝ 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=5, add 4; if n=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

Затем мы разместим @ we pushed earlier at the positions we calculated earlier:

@

И, наконец, исправим пробелы в столбцах и выведем результат:

(~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⍴''

См. мой совет по 05AB1E (разделы Как сжать большие целые числа? и Как сжать целочисленные списки?) чтобы понять, как работает сжатие.
Я использовал этот совет 05AB1E для создания четверти доски.

 

SLuthien


Рег
24 Nov, 2019

Тем
75

Постов
188

Баллов
583
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно