Golfe um twister de corda

24

Como as cordas são torcidas

O algoritmo de torção é muito simples. Cada coluna é deslocada para baixo pelo seu índice (col 0 desce 0, col 1 move 1, ...). A mudança de coluna envolve o topo. Funciona assim:

aaaa
bbbb
cccc

Torna-se:

a
ba
cba
----
 cba
  cb
   c

Com tudo sob a linha de embalagem para o topo. Exemplo real:

Original:
\\\\\\\\\\\\
............
............
............

Twisted:
\...\...\...
.\...\...\..
..\...\...\.
...\...\...\

Entrada

A entrada é uma matriz de cadeias ou uma cadeia de linhas múltiplas. Todas as linhas têm o mesmo comprimento.

Saída

A corda torcida, saída de várias linhas para saída padrão (ou alternativa mais próxima).

Exemplos:

( >indica entrada, o espaço à direita é importante)

>Hello, world!
>I am another 
>string to be 
>twisted!     

Hwrmoe oo br!
Ieii ,dttr e 
s lsna !ohl  
ttaltgnw  ed 


>\\\\\\\\\\\\
>............
>............
>............

\...\...\...
.\...\...\..
..\...\...\.
...\...\...\


>abcdefg
>.......

a.c.e.g
.b.d.f.


>abcdefghij
>..........
>..........

a..d..g..j
.b..e..h..
..c..f..i.


>\\\\.....././
>...../.......
>........././.
>..../.^\\....

\.........../
.\....^..../.
..\../.\../..
...\/...\/...

>cdeab
>deabc
>eabcd
>abcde

cbbbb
ddccc
eeedd
aaaae


>aeimquy37
>bfjnrvz48
>cgkosw159
>dhlptx260

ahknqx147
beloru258
cfipsvy69
dgjmtwz30


>abcdefghi
>jklmnopqr
>stuvwxyz1
>234567890

a3ume7yqi
jb4vnf8zr
skc5wog91
2tld6xph0
J Atkin
fonte
12
É melhor não haver um Mathematica embutido para isso.
Mama Fun Roll
11
Podemos assumir que a entrada conterá apenas ASCII? Ou apenas linhas de impressão ASCII + ou algo assim?
Martin Ender
Sim, apenas ASCII e nova linha (a menos que você aceite a entrada como uma matriz).
111716 JJ

Respostas:

3

Braquilog , 5 bytes

iᵇ↻₎ᵐ

Experimente online!

Obtém entrada como uma matriz de colunas (que parece estar dentro das especificações da pergunta).

iᵇ- Para cada elemento da matriz, emparelhe-o com seu índice (com base em 0)
- mapeie esse predicado para cada elemento do resultado:
↻₎- permita (a coluna) circularmente pela quantidade especificada como o último elemento (o índice)

Facilmente estendido para uma versão que aceita uma única sequência de múltiplas linhas:

13 bytes

ṇẹ\iᵇ↻₎ᵐ\cᵐ~ṇ

Experimente online!

sundar - Restabelecer Monica
fonte
Isso é incrível compactação de informações.
J Atkin
7

Pyth, 11

jC.>R~hZC.z

Experimente aqui

jC.>R~hZC.z    ##  implicit: .z = list of input split by lines
        C.z    ##  transpose .z to get columns
  .>R~hZ       ##  shift each column by it's index
               ##  equivalent to .e.>bk
jC             ##  transpose back and join by newlines
FryAmTheEggman
fonte
7

APL (Dyalog) , 7 bytes

⊖⊖⊖⍨⍬⍋⍉

Requer ⎕io←0

Experimente online!

⍬⍋⍉obtém o intervalo de 0 ao número de colunas
invertidas,
⊖⊖⍨⍬⍋⍉gira verticalmente (verticalmente) a entrada (verticalmente) invertida e 0,1..
inverte isso e retorna-a.

H.PWiz
fonte
6

Retina , 111 101 92 87 bytes

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

(?<=((.))*)(?=(?<1>.*¶)*.*(?<=(?=(?<-2>.)*(.))(?<-1>.+¶)*.*(.(?<=^(?<-1>¶?.+)*))*)).
$3

Woo, resolveu-o em uma única substituição de regex. :) (As chances são de que haja uma solução mais curta usando várias, mas onde está a graça nisso ...)

Experimente online!

Explicação

Isso requer algum conhecimento básico de grupos de equilíbrio . Em resumo, o sabor regex do .NET permite capturar várias vezes com um único grupo, colocando todas as capturas em uma pilha. Essa pilha também pode ser removida, o que nos permite usá-la para contar coisas dentro do regex.

(?<=((.))*)

Isso envia uma captura para os dois grupos 1e 2para cada personagem na frente da partida (na linha atual). Ou seja, conta a posição horizontal da partida.

O resto está em um lookahead:

(?=(?<1>.*¶)*.* [...] )

Combinamos cada linha e também a empurramos para o grupo 1, de modo que o grupo 1agora é a soma da posição horizontal e vertical (onde a última é contada a partir da parte inferior ). Basicamente, isso rotula as diagonais da grade com valores crescentes começando no canto inferior esquerdo. Isso .*apenas move o cursor do mecanismo para o final da string.

Agora, passamos a um lookbehind, que corresponde da direita para a esquerda no .NET:

(?<= [...] (.(?<=^(?<-1>¶?.+)*))*)

Isso irá aparecer repetidamente exatamente Hcapturas do grupo 1(onde Hestá a altura da entrada). O objetivo disso é pegar o módulo do grupo H. Posteriormente, o grupo 1contém a linha (contada na parte inferior) a partir da qual escolher o novo caractere na coluna atual.

(?=(?<-2>.)*(.))(?<-1>.+¶)*.*

Outro olhar para trás, novamente a partir da direita. (?<-1>.+¶)*.+agora usa group 1para encontrar a linha na qual escolher o novo caractere e, em seguida, o lookahead encontra a coluna correta usando group 2.

O caractere desejado é capturado em grupo 3e gravado de volta pela substituição.

Martin Ender
fonte
Ah, lendo fonte de Retina era bom e claro :) $+parece útil ... especialmente se você só quer fazer uma substituição: ^)
FryAmTheEggman
@FryAmTheEggman $+é realmente muito inútil ... a sua inscrição no MSDN soa muito mais útil do que é porque isso implica que (a)|(b)-> $+$+dobraria todos os as e bs mas em vez disso ele remove todos as, porque ele só se refere ao sintaticamente último grupo . Isso significa que é apenas uma maneira de evitar contar todos os grupos se você for muito preguiçoso (como eu). Para jogar golfe, ele salva apenas bytes quando você tem mais de 9 grupos, o que provavelmente é bastante raro para começar.
Martin Ender
Isso é lamentável ... Talvez a retina possa ter um novo tipo de grupo de substituição que retorne o último grupo de correspondência não vazio? De qualquer forma, obrigado pela explicação! :)
FryAmTheEggman
@FryAmTheEggman Será (é uma das coisas que eu tinha em mente quando reescrevi Regex.Replacepara o Retina, mas ainda não consegui implementá-lo).
Martin Ender
4

CJam, 13 bytes

qN/zee::m>zN*

Teste aqui.

Explicação

q    e# Read all input.
N/   e# Split into lines.
z    e# Transpose to get an array of columns.
ee   e# Enumerate, pairing each column with its index.
::m> e# Map: fold: rotate (cyclically shifting each column by its index).
z    e# Transpose again.
N*   e# Join with linefeeds.
Martin Ender
fonte
2
Você quase pode pronunciar esse código fonte.
#
4

TeaScript, 10 bytes

xHl@C(r╢tD

Graças à sintaxe extremamente concisa do TeaScript 3, isso é realmente curto: D

Seria 1 byte mais curto se o loop Sigma não estivesse com erros

Experimente online

Explicação

      // Implicit, x = input
xH    // Transpose input
l@    // Loop
 C(r╢   // Cycle column by index
        // `╢` exits loop
t    // Transpose
D    // Join on \n
Downgoat
fonte
3

Python 3, 164 bytes

Não é a melhor resposta, mas a primeira em Python ...

s=list(zip(*open(0).readlines()))[:-1]
r=[[s[i][(j-i)%len(s[i])] for j in range(len(s[i]))] for i in range(len(s))]
print('\n'.join([''.join(l) for l in zip(*r)]))
josh2112
fonte
11
Você pode salvar um punhado de bytes removendo o espaço que se segue a )ou ]na maioria dos casos, por exemplo, ''.join(l)for l in....é perfeitamente válido
wnnmaw
3

MATLAB, 92 36 bytes

s=bsxfun(@circshift,s,0:size(s,2)-1)

Supondo que a sequência de entrada sjá esteja na forma de uma matriz / matriz de caracteres 2D, por exemplo

s = ['abcdefg';'.......'];
s = ['\\\\.....././';'...../.......';'........././.';'..../.^\\....'];

Explicação: itere pelas colunas da matriz. Para cada coluna, execute um deslocamento circular de seus elementos pelo número de caracteres que é igual ao índice da coluna (-1 devido à indexação do MATLAB).

Matthias W.
fonte
2

Braquilog , 96 bytes

$\:0{h_.|[M:I]hh:I{bh0,?h.|[C:I]h$)D,I-1=:Dr:2&.}C,I+1=J,Mb:J:1&:[C]rc.}$\{hA,[A]:"~s
"w,?b:3&;}

Isso espera uma lista de cadeias de códigos de caracteres como entrada e sem saída, por exemplo brachylog_main([`aaaa`,`bbbb`,`cccc`],_).

Essa é uma resposta ridiculamente longa e provavelmente existe uma maneira muito mais curta de fazer isso.

Explicação

§ Main Predicate

$\:0{}$\{}                            § Create a list containing the transposed input and 0
                                      § Call sub-predicate 1 with this list as input
                                      § Transpose its output and pass it as input to
                                      § sub-predicate 3


§ Sub-predicate 1

h_.                                   § If the matrix is empty, output is empty list
   |                                  § Else
    [M:I]hh:I{}C,                     § Input is [M,I], call sub-predicate 2 with the first
                                      § line of M and I as input. Its output is C.
                 I+1=J,Mb:J:1&        § Call sub-predicate 1 with M minus the first line
                                      § and I+1 as input
                              :[C]rc. § Its output is appended after C, which is then
                                      § unified with the output of sub-predicate 1.


§ Sub-predicate 2

bh0,?h.                               § If the second element of the input list is 0,
                                      § output is the first element of the input
       |                              § Else
        [C:I]                         § Input is [C,I]
             h$)D,                    § Perform a circular permutation of C from left to
                                      § right (e.g. [a,b,c] => [c,a,b]) and unify it with D
                  I-1=:Dr:2&.         § Call sub-predicate 2 with D and I-1 as input, unify
                                      § its output with sub-predicate 2's output


§ Sub-predicate 3

hA,[A]:"~s\n"w,                       § Write the first line of the input as a char codes
                                      § string followed by a new line

               ?b:3&;                 § Call sub-predicate 3 with input minus the first
                                      § line. If it fails (empty input), terminate
Fatalizar
fonte
2

JavaScript, 92 89 bytes

3 bytes de desconto, graças à @ Neil .

s=>(z=s.split`
`).map((m,i)=>m.replace(/./g,(n,j)=>z[((l=z.length)*j+i-j)%l][j])).join`
`

removido
fonte
Você pode salvar 3 bytes usando replace: m.replace(/./g,(n,j)=>z[((l=z.length)*j+i-j)%l][j]).
Neil
11
De fato, [...m].map(todo o caminho até e incluindo o primeiro .join.
Neil
2

Python 2, 115 bytes

lambda s:'\n'.join("".join(s)for s in zip(*[k[-i%len(k):]+k[:-i%len(k)]for i,k in enumerate(zip(*s.split('\n')))]))

Graças à maravilha de zipconseguir reduzir isso a uma linha. Veja em ação aqui .

wnnmaw
fonte
2

MATL , 18 21 bytes

Zy2):"G@Z)@qYS]N$h

A entrada é do formato

['Hello, world!'; 'I am another '; 'string to be '; 'twisted!']

Experimente online!

Como funciona :

Zy       % implicitly take input: 2D char array. Get its size
2)       % second element from size vector: number of columns, say n
:        % create vector [1,2,...,n]
"        % for each element k in that vector
  G      %   push input
  @      %   push k
  Z)     %   k-th column from input
  @qYS   %   circularly shift k-1 positions
]        % end for loop
N$h      % concatenate all stack contents horizontally
         % implicitly display
Luis Mendo
fonte
1

F #, 105 bytes

Minha primeira tentativa (apenas um \npersonagem é necessário):

let m x y=(x%y+y)%y
let f(a:string[])=Array.mapi(fun i x->String.mapi(fun j _->a.[m(i-j)a.Length].[j])x)a

Uso:

f [| @"\\\\\\\\\\\\"
     "............"
     "............"
     "............" |]
pswg
fonte
Acho que nunca vi F # antes no PPCG.
precisa
1

JavaScript (ES6), 73 bytes

t=>t.replace(/./g,(_,i)=>t[(i+s*l-i%l*l)%s],l=t.search`
`+1,s=t.length+1)

Explicação

t=>
  t.replace(/./g,(_,i)=> // replace each character at index i
    t[                   // get the character at index:
      (i                 // start at i
        +s*l             // add s*l to ensure the result is always positive for %s
        -i%l*l           // move the index upwards the num of chars from start of the line
      )%s                // shift the index into the the range of s
    ],
    l=t.search`
`+1,                     // l = line length
    s=t.length+1         // s = input grid length (+1 for the missing newline at the end)
  )

Teste

user81655
fonte
1

Japonês, 29 bytes

Uy £XsV=(Y*Xl -Y %Xl)+X¯V}R y

Teste online!

Como funciona

Uy        // Transpose rows and columns in the input string.
£     }R  // Map each item X and index Y in the result, split at newlines, to:
Y*Xl -Y   //  Take Y times X.length and subtract Y.
%Xl)      //  Modulate the result by X.length.
XsV=      //  Set V to the result of this, and slice off the first V chars of X.
+X¯V      //  Concatenate this with the first V chars of X.
y         // Transpose the result again.
          // Implicit: output last expression
ETHproductions
fonte
1

Haskell, 81 bytes

let t=transpose in t.snd.mapAccumR(\c l -> 1+c,take(length l)(drop c$cycle l))0.t

reimplementação do exemplo CJam, embora o reverso, o mapa e a enumeração façam parte do mapAccumR, o snd remove o acumulador, pois não precisamos mais dele, a reversão é apenas um efeito colateral da dobra direita.

Daniel Hill
fonte
1

Haskell, 65 bytes

g l@("":_)=l;g l|t<-tail<$>l=zipWith(:)(head<$>l)$g$last t:init t

Exemplo de uso: g ["1111","2222","3333"]-> ["1321","2132","3213"].

nimi
fonte
1

MATL , 9 bytes

"@X@qYS&h

Experimente online!

Bastante similar ao núcleo da resposta MATL existente de Luis Mendo , mas mais curto usando recursos que provavelmente não estavam na linguagem naquele momento: 1. "itera através das colunas de uma matriz automaticamente agora, portanto, nenhum negócio caro de construir índices de coluna e indexá-los ( este é o biggie), 2. &hcomo uma maneira abreviada de dizer N$h, e 3. fim implícito do loop, se ]não for especificado.

Como alternativa, pelo mesmo número de conta:

tsn:ql&YS

Experimente no MATL Online

      &YS   % circularly shift the matrix
     l      % across rows (i.e. shift each column) by the amounts
            %  given by this array:
tsn         % duplicate input, get the sum of each column, get the 
            %  number of elements in that (which is the number of columns)
   :q       % construct range 1 to ncols, then decrement to start at 0
            % (implicit output)
sundar - Restabelecer Monica
fonte
0

C (clang) , 114 bytes

Trabalha no GCC sob MinGW. O GCC do TIO fica confuso ao usar strlenna expressão init do primeiro loop for.

f(L,n)char**L;{for(int l=strlen(*L),i=0,j,c;i<n;i++)for(j=c=0;j<=l;j++,c=c?c-1:n-1)putchar(l^j?L[(c+i)%n][j]:10);}

Experimente online!

gastropner
fonte