Intercalar strings


30

Inspiração. * Não acredito que não tivemos esse desafio antes:

Tarefa

Dadas uma ou mais seqüências de caracteres ASCII imprimíveis, intercale-as usando um caractere de cada sequência, ciclicamente, até ficar sem caracteres. Se uma sequência ficar sem caracteres antes das outras, pule essa sequência a partir de então.

Exemplos

SIMPLESIMPLE

POLLSe EPEESPEOPLELESS

LYESe APRONSLAYPERSONS

ABCDEe a ce 123 567Aa1B 2Cc3D E567

"\n$?*e (string vazia) e ,(.)" (espaço à direita) fornece ",\(n.$)?"* (espaço à direita)


* Existem soluções mais curtas de APL.


Como essa é basicamente uma operação de transposição, tivemos alguns desafios muito semelhantes, mas possivelmente nenhum exatamente igual.
Martin Ender

7
Eu tinha essa pergunta no meu CS HW, isso significa que posso encerrar isso como uma pergunta de lição de casa? ; P
Downgoat 08/12/16

@EriktheOutgolfer Cool! Eu aprendi algo hoje.
Adám

Respostas:


23

Geléia , 1 byte

Z

Experimente online!

O "transpose" embutido fará exatamente isso com uma lista de strings.


Estou curioso, como seria o código se você tivesse que preencher cadeias curtas com espaços?
Adám

2
Isso seria z⁶. zé "transpor para a esquerda, preenchendo com a direita"; é um espaço.
Lynn

1
@ Adám Jelly funciona muito bem em listas; onde terminam os embutidos e as construções / design da linguagem começam?
steenbergh

1
@Lynn In Jelly? Qualquer coisa nas listas Átomos e Quicks são construídos.
Adám

2
O @ Adám ;"(concatenação por elementos) resolveria a tarefa sem um built-in.
Dennis

8

Python 2, 101 89 86 69 bytes

Espero conseguir colocar isso em um lambda de alguma forma, encurtando-o, tornando-o recursivo. Não é o ideal porque você espera que a transposição seja mais curta, infelizmente não é (pelo que eu consegui criar até agora).

f=lambda s:' '*any(s)and''.join(x[:1]for x in s)+f([x[1:]for x in s])

Soluções antigas:

w=input();o=''
while any(w):
 for i in range(len(w)):o+=w[i][:1];w[i]=w[i][1:]
print o

lambda s:''.join(''.join([c,''][c<' ']for c in x)for x in map(None,*[list(y)for y in s]))

w=input();o=''
while any(x>=' 'for x in w):
 for i in range(len(w)):o+=w[i][:1];w[i]=w[i][1:]
print o

graças a mathmandan por me fazer sentir burra;) me salvou um monte de bytes! (em uma solução antiga)


Você não poderia simplesmente fazer while any(w):? Strings vazias são falsey em Python.
mathmandan

@mathmandan Você está absolutamente certo, não sei o que eu estava pensando ..
Kade

Não tem problema :) Sua nova solução parece ótima, exceto que eu acho que você precisa anexar f=.
mathmandan

Você pode []desativar a chamada recursiva, deixando-a f(x[1:] for x in s), o que a torna uma compreensão do gerador, que age da mesma forma que uma lista nesse contexto.
Bioweasel



7

Pitão - 3 bytes

Muito simples, adicionará expansão mais tarde, no celular.

s.T

Suíte de teste

s                         Join all the strings together
 .T                       Transpose, without chopping off overhang
  (Q implicit)

4
@Daniel Também estou na escola: P
Maltysen 08/12/16

Algum plano de adicionar a explicação?
John Dvorak

@JanDvorak com certeza está fazendo isso agora.
Maltysen

6

JavaScript (ES6), 52 46 bytes

f=([[c,...s],...a])=>s+a?c+f(s+s?[...a,s]:a):c

Recebe entrada como uma matriz de sequências e saídas como uma única sequência.

Snippet de teste

f=([[c,...s],...a])=>s+a?c+f(s+s?[...a,s]:a):c

g=a=>console.log("Input:",JSON.stringify(a),"Output:",JSON.stringify(f(a)))

g(["SIMPLE"])
g(["POLLS","EPEES"])
g(["LYES","APRONS"])
g(["ABCDE","a c","123 567"])
g(["\"\\n$?*",",(.)\" "]) // Backslash and quote are escaped, but in/output are correct


f=([[c,...s],...a])=>c?c+f([...a,s]):a+a&&f(a)
Neil

@ Neil Essa é uma ótima abordagem. Eu consegui jogar 6 bytes fora do meu próprio país :-)
ETHproductions

6

Haskell, 33 bytes

import Data.List
concat.transpose

Experimente em Ideone. Uso:

Prelude Data.List> concat.transpose$["ABCDE","a c","123 567"]
"Aa1B 2Cc3D E567"

Sem usar um build-in: ( 38 34 bytes)

f[]=[]
f x=[h|h:_<-x]++f[t|_:t<-x]

Experimente em Ideone. 4 bytes de desconto graças ao Zgarb! Uso:

Prelude> f["ABCDE","a c","123 567"]
"Aa1B 2Cc3D E567"

1
Você pode remover todos os parênteses na versão alternativa. Ainda não superará a importação.
Zgarb 08/12/16

Você realmente precisa do caso base?
Xnor

Não importa, é claro que o caso base é necessário.
Xnor

@xnor Você também não pode mover o caso base para o final e substituí-lo por f a=apara salvar um byte, porque ambos []têm um tipo diferente ... tão perto.
Laikoni

5

C, 114 84 bytes

-20 bytes para não calcular o comprimento.

i,b;f(char**s){b=1;while(b){i=-1;b=0;while(s[++i]>0)if(*s[i])putchar(*s[i]++),++b;}}

Aceita matriz de ponteiros de caracteres e requer que o último item seja um ponteiro nulo (consulte o uso).

Ungolfed e uso:

i,b;f(char**s){
 b=1;
 while(b){
  i=-1;
  b=0;
  while(s[++i]>0)
   if(*s[i])
    putchar(*s[i]++),++b;
 }
}


int main(){
 char*a[]={ 
//  "POLLS","EPEES"
//  "LYES","APRONS"
 "ABCDE","a c","123 567"
 ,0};
 f(a);
 puts("");
}

O uso de printf / sprintf não é permitido? : D você ganharia alguns bytes.
Walfrat 08/12/19

@ Walfrat Sem imprimir diretamente, eu precisaria alocar uma string, então como isso poderia salvar alguma coisa.
Karl Napf

foi antes da sua edição em que você adicionou o ++ be remove a computação de comprimento, então sim não pode mais funcionar.
Walfrat

@Walfrat Sim, mas eu tinha um malloce returnantes e este foi mais do que apenas imprimir
Karl Napf

5

PHP, 68 67 bytes

for(;$f=!$k=$f;$i++)for(;y|$v=$argv[++$k];$f&=""==$c)echo$c=$v[$i];

Loops sobre argumentos de linha de comando. Corra com -r.

Após a espira interna, $fé 1quando todas as cordas são terminado, 0else (bit a bit &moldes ""==$cpara int).
Próxima iteração do loop externo: copiar $fpara $k(salva um byte de $k=0) e alternar $f:
Quando todas as strings estiverem concluídas, $fagora falsee o loop será interrompido.


Não funciona com cadeias de entrada vazias. Dê uma olhada no último caso de teste
aross

@aross: fixo. obrigado.
Titus

4

Retina , 13 bytes

A contagem de bytes assume a codificação ISO 8859-1.

O$#`.
$.%`
¶

Experimente online!

Explicação

O$#`.
$.%`

Isso é baseado na técnica de transposição padrão na Retina. Classificamos ( O) todos os caracteres sem avanço de linha ( .), por ( $#) o número de caracteres à frente deles na mesma linha ( $.%`), ou seja, sua posição horizontal.

O segundo estágio simplesmente remove os feeds de linha da entrada.


4

Java, 19 + 155 = 174 160

String f(java.util.Queue<String> q){String s,r="";while(!q.isEmpty()){s=q.poll();r+=s.isEmpty()?"":s.charAt(0);if(s.length()>1)q.add(s.substring(1));}return r;}

Ungolfed:

  String f(java.util.Queue<String> q) {
    String s, r = "";
    while (!q.isEmpty()) {
      s = q.poll();
      r += s.isEmpty() ? "" : s.charAt(0);
      if (s.length() > 1) {
        q.add(s.substring(1));
      }
    }
    return r;
  }

Saída:

SIMPLES

PESSOAS

LAYPERSONS

Aa1B 2Cc3D E567

", (n. $)?" *

Primeira modificação: declaração de string mesclada para salvar alguns bytes. Removido import, foi usado pelo main()método (não mostrado aqui) que também era necessário LinkedList. É menos bytes para referenciar Queuediretamente.


inicializar string s com string r pode economizar um pouco mais
Syamesh K:

Eu sei que já faz quase um ano, mas você pode jogar golfe com alguns bytes:String f(java.util.Queue<String>q){String s,r="";for(;!q.isEmpty();r+=s.isEmpty()?"":s.charAt(0))if((s=q.poll()).length()>1)q.add(s.substring(1));return r;}
Kevin Cruijssen 6/17

3

PHP, 77 bytes

Golfe

function($a){for($d=1;$d!=$s;$i++){$d=$s;foreach($a as$v)$s.=$v[$i];}echo$s;}

Função anônima que recebe uma matriz de seqüências de caracteres.

Tenho certeza de que isso poderia ser mais praticado, mas ainda é cedo. Em cada iteração, pegamos a i-ésima letra de cada sequência especificada e a anexamos à nossa sequência final, uma de cada vez. O PHP apenas lança avisos se acessarmos bits de strings que não existem, então tudo bem. Paramos apenas quando nenhuma alteração foi feita após repetir todas as strings uma vez.

Eu sinto que o uso de $dpode ser jogado mais, mas é cedo. : P


Como exatamente você coloca uma matriz de strings em um único argumento?
Titus

@Titus. Sabe, eu nunca pensei nisso. Eu apenas assumi que você poderia.
Xanderhall

3

Na verdade , 7 6 bytes

Sugestões de golfe são bem-vindas! Experimente online!

Edit: -1 byte graças ao pelicano Teal.

a Z♂ΣΣ

Ungolfing

          Implicit input each string.
a         Invert the stack so that the strings are in the correct order.
<space>   Get the number of items on the stack, len(stack).
Z         Zip all len(stack) strings into one, transposing them.
♂Σ        sum() every transposed list of chars into strings.
Σ         sum() again to join the strings together.

Você não pode remover o # para torná-lo em 6 bytes?
Teal pelican

@Telpelican Welp, agora vou ter que vasculhar todas as minhas respostas antigas do Na verdade e ver se não consigo mudar Z♂#Σpara Z♂Σtodas elas. Obrigado pela dica: D
Sherlock9

Pela primeira vez, olhando para o idioma, parece muito divertido! Ainda bem que pude ajudar :))
Teal pelican

3

JavaScript (ES6), 46 bytes

f=([[c,...s],...a])=>c?c+f([...a,s]):a+a&&f(a)
<textarea oninput=o.textContent=f(this.value.split`\n`)></textarea><div id=o>



2

J , 13 bytes

({~/:)&;#\&.>

Experimente online!

Com base na inspiração para esta pergunta.

Outra maneira de fazer isso leva 27 bytes, mas opera usando transposição. A maioria dos bytes deve lidar com os zeros adicionados automaticamente do preenchimento.

[:u:0<:@-.~[:,@|:(1+3&u:)&>

Explicação

({~/:)&;#\&.>  Input: list of boxed strings S
          &.>  For each boxed string x in S
        #\       Get the length of each prefix from shortest to longest
                 This forms the range [1, 2, ..., len(x)]
                 Rebox it
(    )         Operate on S and the prefix lengths
      &;         Raze both
   /:            Grade up the raze of the prefix lengths
 {~              Index into the raze of S using the grades
               Return

A proibição de J de matrizes mistas realmente o machuca aqui. Experimente no APL.
Adám

2

Utilitários Bash + GNU, 55

 eval paste `sed "s/.*/<(fold -1<<<'&')/g"`|tr -d \\n\\t

E / S via STDIN (separado por linha) e STDOUT.

O sedformata cada linha a uma substituição processo de bater . Estes são então evaleditados pastepara fazer a real intercalação. trem seguida, remove novas linhas e guias desnecessárias.

Ideone.


2

PHP, 63 bytes

Nota: usa codificação IBM-850

for(;$s^=1;$i++)for(;n|$w=$argv[++$$i];$s&=$x<~■)echo$x=$w[$i];

Execute assim:

php -r 'for(;$s^=1;$i++)for(;n|$w=$argv[++$$i];$s&=$x<~■)echo$x=$w[$i];' "\"\n\$?*" "" ",(.)\" " 2>/dev/null;echo
> ",\(n.$)?"* 

Explicação

for(                       # Iterate over string index.
  ;
  $s ^= 1;                 # Continue until $s (stop iterating) is 1.
                           # Flip $s so each iteration starts with $s
                           # being 1.
  $i++                     # Increment string index.
)
  for(
    ;
    "n" | $w=$argv[++$$i]; # Iterate over all input strings. OR with "n"
                           # to allow for empty strings.
    $s &= $x<~■            # If last character printed was greater than
                           # \x0 (all printable chars), set $s to 0,
                           # causing the loop to continue.
  )
    echo $x = $w[$i];      # Print char $i of current string.

IBM-850 ?! Isso é uma codificação natural para PHP?
Adám

@ Adám, o que você quer dizer com "natural"? O PHP trata os bytes no intervalo de 128 a 255 como texto, o que é, portanto, interpretado como uma constante. Se a constante não for definida, ela será interpretada como uma sequência. É assim que eu posso fazer ~■(negado binário 254) em vez de "\x1"(binário 1).
aross

1
Entendo. Não é que você realmente precise dessa página de código, você precisa apenas de 254 bytes.
Adám

@ Adám sim, a página de código apenas o torna um caractere imprimível, que é um pouco menos irritante.
aross

Ótimo uso de $$!
Titus

2

Python 3, 75 bytes

Eu sei que o outro Python é mais curto, mas esta é a primeira vez que usei mapna minha vida, por isso estou muito orgulhoso disso

lambda n:''.join(i[k]for k in range(max(map(len,n)))for i in n if len(i)>k)

1

C, 75 71 bytes

Apenas limitação é o comprimento da saída. Atualmente é 99, mas pode ser facilmente esticada para 999 (+1 byte).

i;main(a,b)char**b;{a--;for(;i<99;i++)*b[i%a+1]&&putchar(*b[i%a+1]++);}

Ungolfed:

i;
main( a, b )
char **b;
{
    a--;
    for( ; i < 99; i++ )
        *b[i % a + 1] && putchar( *b[i % a + 1]++ );
}

1

Oracle SQL, 195 bytes

    select listagg(b,'') within group(order by l,o) from(select substr(a,level,1) b,level l,o from i start with length(a)>0 connect by prior a=a and level<=length(a) and prior sys_guid() is not null)

Recebe sua entrada de uma tabela nomeada icom colunas a(contendo a sequência) e o(ordem da sequência):

    create table i (a varchar2(4000), a integer)

Explicação:
Estamos explorando CONNECT BYpara dividir as strings em cada um dos personagens que as compõem. PRIOR SYS_GUID()sendo NOT NULLgarante que não acabemos presos em um loop.
Em seguida, concatenamos os caracteres únicos, LISTAGGmas os embaralhamos com uma ORDER BYcláusula, ordenando-os primeiro pela posição na string original e somente depois pela string da qual eles vieram.

Não é tão curto quanto as outras respostas, mas SQL não é realmente uma linguagem de manipulação de string :)


1

Python 2, 128 96

Eu esperava não precisar usar ferramentas

a=lambda a:"".join([i for i in reduce(lambda: b,c:b+c, map(None,*map(lambda m:list(m),a)) if i])

Ungolfed

 a=lambda a:                              #Start a lambda taking in a
    "".join(                              #Join the result together with empty string
        [i for i in reduce(               #For every item, apply the function and 'keep'
           lambda: b,c:b+c,               #Add lists from...
                map(None,*map(            #None = Identity function, over a map of...
                    lambda m:list(m), a)  #list made for mthe strings m
                   ) if i                 #truthy values only (otherwise the outer map will padd with None.
       ])

Gostaria de receber feedback / aconselhamento sobre como melhorar isso.
Pureferret


1

R , 73 bytes

for(i in 1:max(nchar(s<-scan(,""))))for(j in seq(s))cat(substr(s[j],i,i))

Experimente online!

Explicação: muito simples (mas detalhada), basta percorrer a impressão do icaractere da jsequência th. Felizmente, substrretorna uma string vazia se receber uma entrada fora do intervalo.


0

Python, 112 bytes

i=len(x)if len(x)>len(y) else len(y) h=0 a="" while h<i: if h<len(x) a+=x[h] if h<len(y): a += y[h] h+=1 print a

6
Sua formatação está realmente desarrumada. De onde você chega xe yde onde?
Kade

0

Perl 5 , 53 bytes

$i=0,map{push@{$a[$i++]},$_}/./g for<>;print@$_ for@a

Experimente online!

Método

Cria uma matriz bidimensional em que o número de linhas é igual ao comprimento da string mais longa e o número máximo de colunas é igual ao número de strings. Em seguida, imprima cada linha da matriz sem espaçamento.


0

TXR Lisp , 20 bytes

(opip weave cat-str)

Corre:

1> (opip weave cat-str)
#<intrinsic fun: 0 param + variadic>
2> [*1 "LYES" "APRONS"]
"LAYPERSONS"
3> [*1 "ABCDE" "a c" "" "123 567"]
"Aa1B 2Cc3D E567"
4> [*1 "\"\\n$?*" "" ",(.) "]
"\",\\(n.$)? *"

Como a weavefunção é lenta, ela retorna uma lista, e é por isso que precisamos forçar o resultado a uma string. Por ser preguiçoso, pode tecer sequências infinitas. Por exemplo, podemos tecer os números naturais pares e ímpares, que são listas preguiçosas infinitas:

5> (take 20 (weave (range 2 : 2) (range 1 : 2)))
(2 1 4 3 6 5 8 7 10 9 12 11 14 13 16 15 18 17 20 19)

0

K (oK) , 35 29 bytes

Solução:

{`c$r@&~^r:,/+(`i$x)[;!#,/x]}

Experimente online!

Exemplo:

> {`c$r@&~^r:,/+(`i$x)[;!#,/x]}("ABCDE";"a c";"123 567")
"Aa1B 2Cc3D E567"
> {`c$r@&~^r:,/+(`i$x)[;!#,/x]}("\n$?*";"";",(.)\" ")
"\n,$(?.*)\" "
> {`c$r@&~^r:,/+(`i$x)[;!#,/x]}("POLLS";"EPEES")
"PEOPLELESS"

Explicação:

Use a indexação de segundo nível para obter índices de 0 a max (comprimento da lista nivelada) em todas as listas de entrada. Qualquer indexação além do limite da sub-lista retornará um valor nulo. Virar (gira 90), achatar e retirar os resultados não nulos.

Notas:

  • Eu converti para integer ( i$) para obter nulos úteis, pois space ( ) é considerado nulo para uma lista de caracteres, o que significa que você não pode diferenciar nulos de espaços válidos.
  • Também não consegui que o TIO trabalhasse com entrada (funcionou bem no oK repl), então o link do TIO inclui o exemplo "ABCDE" ...

0

Jq 1.5 , 49 bytes

map(explode)|transpose|map(map(values)[])|implode

Explicação

                      # example input:          ["LYES","APRONS"]
  map(explode)        # make list of ordinals   [[76,89,69,83],[65,80,82,79,78,83]]
| transpose           # zip lists               [[76,65],[89,80],[69,82],[83,79],[null,78],[null,83]]
| map(map(values)[])  # rm nulls and flatten    [76,65,89,80,69,82,83,79,78,83]
| implode             # convert back to string  "LAYPERSONS"

Sample Run

$ paste input <(jq -Mrc 'map(explode)|transpose|map(map(values)[])|implode' input)
["SIMPLE"]                  SIMPLE
["POLLS","EPEES"]           PEOPLELESS
["LYES","APRONS"]           LAYPERSONS
["ABCDE", "a c", "123 567"] Aa1B 2Cc3D E567
["\"\\n$?*", "", ",(.)\" "] ",\(n.$)?"* 

$ echo -n 'map(explode)|transpose|map(map(values)[])|implode' | wc -c
  49    

Experimente online

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.