Jouez au twister à cordes

24

Comment les cordes sont tordues

L'algorithme de torsion est très simple. Chaque colonne est décalée vers le bas par son index (col 0 descend 0, col 1 se déplace 1, ...). Le décalage de colonne se déplace vers le haut. Cela fonctionne comme ceci:

aaaa
bbbb
cccc

Devient:

a
ba
cba
----
 cba
  cb
   c

Avec tout sous la ligne enveloppant vers le haut. Exemple réel:

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

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

Contribution

L'entrée est soit un tableau de chaînes, soit une chaîne de plusieurs lignes. Toutes les lignes ont la même longueur.

Sortie

La chaîne torsadée, sortie multi-ligne vers sortie standard (ou alternative la plus proche).

Exemples:

( >indique l'entrée, l'espace de fin est important)

>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
la source
12
Il vaut mieux ne pas avoir de Mathematica intégré pour cela.
Mama Fun Roll
1
Pouvons-nous supposer que l'entrée ne contiendra que de l'ASCII? Ou seulement des sauts de ligne ASCII + imprimables ou quelque chose?
Martin Ender
Oui, juste ASCII et newline (sauf si vous prenez l'entrée comme un tableau).
J Atkin

Réponses:

3

Brachylog , 5 octets

iᵇ↻₎ᵐ

Essayez-le en ligne!

Obtient une entrée sous forme de tableau de colonnes (ce qui semble correspondre aux spécifications de la question).

iᵇ- Pour chaque élément du tableau, associez-le à son index (basé sur 0)
- mappez ce prédicat à chaque élément du résultat:
↻₎- permutez (la colonne) de façon circulaire du montant spécifié comme dernier élément (l'index)

Extension facile à une version qui accepte une seule chaîne multiligne:

13 octets

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

Essayez-le en ligne!

Sundar - Rétablir Monica
la source
C'est une compression des informations incroyable.
J Atkin
7

Pyth, 11

jC.>R~hZC.z

Essayez-le ici

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
la source
7

APL (Dyalog) , 7 octets

⊖⊖⊖⍨⍬⍋⍉

A besoin ⎕io←0

Essayez-le en ligne!

⍬⍋⍉obtient la plage de 0 au nombre de colonnes
revers verticalement
⊖⊖⍨⍬⍋⍉rotation (verticalement) le (verticalement) inversé par entrée 0,1..
inverse que, et le retourner.

H.PWiz
la source
6

Rétine , 111 101 92 87 octets

Le nombre d'octets suppose un codage ISO 8859-1.

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

Woo, l'a résolu dans une seule substitution d'expression régulière. :) (Il y a de fortes chances qu'il y ait une solution plus courte en utilisant plusieurs, mais où est le plaisir là-dedans ...)

Essayez-le en ligne!

Explication

Cela nécessite une connaissance de base des groupes d'équilibrage . En bref, la saveur regex de .NET vous permet de capturer plusieurs fois avec un seul groupe, en poussant toutes les captures sur une pile. Cette pile peut également être extraite, ce qui nous permet de l'utiliser pour compter les choses à l'intérieur de l'expression régulière.

(?<=((.))*)

Cela pousse une capture sur les deux groupes 1et 2pour chaque personnage devant le match (dans la ligne actuelle). Autrement dit, il compte la position horizontale du match.

Le reste est dans une impasse:

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

Nous faisons correspondre chaque ligne et la poussons également sur le groupe 1, de sorte que le groupe 1est maintenant la somme de la position horizontale et verticale (où cette dernière est comptée à partir du bas ). Cela marque essentiellement les diagonales de la grille avec des valeurs croissantes à partir du coin inférieur gauche. Cela .*déplace alors simplement le curseur du moteur à la fin de la chaîne.

Nous passons maintenant à un lookbehind, qui est mis en correspondance de droite à gauche dans .NET:

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

Cela fera apparaître à plusieurs reprises exactement les Hcaptures du groupe 1(où Hest la hauteur de l'entrée). Le but de cela est de prendre le groupe modulo H. Ensuite, le groupe 1contient la ligne (comptée à partir du bas) à partir de laquelle choisir le nouveau caractère dans la colonne actuelle.

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

Encore un coup d'œil, partant de nouveau à droite. (?<-1>.+¶)*.+utilise maintenant le groupe 1pour trouver la ligne à partir de laquelle choisir le nouveau personnage, puis le trouve la colonne préanalyse correcte en utilisant le groupe 2.

Le caractère souhaité est capturé en groupe 3et réécrit par la substitution.

Martin Ender
la source
Ah, lire la source de Retina était agréable et clair :) a l' $+air utile ... surtout si vous ne voulez faire qu'une seule substitution: ^)
FryAmTheEggman
@FryAmTheEggman $+est en fait assez inutile ... sa description sur MSDN semble beaucoup plus utile qu'elle ne l'est parce qu'elle implique que (a)|(b)-> $+$+doublerait tous les as et bs mais à la place elle supprime tous les as, car elle se réfère simplement au dernier groupe syntaxiquement . Cela signifie que c'est juste un moyen d'éviter de compter tous les groupes si vous êtes trop paresseux (comme moi). Pour le golf, cela n'économise que des octets lorsque vous avez plus de 9 groupes, ce qui est probablement assez rare au départ.
Martin Ender
C'est dommage ... Peut-être que la rétine pourrait avoir un nouveau type de groupe de remplacement qui retournerait le dernier groupe de correspondance non vide? Quoi qu'il en soit, merci pour l'explication! :)
FryAmTheEggman
@FryAmTheEggman Ce sera le cas (c'est l'une des choses que j'avais en tête lors de la réécriture Regex.Replacepour Retina, mais je n'ai pas encore réussi à l'implémenter).
Martin Ender
4

CJam, 13 octets

qN/zee::m>zN*

Testez-le ici.

Explication

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
la source
2
Vous pouvez presque prononcer ce code source.
mınxomaτ
4

TeaScript, 10 octets

xHl@C(r╢tD

Grâce à la syntaxe extrêmement concise de TeaScript 3, ceci est vraiment court: D

Serait plus court d'un octet si la boucle Sigma n'était pas boguée

Essayez-le en ligne

Explication

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

Python 3, 164 octets

Pas la meilleure réponse de loin, mais la première en 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
la source
1
Vous pouvez enregistrer une poignée d'octets en )]''.join(l)for l in....
supprimant
3

MATLAB, 92 36 octets

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

En supposant que la chaîne d'entrée sest déjà sous la forme d'un tableau / d'une matrice de caractères 2D, par exemple

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

Explication: parcourez les colonnes de la matrice. Pour chaque colonne, effectuez un décalage circulaire de ses éléments par le nombre de caractères égal à l'index de la colonne (-1 en raison de l'indexation MATLAB).

Matthias W.
la source
2

Brachylog , 96 octets

$\: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&;}

Cela attend une liste de chaînes de codes de caractères en entrée et sans sortie, par exemple brachylog_main([`aaaa`,`bbbb`,`cccc`],_).

C'est une réponse ridiculement longue, et il existe probablement un moyen beaucoup plus court de le faire.

Explication

§ 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
Fatalize
la source
2

JavaScript, 92 89 octets

3 octets de réduction merci @Neil .

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

supprimé
la source
Vous pouvez enregistrer 3 octets en utilisant replace: m.replace(/./g,(n,j)=>z[((l=z.length)*j+i-j)%l][j]).
Neil
1
En effet, [...m].map(tout le chemin jusqu'au premier inclus .join.
Neil
2

Python 2, 115 octets

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

Merci à la merveille d'avoir zipréussi à ramener cela à une seule ligne. Voyez-le en action ici .

wnnmaw
la source
2

MATL , 18 21 octets

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

L'entrée est de la forme

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

Essayez-le en ligne!

Comment ça marche :

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
la source
1

F #, 105 octets

Mon premier coup de couteau (seul un \npersonnage est requis):

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

Usage:

f [| @"\\\\\\\\\\\\"
     "............"
     "............"
     "............" |]
pswg
la source
Je ne pense pas avoir déjà vu F # sur PPCG.
J Atkin
1

JavaScript (ES6), 73 octets

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

Explication

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

Tester

user81655
la source
1

Japt, 29 octets

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

Testez-le en ligne!

Comment ça marche

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
la source
1

Haskell, 81 octets

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

réimplémentation de l'exemple CJam, bien que l'inverse, la carte et l'énumération fassent partie de mapAccumR, le snd supprime l'accumulateur puisque nous n'en avons plus besoin, l'inversion n'est qu'un effet secondaire du pli droit.

Daniel Hill
la source
1

Haskell, 65 octets

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

Exemple d'utilisation: g ["1111","2222","3333"]-> ["1321","2132","3213"].

nimi
la source
1

MATL , 9 octets

"@X@qYS&h

Essayez-le en ligne!

Assez similaire dans son noyau à la réponse MATL existante de Luis Mendo , mais plus court en utilisant des fonctionnalités qui n'étaient probablement pas dans le langage à ce stade: 1. "itère automatiquement dans les colonnes d'une matrice maintenant, donc pas de travail coûteux de construction d'index de colonne et d'indexation en eux ( c'est le biggie), 2. &hcomme une façon abrégée de dire N$h, et 3. fin de boucle implicite si ]n'est pas spécifié.

Alternativement, pour le même bytecount:

tsn:ql&YS

Essayez-le sur 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 - Rétablir Monica
la source
0

C (clang) , 114 octets

Fonctionne dans GCC sous MinGW. Le GCC de TIO est confus en utilisant strlenl'expression init de la première boucle 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);}

Essayez-le en ligne!

gastropner
la source