Построй мне город


34

Кодеры всегда пытаются сгладить массивы в скучные одномерные объекты, и это меня огорчает.

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

Рассмотрим строку: aaabbbbbccqrrssstttttttPPw

Это выглядит намного лучше, как это:

            tt
            tt
  bb        tt
  bb        tt
aabb      sstt
aabbcc  rrssttPP
aabbccqqrrssttPPww

(Хорошо, да, буквы продублированы, чтобы они выглядели как городские горизонты).

Возьмите строку ввода, продублируйте каждый подраздел соответствующих символов (не обязательно букв алфавита) и постройте мне город!

Самый короткий код байтов побеждает.

Я на самом деле думал, что у меня есть требования, но ответить на несколько вопросов:

  • это должно быть на земле
  • Вы можете иметь дополнительное небо, если хотите (ведущие пустые строки, окружающие пустое пространство) - но не между зданиями
  • буквы могут быть повторно использованы внутри строки (та же архитектура, другое местоположение)
  • Предполагается, что буквы ASCII, но больше внимания будет уделено тем, кто поддерживает дополнительные кодировки (UTF8 и т. д.).

3
Можем ли мы вывести городской пейзаж с поворотом на 90 градусов?
Okx

6
Будут ли персонажи когда-либо повторяться снова aaabbbbaa?
TheLethalCoder

14
@Okx ты когда-нибудь видел город, повернутый на 90 градусов, это выглядело бы очень глупо! ;)
Том


10
Добро пожаловать на сайт! Что касается будущих задач, я рекомендую сначала опубликовать их в Песочнице, где вы можете получить отзывы от сообщества, прежде чем публиковать их в качестве испытания.
Дада

Ответы:


11

05AB1E , 6 байтов

γ€DζR»

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

В версии, более новой, чем задача, ζбыла добавлена ​​в качестве замены для.Bø

05AB1E , 8 байтов

γ€D.BøR»

Объяснение:

γ            Convert into a list of consecutive equal elements
 €D          Duplicate each element
   .B        Squarify; pad each element with spaces so that they are the length of the longest element
     ø       Transpose
      R      Reverse (otherwise the city would be upside-down)
       »     Join by newlines

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


1
Интересно, что Jelly имеет z⁶для .Bø... но он также имеет Œgx'2для γ€D> _>
Эриком Outgolfer

γ.BD)ø˜øR»было то, что я имел, не глядя, €Dнамного лучше; Я чувствую, что нам обоим не хватает 1-байтового решения для встроенного дублирования.
Волшебная Урна Осьминога

3
@MagicOctopusUrn Подождите, вы решили проблему, даже не глядя на нее?
Okx

@Okx Хорошо, не стоит смотреть на ответы раньше, так как все удовольствие от игры в гольф может быть отрезано.
Эрик Outgolfer

@EriktheOutgolfer Это была шутка, и я имел в виду, что он решил ее, не глядя на содержание задачи.
Okx

6

CJam , 23 байта

qe`::*:__:,:e>f{Se[}zN*

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

Объяснение:

qe`::*:__:,:e>f{Se[}zN* Accepts (multi-line?) input
q                       Take all input
 e`::*                  Split into groups of equal elements
      :_                Duplicate each
        _:,:e>          Push maximal length without popping
              f{Se[}    Left-pad each to that length with space strings (NOT space chars, although not a problem here)
                    z   Zip
                     N* Join with newlines

Ничего себе, ответ CJam> _>
Мистер Xcoder

6

Желе , 9 байт

Œgx'2z⁶ṚY

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

Объяснение:

Œgx'2z⁶ṚY  Main Link
Œg         Group runs of equal elements
  x        Repeat
   '              the lists
    2                       twice without wrapping
     z⁶    Zip (transpose), filling in blanks with spaces
       Ṛ   Reverse the whole thing so it's upside-down
        Y  Join by newlines

1
Не могли бы вы добавить объяснение, милорд? Я не могу понять, что здесь происходит: о
Натан


@HyperNeutrino Хорошее объяснение ...
Эрик Outgolfer

Просто чтобы быть уверенным, это правильно? : P
HyperNeutrino

@HyperNeutrino Ну, это было не совсем намерение ', которое состояло в том, чтобы повторять сами списки, а не элементы внутри них, но в целом это хорошо. :)
Эрик Outgolfer

6

Python 3 , 155 136 134 132 байта

-19 байт благодаря @LeakyNun
-2 байт благодаря @officialaimm
-1 байт благодаря @Wondercricket

s=input()+'+'
k=' '*len(s)
a=[]
c=b=''
while s:
 while c in b:b+=c;c,*s=s
 a+=b+k,b+k;b=c
for r in[*zip(*a)][:0:-1]:print(*r,sep='')

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



5

Ява 8, 412 400 330 324 312 319 байт

-6 байт благодаря VisualMelon
-12 байт благодаря Кевину Круйссену,
но +19 байт, потому что я забыл включить импорт в число байтов.

import java.util.*;x->{Map m=new HashMap(),n;int l=x.length(),i=l,v,y,h=0,d=1;char c,k;for(;i-->0;m.put(c,d=m.get(c)!=null?d+1:1),h=d>h?d:h)c=x.charAt(i);for(y=h;y>0;y--){n=new HashMap(m);for(i=0;i<l;i++)if(n.get(k=x.charAt(i))!=null){v=(int)m.get(k);System.out.print((y>v?"  ":k+""+k)+(i==l-1?"\n":""));n.remove(k);}}}

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


1
Гольф Java и C # (мой отдел) - это очень весело! Держись! Не сдавайся! Не проверено, но я думаю, что вы можете сэкономить несколько байтов, перенастроив циклы for: вы можете предварительно назначить i=0или, что лучше i=l, и вести обратный отсчет for(;i-->0;h=d>h?d:h)(и добавить h=туда немного). Тот же обратный отсчет будет работать и для внутреннего цикла. Внутренний ifтакже не нуждается в фигурных скобках {}. И всегда надоедать <=или >=, вы можете перевернуть троичный с помощью >и сохранить байт.
VisualMelon

Спасибо, я мог бы убрать еще 6 байтов кода благодаря вашим советам. Ну, я думаю, что я собираюсь остаться с Java Golfing, так как мне на самом деле это нравится;).
Twometer

1
Добро пожаловать в PPCG! Боюсь, вам придется увеличить число байтов до 329 (+19 байтов из-за необходимости import java.util.*;для Mapи HashMap, импорт является частью количества байтов; -1 путем удаления конечной точки с запятой, что не часть подсчета байтов).
Кевин Круйссен


1
Краткое описание изменений: HashMap<>HashMap; Map n=,nи n=; m.put(c,d=m.get(c)!=null?d+1:1);внутри петли, чтобы избавиться от скобок; k=x.charAt(i)внутри, if(n.get(k)!=null)чтобы избавиться от точки с запятой и петли для скобок. И снова добро пожаловать и отличный ответ! +1 от меня. Кроме того, на случай, если вы еще этого не видели: советы по игре в гольф на Java и советы по игре в гольф на <любой язык> могут быть интересными для чтения.
Кевин Круйссен

5

Джапт , 19 18 15 13 12 байт

Включает конечные пробелы в каждой строке.

ò¦
íU c ·z w

Попробуй это


объяснение

         :Implicit input of string U
ò        :Split U to an array by ...
¦        :   checking for inequality between characters.
í        :Pair each item in U with...
U        :   The corresponding item in U (i.e, duplicate each string)
c        :Flatten the array (í creates an array of arrays).
·        :Join to a string with newlines.
z        :Rotate 90 degrees.
w        :Reverse.
         :Implicit output of resulting string.

4

Mathematica, 150 байт

(z=Characters[v=#];f=CharacterCounts[v][#]&/@(d=Union@z);Row[Column/@Map[PadLeft[#,Max@f,""]&,Table[Table[d[[i]]<>d[[i]],f[[i]]],{i,Length@d}],{1}]])&

4

R 135 байтов

e=rle(sub('(.)','\\1\\1',strsplit(scan(,''),'')[[1]]));write(sapply(sum(e$l|1):1,function(x)ifelse(e$l>=x,e$v,'  ')),'',sum(e$l|1),,'')

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

читает из стандартного ввода, пишет в стандартный вывод (с завершающим переводом строки).

Объяснение:

  • rle находит длины полос персонажей, высоты каждой башни.
  • subвыражение заменяет каждый символ с его двойным (так что я не должен слоняться с установкой соседних индексов вместе)
  • sapply возвращает массив (в данном случае матрица):
    • sum(e$l|1)количество отдельных символов; мы идем сверху вниз
    • ifelse( ... ) это векторизация if...else позволяющая нам построить матрицу башен и двойных пространств
    • write пишет в консоль, с несколькими вариантами форматирования.



2

MATL , 15 байт

'(.)\1*'XXtvc!P

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

объяснение

'(.)\1*' % Push string to be used as regexp pattern
XX       % Implicit input. Regexp matching. Pushes row cell array of matching substrings
t        % Duplicate
v        % Concatenate vertically
c        % Convert to char. This reads cells in column-major order (down, then across)
         % and produces a 2D char array, right-padding with spaces
!        % Transpose
P        % Flip vertically. Implicitly display

2

Древесный уголь , 40 байт:

A⟦⟦ω⟧⟧λFθ¿⁼ι§§λ±¹¦⁰⊞§λ±¹ι⊞λ⟦ι⟧FλF²↑⁺⪫ιω¶

Попробуйте онлайн! Ссылка на подробную версию кода. Первоначально я пытался выполнить простой цикл над строкой ввода, чтобы печатать продолговатую букву каждый раз, когда буква менялась, но я переключился на этот метод построения списка, так как он экономил 5 байтов. Объяснение: Переменная lсодержит вложенный список вводимых букв. Символы, которые соответствуют текущим последним элементам списка, помещаются в последний список, в противном случае для этого символа создается новый подсписок. Затем остается объединить буквы в каждом подсписке, чтобы они могли печататься вертикально дважды.


2

C 259 231 байт

Гольф-код

#define v a[1][i
i,k,l,x,h,w;main(char*s,char**a){for(;v];w+=2*!x,s=v++],h=x>h?x:h)x=(s==v])*(x+1);h++;s=malloc((x=h++*++w+1)+w);memset(s,32,h*w);for(i=k;v];s[x+1]=s[x]=k=v++],x=k==v]?x-w:(h-1)*w+l++*2+3)s[i*w]=10;printf("%s",s);}

Подробный код

//Variable Explanations:
//i - increment through argument string, must beinitialized to 0
//k - increment through argument string, must be initialized to 0
//l - record x coordinate in return value, must be initialized to 0
//x - record the actual character position within the return string
//arrheight - the height of the return string
//arrwidth - the width of the return string
//arr - the return string
//argv - the string containing the arguments
#define v argv[1][i

i,k,l,x,arrheight,arrwidth;

main(char*arr,char**argv){
  for(;v];                                 //For Length of input
    arrwidth+=2*!x,                        //increment width by 2 if this char is not the same as the last
    arr=v++],                              //set arr to current char
    arrheight=x>arrheight?x:arrheight      //see if x is greater than the largest recorded height
  )x=(arr==v])*(x+1);                     //if this character is the same as the last, increment x (using arr to store previous char)
  arrheight++;                             //increment height by one since its 0 indexed
  arr=malloc((x=arrheight++*++arrwidth+1)+arrwidth); //create a flattened array widthxheight and set x to be the bottom left position
  memset(arr,32,arrheight*arrwidth);       //fill array with spaces
  for(i=k;v];                              //For Length of input
    arr[x+1]=arr[x]=k=v++],                //set x and x+1 positions to the current character, store current character in i
    x=k==v]?x-arrwidth:(arrheight-1)*arrwidth+l++*2+3 //if next char is same as current move vertically, else set x to bottom of next column
  )arr[i*arrwidth]=10;                     //Add new lines to string at end of width

  printf("%s",arr);                        //output string

}

Составлено с GCC, без специальных флагов

редактировать

Сохранено 28 байт благодаря adelphus. Его изменение позволило мне создать определение. И я сделал цикл while для циклов for, чтобы сэкономить 2 байта каждый, переставляя цикл. Я также исправил проблему, из-за которой код ломался, когда последний введенный символ не был одиночным. Код не удастся, если есть только одна уникальная буква, но должен работать во всех других случаях.


Ницца! Но версия для гольфа почему-то не работает с произвольным вводом. Удаление последней буквы «w» из входных данных выборки приводит к потере q и повторению строки. Конечно, это что-то маленькое ...
adelphus

также while (i < strlen(argv[1]))может быть сокращено до while (argv[1][i])- цикла до нулевого символа
adelphus

@adelphus Интересно, я попробую завтра, когда у меня будет шанс. Я не проверял ничего, кроме данного контрольного примера (ленивый, я знаю).
dj0wns

Это действительно помогло, мне удалось решить проблему и уменьшить ее почти на 30 байт!
dj0wns

1

Пип , 22 байта

21 байт кода, +1 для -lфлага.

Ya@`(.)\1*`RV:yWVyZDs

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

объяснение

                       a is 1st cmdline arg; s is space (implicit)
 a@`(.)\1*`            Using regex, create list of runs of same character in a
Y                      Yank that into y variable
              yWVy     Weave (interleave) y with itself to duplicate each item
                  ZDs  Zip to transpose, with a default character of space filling gaps
           RV:         Reverse the resulting list (with the compute-and-assign
                        meta-operator : being abused to lower the precedence)
                       Auto-print, one sublist per line (implicit, -l flag)

1

QuadS , 15 + 1 = 16 байт

+1 байт за 1флаг.

⊖⍵
(.)\1*
2/⍪⍵M

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

⊖⍵ пост-процесс, переворачивая вверх дном

(.)\1* пробеги одинаковых персонажей

2/⍪⍵M дублировать столбец M ATCH

1Флаг приводит к тому , чтобы результаты были объединены вместе.


1

Haskell, 144 байта

f s=let x=groupBy(==)s;l=length;m=maximum(map l x)in concatMap(++"\n")$reverse$transpose$concat[[z,z]|z<-(map(\y->y++(replicate(m-(l y))' '))x)]

Я уверен, что могу добиться большего, чем это, но это лучшее, что я могу придумать на данный момент.


1
Сначала плохие новости: вы используете функции, Data.Listкоторые не входят в область действия по умолчанию. Вы должны либо добавить import Data.Listсчетчик байтов, либо указать среду Haskell, которая включает его по умолчанию (например, изменить язык с Haskellна Haskell (lambdabot). - Некоторые советы: а) использовать шаблонную защиту для связывания переменных вместо letи / или объявления вспомогательных функций непосредственно: l=length;f s|x<-groupBy(==)s,m<-... =concatMap. б) map l xесть l<$>x, в) concatMap("++\n"есть unlines. г) groupBy(==)это просто group. е) concatесть id=<<. Вы можете использовать mтолько один раз, так встраивать его
Ними

1
... е) нет необходимости ()вокруг l y, replicate ... ' 'и map ... x. В общем и целом: import Data.List;l=length;f s|x<-group s=unlines$reverse$transpose$id=<<[[z,z]|z<-map(\y->y++replicate(maximum(l<$>x)-l y)' ')x].
Ними

1
groupBy(==)= group, хотя я не уверен, есть ли один в Prelude, а другой нет. concatMapможет быть написано >>=, и mapможет быть добавлено <$>, и concat[[z,z]|z<-…]может быть (replicate 2)=<<…или(\z->[z,z])=<<…
Bergi

Вы можете сбрить еще один байт из превосходного (\z->[z,z])(:)<*>pure...transpose$(:)<*>pure=<<map(\y...)x
nimi


1

Рубин , 116 байт

->s{a=s.scan(/(.)(\1*)/).map{|x,y|[x,y.size+1]}.to_h
m=a.values.max
m.times{|i|puts a.map{|k,v|v+i<m ?'  ':k*2}*''}}

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


puts a.map{...}можно заменить наp(a.map{})
Филипп Бартузи

pбудет выводить символы кавычек, так что это здесь не подходит
Alex

оу, спасибо Вы учитесь каждый день - stackoverflow.com/a/1255362/2047418
Филипп Бартузи


0

q / kdb +, 53 байта

Решение:

{(|)(+)(,/)(max(#:)each c)$(+)2#(,)c:((&)differ x)_x}

Пример:

 q){(|)(+)(,/)(max(#:)each c)$(+)2#(,)c:((&)differ x)_x}"BBPPPPxxGGGGKKKKKKKkkkkEEeeEEEeeEEEEEOOO8####xxXXX"
 "        KK                      "
 "        KK                      "
 "        KK          EE          "
 "  PP  GGKKkk        EE    ##    "
 "  PP  GGKKkk    EE  EEOO  ##  XX"
 "BBPPxxGGKKkkEEeeEEeeEEOO  ##xxXX"
 "BBPPxxGGKKkkEEeeEEeeEEOO88##xxXX"

Объяснение:

{reverse flip raze (max count each c)$flip 2#enlist c:(where differ x)_x} / ungolfed function
{                                                                       } / lambda function
                                                      (where differ x)    / indices where x differs
                                                                      _   / cut at these points aabbbc -> "aa","bbb","c"
                                                    c:                    / save in variable c
                                             enlist                       / put this list in another list
                                           2#                             / take two from this list (duplicate)
                                      flip                                / rotate columns/rows
                   (max count each c)                                     / find the longest run of characters
                                     $                                    / whitespace pad lists to this length
              raze                                                        / reduce down lists
         flip                                                             / rotate columns/rows
 reverse                                                                  / invert so buildings are on the ground

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.