Sobreposição de blocos de string


22

Desafio:

Dada uma lista de cadeias de linhas múltiplas, sobreponha-as (na parte superior esquerda) e produza o resultado.

Exemplo:

Entrada: ["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
Saída:

cbaa
bbaa
bbaa
aaaa

Regras do desafio:

  • O formato de entrada é flexível. Você pode obter a entrada como uma lista 2D de linhas (ou seja [["aaaa","aaaa","aaaa","aaaa"],["bb","bb","bb"],["c"]]) ou lista 3D de caracteres (ou seja [[["a","a","a","a"],["a","a","a","a"],["a","a","a","a"],["a","a","a","a"]],[["b","b"],["b","b"],["b","b"]],[["c"]]]). Você tem permissão para receber todas as entradas uma por uma através do STDIN. Etc.
  • O formato de saída é rigoroso. Você pode optar por imprimir ou retornar a sequência de várias linhas. (Se o seu idioma não tiver seqüências de caracteres, a saída como uma lista 2D de caracteres é permitida como alternativa. Mas somente se o seu idioma não possuir strings.)
  • A ordem da lista de entrada é obviamente importante (mas você pode fazer a entrada inversa, se assim o desejar).
  • As entradas conterão apenas ASCII imprimível no intervalo unicode [33,126] ( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~).
  • As entradas serão apenas retângulos (portanto, sem formas estranhas). A saída não é retângulos necessários, no entanto.
  • Espaços à direita e uma nova linha à direita são permitidos. Espaços iniciais e / ou novas linhas não.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta com as regras de E / S padrão , para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código (ou seja, TIO ).
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.

Casos de teste:

Entrada: ["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
Saída:

cbaa
bbaa
bbaa
aaaa

Entrada: ["12345\n54321","00\n00\n00\n00","001\n011\n012"]
Saída:

00145
01121
012
00

Entrada: ["sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"]
Saída:

this%^
is_a_+
testty
uiopas
t!
h_
i_
n_
g_

As novas linhas finais são permitidas? Ou, mais especificamente, é permitida uma quantidade arbitrária de novas linhas finais?
JAD 5/06

@ JAD Sim, claro, por que não. Desde que o restante seja produzido sem espaços à esquerda / novas linhas. As novas linhas / espaços à direita não são realmente importantes, portanto podem ser adicionadas opcionalmente.
Kevin Cruijssen

Respostas:


6

Geléia , 3 bytes

a/Y

Experimente online!

Não usava Jelly há algum tempo, mas achei que o desafio nos comentários era superável. Muito diretamente usa o lógico e ( a) para executar a operação de empilhamento entre cada elemento da entrada ( /). Yé usado para imprimir no formato necessário.


Ah legal! Eu sou muito ruim com Jelly tbh. Minha solução preparada foi ḷ""/Ycom uma lista de entradas invertida. Nem sabia a..
Kevin Cruijssen 04/06

11

JavaScript (Node.js) , 24 bytes

Guardado 2 bytes graças a @Grimy

Supõe que a sequência retornada seja impressa em um terminal que suporte códigos de escape ANSI . Contém o caractere não imprimível ESC, que é escapado (sem trocadilhos), conforme \x1Babaixo.

a=>`\x1B[2J\x1B[H`+a.join`\x1B[H`

Isso não funciona no TIO, mas você pode experimentá-lo online! para ver a saída bruta.

Quão?

As sequências CSI usadas são:

  • ED (apagar no visor):

    ESC[2J

    onde 2 significa "limpar a tela inteira"

  • CUP (posição do cursor):

    ESC[H

    o que significa "move o cursor para a linha n , coluna m " , onde ambos n e m são omitidos e implicitamente definida como 1 (canto superior esquerdo do ecrã).

Saída de exemplo

saída


Supondo que um terminal compatível com ECMA-48, você pode omitir ambos ;. Além disso, acho que deve ser "JavaScript + terminal" ou algo semelhante que não concorra com o JavaScript puro.
Grimmy

@ Grimy Thanks! (Para qualquer pessoa interessada, aqui está a especificação ECMA-48 - mas não encontrei onde é mencionado que o ponto-e-vírgula pode ser omitido - se é que é mencionado.)
Arnauld

1
5.4.2.h é um pouco confusa redigido, mas a parte interessante é: if the last parameter sub-string(s) is empty, the separator preceding it may be omitted. Como existem apenas duas sub-strings, o separador que precede a última substring é o único e pode ser omitido.
Grimmy

Não conheço ANSI, mas é o primeiro \x1B[H+ necessário? Ele não está começando no canto superior esquerdo por padrão e você só precisa redefini-lo após cada entrada (que é o que a junção faz)? Ou ele é iniciado inicialmente em outro lugar por padrão e você precisa explicitamente iniciar na posição do cursor para que seja redefinido com êxito nessa posição na junção?
Kevin Cruijssen 04/06

1
@ Arnauld Como você provavelmente sempre terá algo mais no terminal ao executar esta função, acho que a redefinição inicial é necessária, afinal. Quanto omitindo impressão, eu acho que f=a=>print(`\x1B[H`+a.join`\x1B[H`)com f(input_here)produziria a mesma saída print(f(input_here))? Portanto, não vejo por que você não teria permissão para omitir printe simplesmente retornar uma string.
Kevin Cruijssen 04/06

7

R , 120 , 111 110 107 bytes

function(x,`!`=ncol,M=array('',Reduce(pmax,Map(dim,x)))){for(m in x)M[1:!t(m),1:!m]=m
write(t(M),1,!M,,'')}

Experimente online!

Uma função que aceita uma lista de matriz de caracteres (entrada 3D é aceita).

(como você pode notar pela contagem de bytes, isso não é muito fácil de fazer no R ...)

  • -9 bytes graças a @Giuseppe
  • -4 bytes graças a @RobinRyder

4
Eu estava realmente esperando uma solução de mais de 200 bytes! Eu darei uma boa recompensa sempre que essa pergunta se tornar elegível à recompensa
Giuseppe

@Giuseppe: ainda é muito mais longo que em outros idiomas ... :(
digEmAll

2
111 bytes usando em arrayvez de matrix!
Giuseppe

@ Giuseppe: puro!
digEmAll

3
107 com um alias para ncol(você pode transpor para obter nrow).
Robin Ryder

5

Python 2 , 88 bytes

n,f=None,filter
for l in map(n,*input()):print''.join(f(n,x)[-1]for x in map(n,*f(n,l)))

Experimente online!


Explicação (com exemplo):

Toma uma lista 2D como entrada.

Input: [["12345","54321"],["00","00","00","00"],["001","011","012"]]

Primeiro, a lista de entrada é compactada, para obter as linhas de cada retângulo de entrada ( map(None,l)o mesmo é o maior zip):

map(n,*input())   gives:

('12345', '00', '001')
('54321', '00', '011')
(None, '00', '012')
(None, '00', None)

Cada uma dessas linhas é filtrada para se removida Nonee compactada novamente:

map(None,*filter(None,l))

filter(None,l) for each l gives:

('12345', '00', '001')
('54321', '00', '011')
('00', '012')
('00',)

map*... gives:

[('1', '0', '0'), ('2', '0', '0'), ('3', None, '1'), ('4', None, None), ('5', None, None)]
[('5', '0', '0'), ('4', '0', '1'), ('3', None, '1'), ('2', None, None), ('1', None, None)]
[('0', '0'), ('0', '1'), (None, '2')]
['0', '0']

Qual é uma lista de caracteres para cada posição do resultado desejado. Essas listas são filtradas novamente e a última é obtida:

filter(None,x)   gives:

[('1', '0', '0'), ('2', '0', '0'), ('3', '1'), ('4',), ('5',)]
[('5', '0', '0'), ('4', '0', '1'), ('3', '1'), ('2',), ('1',)]
[('0', '0'), ('0', '1'), ('2',)]
['0', '0']

and with [-1]:

['0', '0', '1', '4', '5']
['0', '1', '1', '2', '1']
['0', '1', '2']
['0', '0']

Por fim, as listas resultantes são unidas e impressas:

print''.join(..)

00145
01121
012
00

RE "Retorna uma lista de seqüências de caracteres", o estado das regras "O formato da saída é rigoroso. Você pode optar por imprimir ou retornar a sequência de várias linhas. Listas 2D ou 3D, pois as saídas não são permitidas.". O programa completo de 88 bytes parece bom
Jonathan Allan

@JonathanAllan, welp, eu interpretei mal a saída estrita (ou esqueci?: P)
TFeld

5

R, 107 97 bytes

function(x)for(i in 1:max(lengths(x))){for(m in x)if(i<=length(m))cat(m[i],'\r',sep='');cat('
')}

Não parece funcionar no TIO, o que pode estar relacionado ao uso do \rcaractere de retorno de carro. Ele funciona na minha instalação local do R.

Recebe entrada como uma lista que contém um vetor de linhas:

x <- list(c("aaaa","aaaa","aaaa","aaaa"),c("bb","bb","bb"),c("c"))

Faz um loop nas linhas de cada retângulo, imprimindo um retorno de carro após cada um, reiniciando a linha.

Se esticarmos um pouco as regras, podemos acabar com a verificação do comprimento da entrada e fazer um loop infinito, imprimindo uma enorme quantidade de novas linhas:

R, 85 bytes

function(x)for(i in 1:8e8){for(m in x)if(i<=length(m))cat(m[i],'\r',sep='');cat('
')}

106 bytes É bom ver você jogando golfe aqui e ali!
Giuseppe

Possivelmente 97 bytes ; não está claro se isso realmente funciona, pois estou testando apenas no TIO
Giuseppe

@Giuseppe Hi! Sua sugestão funciona para mim. Se nos é permitido imprimir novas linhas à direita, também é possível usar um loop for arbitrariamente grande, mas acho que isso está forçando os limites do desafio.
JAD 5/06

@JAD: ótima idéia de usar \re bem-vindo de volta! Apenas uma observação, acho que isso funciona apenas em sessões interativas R (quando interactive()retorna verdadeiro)
digEmAll

@digEmAll Funciona na minha máquina usando a rscriptpartir da linha de comando. Eu suspeito que é uma coisa do Windows / Linux, já que o Windows usa \r\npara novas linhas e Linux \n.
JAD 6/06

4

APL (Dyalog Unicode) , SBCS de 22 bytes

Função de prefixo tácito anônimo, tendo como argumento a lista de matrizes de caracteres 2D. Imprime.

(⊃{⍺@(⍳⍴⍺)⊢⍵}/)⌽,∘⊂1⌷↑

Experimente online!

Isso funciona criando uma tela, anexando-a à lista de blocos e reduzindo (dobrando) com uma função que coloca os blocos no canto.

 misture o bloco 2D para criar um bloco 3D ortogonal, preenchendo-o com espaços conforme necessário

1⌷ pegue a primeira camada

 coloque que, em
 seguida,
⌽, anexe a lista invertida de blocos

() Aplique a seguinte função tácita:

{}/ Reduza usando a seguinte lambda anônima:

  ⊢⍵ com o argumento certo como tela ...

  ⍺@() Altere com os elementos do argumento esquerdo, colocados nos seguintes índices:

   ⍴⍺ a forma do argumento esquerdo

    os índices de uma matriz dessa forma

 divulgar (porque a redução incluía para reduzir a classificação)


4

Haskell, 66 bytes

unlines.foldl((const?)?)[]
(g?(a:b))(c:d)=g a c:(g?b)d;(_?a)b=a++b

A entrada é feita como uma lista de lista de strings em ordem inversa, por exemplo, para o primeiro caso de teste: [["c"],["bb","bb","bb"],["aaaa","aaaa","aaaa","aaaa"]].

Experimente online!


3

05AB1E , 12 bytes

Porta da solução python do TFeld
2 bytes salvos graças ao Grimy

ζεðKζðδK€θJ,

Experimente online!

Explicação

ζ             # transpose input with space as filler
 ε            # apply to each
  ðK          # remove spaces
    ζ         # transpose with space as filler
     ðδK      # deep remove spaces
        €θ    # get the tail of each
          J   # join each
           ,  # print

Versão alternativa de 14 bytes

õζεÅ»DŠg.$J}θ,

Experimente online!

Explicação

õζ              # zip with empty string as filler
  ε             # apply to each
   Å»      }    # cumulative reduce by
     D          # duplicate second input
      Š         # move down twice on stack
       g.$      # remove len(other_copy) elements from the other input
          J     # join with other copy
            θ,  # print the last element

1
Ah, lembre-se de que --no-lazyé a correção para ainda usar um mapa / filtro com impressão para o implícito y, para salvar um byte em comparação com vy...,:) Eu sabia que funcionava na versão herdada, mas na nova versão também geraria o [...]. Não sabia que isso era devido à falta de --no-lazy. ;) Quanto à resposta em si, muito legal! Eu sabia que era necessária uma redução cumulativa, mas não consegui resolver o problema quando tentei. Você faz parecer tão fácil ..
Kevin Cruijssen 04/06

Eu o tinha mencionado nas regras, mas esqueci de aplicá-lo aos casos de teste .., mas os espaços não estarão na entrada. Portanto, você provavelmente pode salvar alguns bytes lá, já que o zip-filler é um espaço por padrão. (Não tenho certeza se isso salva alguma coisa na sua primeira resposta, mas no porto que pode.)
Kevin Cruijssen

2
õζεõKpode ser ζεðK, õζõδKpode ser ζðδK.
Grimmy

@ Grimy: Ah, sim, os espaços não podem mais estar na entrada. Obrigado!
Emigna 04/06



2

PowerShell 6 , somente console, 20 bytes

com base na resposta de Arnauld . Isso funciona apenas com console e não funciona no TIO.

cls
$args-join"`e[H"

Experimente online!


PowerShell , 103 bytes

$args|%{$l=$_-split'
';$r=&{$r+($l|%{''})|%{($x=$l[$j++])+($_-replace"^.{0,$("$x"|% Le*)}")}|?{$_}}}
$r

Experimente online!

Desenrolado:

$args|%{
    $l=$_-split"`n"
    $r=&{                           # run this scriptblock in a new scope
        $r+($l|%{''})|%{
            $x=$l[$j++]             # a new line or $null
            $w="$x"|% Length
            $y=$_-replace"^.{0,$w}" # remove first chars from the current line
            $x+$y                   # output the new line plus tail of the overlapped line
        }|?{$_}                     # filter out not empty lines only
    }                               # close the scope and remove all variables created in the scope
}
$r


1

Ruby , 67 bytes

Entrada é uma lista de linhas. Cria uma lista de linhas e sobrescreve à medida que passa pelas entradas e as junta a uma nova linha (representada pela variável $/) no final para corresponder à saída estrita.

->i,*r{i.map{|e|j=-1;e.map{|l|r[j+=1]||='';r[j][0,l.size]=l}};r*$/}

Experimente online!


1

C (GCC, MinGW) 138 bytes

Supõe que CR coloca o cursor no início da linha atual.

d,i,l;f(S,n,p,t)char**S,*p,*t;{for(d=i=0;i<n;d+=l)p=strchr(t=S[i],10),printf("\n%.*s\r"+!!i,l=p?p-t:strlen(t),t),S[i++]+=l+!!p;d&&f(S,n);}

Testado com:

int main()
{
    char *test1[] = {"aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"};
    char *test2[] = {"12345\n54321","00\n00\n00\n00","001\n011\n012"};
    char *test3[] = {"sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"};

    f(test1, 3);
    f(test2, 3);
    f(test3, 3);
}


1

Javascript (navegador) , 216 208 204 bytes

Minha tentativa nisso. Não estou feliz com o tamanho e certamente deve haver mais para melhorar, mas não sou tão experiente no golfe.

var n='\n',x=s=>s.split``.reverse().join``,i,j,f=a=>a.map(s=>s.split(n).map(y=>x(y))).reduce((a,b)=>{for(i=0;i<b.length;i++){j=a[i];if(!j)j=b[i];a[i]=b[i].padStart(j.length,j)}return a}).map(s=>x(s)).join(n)

De qualquer forma, o que ele faz é primeiro dividir todas as strings, depois reverter todas as strings e, em seguida, girar em um bloco de operação reduzido . Em seguida, inverta todas as seqüências novamente e junte-as novamente com novas linhas.

Um agradecimento especial a Kevin Cruijssen por me lembrar que a última parte de um loop for acontece no final e uma economia total de bytes de 8 bytes.

var n='\n',x=s=>s.split``.reverse().join``,i,j,f=a=>a.map(s=>s.split(n).map(y=>x(y))).reduce((a,b)=>{for(i=0;i<b.length;a[i]=b[i++].padStart(j.length,j))if(!(j=a[i]))j=b[i];return a}).map(s=>x(s)).join(n)

console.log(f(["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]));
console.log(f(["12345\n54321","00\n00\n00\n00","001\n011\n012"]));
console.log(f(["sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"]));


1
Ambos ('')podem ser dois `para salvar quatro bytes :) '
Kevin Cruijssen

1
Além disso, você pode substituir o for(i=0;i<b.length;i++){j=a[i];if(!j)j=b[i];a[i]=b[i].padStart(j.length,j)}por for(i=0;i<b.length;a[i]=b[i++].padStart(j.length,j))if(!(j=a[i]))j=b[i];.
Kevin Cruijssen

1
O jprimeiro é atribuído com (j=a[i]), a instrução if é concluída com if(!...)j=b[i];(onde ...está o (j=a[i])valor atualizado de j) e, em seguida, ;a[i]=b[i++].padStart(j.length,j))é feita no final da iteração do loop for. Não tenho certeza de onde está o problema e parece funcionar?
Kevin Cruijssen

1
ooohhh .... * olhos grandes * que desbloquearam algo
Tschallacka

1
Btw, se você ainda não os viu, dicas para jogar golfe em <todos os idiomas> e dicas para jogar golfe em JavaScript podem ser interessantes para ler. :)
Kevin Cruijssen

1

C (gcc) , 51 47 bytes

f(char**s){for(;*s;printf("\e[s%s\e[u",*s++));}

Experimente online!

-4 bytes graças ao ceilingcat.

Usa as seqüências CSI para salvar / restaurar a posição do cursor. Apenas itera sobre a matriz de cadeias passadas (no mesmo formato que argv) e imprime <save position>string<restore position>para cada uma.

Isso deixa o cursor no canto superior esquerdo; portanto, ao executar no terminal, é importante deixar novas linhas suficientes posteriormente para que o prompt não atrapalhe a entrada.


1

Japt -P , 7 bytes

Recebe a entrada como uma matriz de seqüências de várias linhas, produz uma única sequência de várias linhas.

ú y_¸¬Ì

Tente

ú y_¸¬Ì     :Implicit input of array
ú           :Right pad each line of each element with spaces to the length of the longest
  y         :Transpose
   _        :Map
    ¸       :  Split on spaces
     ¬      :  Join
      Ì     :  Last character
            :Implicitly join and output

1

Consulta T-SQL, 297 295 bytes

Usando ¶ como separador e uma variável de tabela como entrada.

DECLARE @ table(a varchar(max),k int identity(1,1))
INSERT @ values('aaaa¶aaaa¶aaaa¶aaaa'),('bb¶bv¶bb'),('c');

WITH c as(SELECT k,row_number()over(partition
by k order by k)s,value v FROM @ CROSS APPLY
string_split(a,'¶')s),m(i,l,e)as(SELECT*FROM c
WHERE k=1UNION ALL
SELECT k,s,STUFF(e,1,len(v),v)FROM m
JOIN c ON-~i=k and s=l)SELECT
top 1with ties e FROM m
ORDER BY rank()over(partition by l order by-i)

Experimente online


1

Javascript (navegador), 129 124 bytes

Minha primeira tentativa no código de golfe. Eu li os links fornecidos nas regras (brechas, regras padrão ...), então espero ter feito algo errado!


Eu mantive as entradas como estão no primeiro post (formulário de matriz plana).

_=o=>{o=o.map(i=>i.split`\n`),r=o.shift();for(a of o)for(l in a)b=a[l],r[l]=r[l]?b+r[l].slice(b.length):b;return r.join`\n`}

Obrigado a Kevin Cruijssen por salvar 5 bytes.


Testes:


1
Bem-vindo ao PPCG! Ótima primeira resposta, +1 de mim. Algumas pequenas coisas para o golfe: for(a of o){for(l in a){b=a[l],r[l]=(r[l])?b+r[l].slice(b.length):b}}pode ser for(a of o)for(l in a)b=a[l],r[l]=r[l]?b+r[l].slice(b.length):b;:)
Kevin Cruijssen

1
@KevinCruijssen - Obrigado, atualizei meu post! Eu li esses dois guias antes de postar, eles foram úteis. Mas possivelmente sinto falta de alguns truques que poderiam melhorar ainda mais minha tentativa!
Kévin Bibollet

1
Uma outra coisa do meu primeiro comentário que você perdeu é o parêntese em torno do =(r[l])?qual pode ser removido para =r[l]?:)
Kevin Cruijssen 12/06

1
@ KévinBibollet, é necessário para retornar o resultado final de r. Sem ele, o resultado do mapeamento seria retornado.
Shaggy

1
Porém, se você deseja manter o formato de E / S usado nos casos de teste, ainda é possível diminuir para 85 bytes, mas observe que a E / S é flexível.
Shaggy

1

Pitão , 18 bytes

L.tb0VyQsme #dy #N

Experimente online!(nota: o próprio código avalia apenas um bloco, o modo de suíte de testes do intérprete executa o programa uma vez para cada linha de entrada)

Baseado na solução Python 2 da TFeld .

Explicação:

L.tb0         # define a lambda function called y which does a transpose, padding with integer 0's
VyQ           # loop over transposed first input line (Q = eval(input()) ) (loop index = N)
   s          # concatenate array of strings (implicitly printed)
    m         # map over
         y #N # transpose of non-falsy values of N
     e        # for each item: last element of array
       #d     # relevant space at the start! filter with identity function, removes falsy values

para uma explicação de por que o próprio algoritmo funciona, consulte a resposta do TFeld.


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.