Construa-me uma cidade


34

Os codificadores estão sempre tentando achatar matrizes em entediantes entidades unidimensionais e isso me deixa triste.

Sua tarefa é desfazer uma seqüência arbitrária de caracteres, produzindo uma linda paisagem da cidade.

Considere a string: aaabbbbbccqrrssstttttttPPw

Parece muito melhor assim:

            tt
            tt
  bb        tt
  bb        tt
aabb      sstt
aabbcc  rrssttPP
aabbccqqrrssttPPww

(Ok, sim, as letras são duplicadas para parecer mais com o horizonte da cidade).

Pegue uma string de entrada, duplique cada subseção de caracteres correspondentes (não necessariamente letras alfabéticas) e construa-me uma cidade!

Os bytes de código mais curto ganham.

Na verdade, eu pensei que tinha os requisitos acertados, mas para responder a algumas perguntas:

  • deve estar no chão
  • você pode ter céu extra, se quiser (linhas em branco à esquerda, espaço em branco ao redor) - mas não entre os prédios
  • as letras podem ser reutilizadas dentro da string (mesma arquitetura, local diferente)
  • presume-se que as letras sejam ASCII, mas será dado um toque maior àqueles que suportam codificações adicionais (UTF8, etc.)

3
Podemos produzir a paisagem urbana girada 90 graus?
Okx 27/06

6
Os personagens se repetirão novamente, ou seja aaabbbbaa?
TheLethalCoder

14
@ Ok, você já viu uma cidade girar 90 graus, que pareceria muito boba! ;)
Tom

7
Rod

10
Bem-vindo ao site! Para desafios futuros, recomendo publicá-los primeiro na Sandbox, onde você pode obter feedbacks da comunidade antes de publicá-los como um desafio.
Dada

Respostas:


11

05AB1E , 6 bytes

γ€DζR»

Experimente online!

Em uma versão mais recente que o desafio, ζfoi adicionada como uma substituição para.Bø

05AB1E , 8 bytes

γ€D.BøR»

Explicação:

γ            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

Experimente online!


1
Curiosamente, Jelly tem z⁶para .Bø... mas também Œgx'2para γ€D> _>
Erik the Outgolfer

γ.BD)ø˜øR»era o que eu tinha sem olhar, €Dé muito melhor; No entanto, sinto que estamos perdendo a solução de 1 byte para duplicação em linha.
Magic Octopus Urn

3
@MagicOctopusUrn Espere, você resolveu o desafio sem sequer olhar para ele?
Okx

@ Ok Bem, é aconselhável não olhar para as respostas antes, já que toda a diversão de jogar golfe pode ser interrompida.
Erik the Outgolfer

@EriktheOutgolfer Era uma piada, e o que eu quero dizer é que ele resolveu isso sem olhar para o conteúdo do desafio.
Okx 29/06

6

CJam , 23 bytes

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

Experimente online!

Explicação:

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

Uau, uma resposta CJam> _>
Sr. Xcoder

6

Geléia , 9 bytes

Œgx'2z⁶ṚY

Experimente online!

Explicação:

Œ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
Você poderia adicionar uma explicação, por favor, milord? Não consigo entender o que está acontecendo aqui: o
Nathan


@HyperNeutrino Nice explanation ... #
31517 Erik the Outgolfer

Só para ter certeza, está correto? : P
HyperNeutrino 27/06

@HyperNeutrino Bem, não era exatamente essa a intenção ', que era repetir as listas em si e não os itens dentro delas, mas no geral é bom. :)
Erik the Outgolfer

6

Python 3 , 155 136 134 132 bytes

-19 bytes graças a @LeakyNun
-2 bytes graças a @officialaimm
-1 byte graças a @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='')

Experimente online!



5

Java 8, 412 400 330 324 312 319 bytes

-6 bytes graças ao VisualMelon
-12 bytes graças a Kevin Cruijssen
mas +19 bytes porque esqueci de incluir as importações na contagem de bytes.

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);}}}

Experimente online!


1
Jogar golfe em Java e C # (meu departamento) é muito divertido! Continue nisso! Não testado, mas acho que você pode salvar alguns bytes, rejeitando os loops for: você pode pré-atribuir i=0, ou melhor i=l, e fazer a contagem regressiva for(;i-->0;h=d>h?d:h)(e colocar a parte de h=dentro). A mesma contagem regressiva também funcionará para o loop interno. O interior iftambém não precisa dos aparelhos {}. E esteja sempre cansado <=ou >=, você pode mudar o ternário >e salvar um byte.
VisualMelon

Obrigado, eu poderia remover outros 6 bytes do código, graças às suas dicas. Bem, acho que vou ficar com o Java Golfing, já que realmente gosto;).
Twometer 28/06

1
Bem-vindo ao PPCG! Receio que você precise aumentar a contagem de bytes para 329 (+19 bytes devido ao necessário import java.util.*;para Mape HashMap, as importações fazem parte da contagem de bytes; e -1 removendo o ponto e vírgula à direita, o que não é parte da contagem de bytes).
Kevin Cruijssen


1
Resumo das alterações: HashMap<>HashMap; Map n=,ne n=; m.put(c,d=m.get(c)!=null?d+1:1);dentro do loop for para se livrar dos suportes; k=x.charAt(i)dentro do if(n.get(k)!=null)para se livrar dos suportes de ponto e vírgula e de loop for. Mais uma vez, bem-vinda e ótima resposta! +1 de mim. Além disso, caso você ainda não tenha visto: Dicas para jogar golfe em Java e Dicas para jogar em <qualquer idioma> podem ser interessantes para ler.
Kevin Cruijssen

5

Japt , 19 18 15 13 12 bytes

Inclui espaços à direita em cada linha.

ò¦
íU c ·z w

Teste-o


Explicação

         :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 bytes

(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 bytes

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),,'')

Experimente online!

lê de stdin, grava em stdout (com uma nova linha à direita).

Explicação:

  • rle encontra os comprimentos das faixas de caracteres, as alturas de cada torre.
  • a subexpressão substitui cada caractere por seu duplo (então eu não precisei mexer com a definição de índices adjacentes)
  • sapply retorna uma matriz (neste caso, uma matriz):
    • sum(e$l|1)é o número de caracteres distintos; vamos de cima para baixo
    • ifelse( ... )é um vetorizado if...elseque nos permite construir uma matriz de torres e espaços duplos
    • write grava no console, com algumas opções para formatar.



2

MATL , 15 bytes

'(.)\1*'XXtvc!P

Experimente online!

Explicação

'(.)\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

Carvão , 40 bytes:

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

Experimente online! Link é a versão detalhada do código. Inicialmente, tentei um loop simples sobre a string de entrada para imprimir um oblongo toda vez que a letra era alterada, mas mudei para esse método de criação de lista, pois economizava 5 bytes. Explicação: A variável lcontém uma lista aninhada das letras de entrada. Os caracteres que correspondem aos últimos elementos da lista atual são empurrados para a última lista, caso contrário, uma nova sublist é criada para esse personagem. Resta então juntar as letras em cada sub-lista para que elas possam ser impressas verticalmente duas vezes.


2

C, 259 231 bytes

Código de golfe

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

Código detalhado

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

}

Compilado com o GCC, sem sinalizadores especiais

Editar

Economizou 28 bytes graças a adelphus. Sua mudança me permitiu criar uma definição. E eu fiz os loops while em loops para economizar 2 bytes cada, reorganizando o loop. Também corrigi um problema em que o código seria interrompido quando o último caractere na entrada não fosse singleton. O código falhará se houver apenas uma letra exclusiva, mas deve funcionar em todos os outros casos.


Agradável! Mas a versão golfed não parece funcionar com dados arbitrários por algum motivo. A remoção do "w" final da entrada de amostra parece perder os qs e repetir a sequência. Claro que é algo pequeno ...
adelphus

também while (i < strlen(argv[1]))pode ser reduzido para while (argv[1][i])- loop até o caractere nulo
Adelphus

@adelphus Interessante, vou experimentar amanhã quando tiver uma chance. Não testei nada além do caso de teste fornecido (preguiçoso eu sei).
dj0wns

Isso realmente ajudou muito, consegui resolver o problema e reduzir em quase 30 bytes!
dj0wns

1

Pip , 22 bytes

21 bytes de código, +1 para -lsinalizador.

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

Experimente online!

Explicação

                       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 bytes

+1 byte para o 1sinalizador.

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

Experimente online!

⊖⍵ pós-processo virando de cabeça para baixo

(.)\1* execuções de caracteres idênticos

2/⍪⍵M duplicar o M atch coluna

O 1sinalizador faz com que os resultados sejam mesclados.


1

Haskell, 144 bytes

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

Estou bastante confiante de que posso fazer melhor do que isso, mas é o melhor que posso encontrar por enquanto.


1
Más notícias primeiro: você usa funções das Data.Listquais não está no escopo por padrão. Você deve adicionar a import Data.Listcontagem de bytes ou especificar um ambiente Haskell que o inclua por padrão (por exemplo, alterar o idioma de Haskellpara Haskell (lambdabot). - Algumas dicas: a) usar guardas de padrão para vincular variáveis ​​em vez de lete / ou declarar funções auxiliares diretamente: l=length;f s|x<-groupBy(==)s,m<-... =concatMap. b) map l xé l<$>x, c) concatMap("++\n"é unlines. d) groupBy(==)é justo group. e) concaté id=<<. Você pode usar mapenas uma vez, de modo inline
nimi

1
... f) não há necessidade de ()passear l y, replicate ... ' 'e map ... x. Todos em todos: 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].
N /

1
groupBy(==)= group, embora eu não tenha certeza se um está no Prelude e o outro não. concatMappode ser escrito >>=, e mappode ser infixado como <$>, e concat[[z,z]|z<-…]pode ser (replicate 2)=<<…ou(\z->[z,z])=<<…
Bergi

Você pode raspar mais um byte de @ excelente dica de Bergi: (\z->[z,z])é (:)<*>pure, ou seja,...transpose$(:)<*>pure=<<map(\y...)x
nimi




0

q / kdb +, 53 bytes

Solução:

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

Exemplo:

 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"

Explicação:

{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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.