Побудуй мені місто


34

Кодери завжди намагаються згладити масиви в нудні одновимірні сутності, і це мені сумно.

Ваше завдання - розкрутити довільну рядок символів, вивівши чудовий міський небосквіт.

Розглянемо рядок: aaabbbbbccqrrssstttttttPPw

Це виглядає набагато краще так:

            tt
            tt
  bb        tt
  bb        tt
aabb      sstt
aabbcc  rrssttPP
aabbccqqrrssttPPww

(Гаразд, так, букви дублюються, щоб зробити вигляд міста більше-на горизонті).

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

Виграють найкоротші коди байтів.

Насправді я думав, що я маю вимоги, але я відповів на деякі запитання:

  • вона повинна бути на землі
  • Ви можете мати додаткове небо, якщо хочете (провідні порожні лінії, навколишній порожній простір), але не між будівлями
  • літери можуть бути повторно використані всередині рядка (та ж архітектура, інше розташування)
  • літери вважаються ASCII, але більше чуттів буде надано тим, хто підтримує додаткові кодування (UTF8 тощо)

3
Чи можемо ми вивести міський пейзаж, повернутий на 90 градусів?
Окс

6
Чи повторюватимуться персонажі, тобто aaabbbbaa?
TheLethalCoder

14
@Oxx Ви коли-небудь бачили, як місто повертається на 90 градусів, це виглядало б дуже нерозумно! ;)
Том


10
Ласкаво просимо на сайт! Для майбутніх проблем я рекомендую опублікувати їх спочатку в пісочниці, де ви можете отримати відгуки від спільноти, перш ніж публікувати це як виклик.
Дада

Відповіді:


11

05AB1E , 6 байт

γ€DζR»

Спробуйте в Інтернеті!

У новій версії, ніж виклик, ζдодано як заміну для fo.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> _>
Ерік the Outgolfer

γ.BD)ø˜øR»було те, що я мав, не дивлячись, €Dчи так краще; Я відчуваю, що ми обидва пропускаємо 1-байтове рішення для вбудованого дублювання.
Чарівний восьминога Урна

3
@MagicOctopusUrn Зачекайте, ви вирішили завдання, навіть не дивлячись на нього?
Okx

@ Okx Ну, розумно не дивитись на відповіді раніше, оскільки вся забава від гольфу в ньому сама може бути відрізана.
Ерік Аутгольфер

@EriktheOutgolfer Це був жарт, і я маю на увазі те, що він вирішив це, не дивлячись на зміст виклику.
Оккс

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
Чи можете ви додати пояснення, будь ласка, господарю? Я не можу зрозуміти, що тут відбувається: o
Натан


@HyperNeutrino Приємне пояснення ...
Ерік Переможник

Просто для впевненості, чи правильно? : P
HyperNeutrino

@HyperNeutrino Добре, що це було не зовсім наміром ', яке полягало в повторенні самих списків, а не предметів всередині них, але в цілому це добре. :)
Erik the 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

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

-6 байт завдяки VisualMelon
-12 байт завдяки Kevin Cruijssen,
але +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 # (мій відділ) - це велике задоволення! Тримайте це! Не перевірено, але я думаю, що ви можете зберегти кілька байт шляхом повторного переміщення циклів для циклів: ви можете попередньо призначити 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, видаливши крапку з двокрапкою, яка не є частина підрахунку байтів).
Kevin Cruijssen


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 від мене. Крім того, якщо ви цього ще не бачили: Поради щодо гольфу на Яві та Поради щодо гольфу на будь-якій мові можуть бути цікавими для прочитання.
Kevin Cruijssen

5

Japt , 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

Математика, 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),,'')

Спробуйте в Інтернеті!

читає з stdin, записує в stdout (із заднім рядком).

Пояснення:

  • 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 для циклів, щоб зберегти по 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 дублювати columnified 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
... f) немає потреби ()навколо 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, хоча я не впевнений, чи є один у Прелюдії, а другий - ні. 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буде виводити символи цитат, тому це не підходить сюди
Алекс

о, уа, дякую. Ви дізнаєтеся , повсякденне - stackoverflow.com/a/1255362/2047418
Filip Bartuzi


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.