Hacer un programa de triangularidad válido

19

Triangularity es un nuevo esolang desarrollado por Mr. Xcoder donde la estructura del código debe seguir un patrón muy específico:

  • Para la nlínea de código th, debe haber exactamente 2n-1caracteres del programa en él. Esto causa una forma triangular / piramidal, con la primera línea con solo un carácter y el resto aumentando en incrementos de 2.
  • Cada línea debe rellenarse con .s a la izquierda y a la derecha, de modo que los caracteres se centren en sus líneas y todas las líneas se rellenen con la misma longitud. Si lse define como el número de líneas en el programa, cada línea en el programa debe tener una longitud de2 * l - 1

Por ejemplo, el programa de la izquierda es válido, pero el programa de la derecha no lo es:

 Valid    |  Invalid  
          |
...A...   |  ABCDE
..BCD..   |  FGH
.EFGHI.   |  IJKLMN
JKLMNOP   |  OPQRS

Cuando se presenta en la estructura válida, el nombre se vuelve obvio.

Tarea

Su tarea es tomar una cadena de línea única como entrada, que representa el código de Triangularidad, y convertirla en un código válido como se describió anteriormente.

Especificaciones para E / S:

  • La entrada solo contendrá caracteres en el rango 0x20 - 0x7e
  • La longitud de la entrada siempre será un número cuadrado y, por lo tanto, se puede rellenar muy bien.
  • Debe usar puntos para el relleno de salida, no otra cosa.

Puede ingresar y enviar a través de cualquier método aceptable . Este es un por lo que gana el código más corto en bytes .

Casos de prueba

input
----
output

g
----
g

PcSa
----
.P.
cSa

DfJ0vCq7G
----
..D..
.fJ0.
vCq7G

7xsB8a1Oqw5fhHX0
----
...7...
..xsB..
.8a1Oq.
w5fhHX0

QNYATbkX2sKZ6IuOmofwhgaef
----
....Q....
...NYA...
..TbkX2..
.sKZ6IuO.
mofwhgaef

ABCDEF"$%& G8"F@
----
...A...
..BCD..
.EF"$%.
& G8"F@

ab.c
----
.a.
b.c

Para aquellos que conocen la triangularidad, notarán desde el último caso de prueba que las cadenas no tienen que ser manejadas

caird coinheringaahing
fuente
Sandbox post
caird coinheringaahing
13
Me doy cuenta de que esto probablemente sea inútil, pero ¿le gustaría al votante negativo explicar su voto? Me encantaría mejorar el desafío de cualquier manera que pueda.
caird coinheringaahing
¿Son aceptables las nuevas líneas iniciales o finales?
Arnauld
@Arnauld Sí, los espacios en blanco iniciales y finales están perfectamente bien.
caird coinheringaahing
¿Está bien una lista de líneas?
Sr. Xcoder

Respuestas:

19

Triangularidad , 127 bytes.

.......).......
......2)1......
...../)IL^.....
....f)rMD@_....
...)2)1/)IL^...
..f+`"'.'*"+E..
.DWReD)2s^)Its.
D+@sh+s+})10cJ.

Pruébalo en línea!

Explicación

Eliminando los caracteres que componen el relleno, obtenemos el siguiente programa:

)2)1/)IL^f)rMD@_)2)1/)IL^f+`"'.'*"+EDWReD)2s^)ItsD+@sh+s+})10cJ

... Que es bastante largo, ¿verdad? Vamos a dividirlo en pedazos.

Generando los enteros [0… √len (entrada))

)2)1/)IL^f)r – Subprogram #1.
)            – Creates a new stack entry, equal to 0. This must precede any integer
               literal, because each character in '0123456789' isn't parsed on its
               own as a literal, but rather they are commands which multiply the ToS
               by 10 and add the value of their digit equivalent. 
 2           – ToS * 10 + 2 = 2.           || STACK: [2]
  )1         – The literal 1.              || STACK: [2, 1]
    /        – Division.                   || STACK: [1 / 2] = [0.5]
     )I      – Get the input at index 0.   || STACK: [0.5, input]
       L     – Length.                     || STACK: [0.5, len(input)]
        ^    – Exponentiation.             || STACK: [len(input) ** 0.5]
         f   – Trim decimals.              || STACK: [int(len(input) ** 0.5)] 
          )r – Create the list [0 .. ToS). || STACK: [[0 ... int(len(input) ** 0.5))]

Generando los puntos

MD@_)2)1/)IL^f+`"'.'*"+E – Subprogram #2.
MD                       – For each integer in the range, run some code on a separate
                           stack, preinitialised to two copies of the argument.
  @_                     – Increment and negate the ToS.
    )2)1/)IL^f           – The square root of the length of the input, again.
              +          – Add the two.
               `         – And cast the integer given to a string.
                "'.'*"+  – Prepends the literal "'.'*" to the string representation.
                       E – Evaluate as a Python expression (basically string repetition).

Recortar los personajes en el frente

DWReD)2s^)It – Subprogram #3.
D            – Duplicate the result of the expression above.
 W           – Wrap the whole intermediate stack to an array.
  Re         – Reverse the stack and dump the contents separately onto the stack.
    D        – Duplicate the result.
     )2      – Push the literal 2.
       s^    – Swap and perform exponentiation.
         )It – Push the input and trim the characters before that index.

Recortar los personajes al final

sD+@sh+s+ – Subprogram #4.
s         – Swap the top two elements on the stack.
 D+       – Double. Push twice and add.
   @      – Increment.
    sh    – Swap the top two elements and trim the characters after that index.
      +   – Append the first set of dots.
       s+ – And prepend the second set of dots.

Poner fin al bucle e imprimir bonitas

})10cJ – Subprogram #5.
}      – End the loop.
 )10   – Push the literal 10.
    c  – Convert from code-point to character (yields '\n').
     J – And join the result by newlines.
Sr. Xcoder
fuente
¿tiene que puntuar bytes para el "." caracteres si están obligados por los intrínsecos del lenguaje?
JDL
@JDL Sí, el programa no puede ejecutarse correctamente sin ellos, así que debo incluirlos en el recuento de bytes :-)
Sr. Xcoder
¿Necesita "recortar decimales", ya que se garantiza que la longitud de la entrada sea cuadrada? También debe poder obtener la varilla del Jextremo y generar una serie de líneas. Sin embargo, no sé si eso le ahorrará algo, si el final de la última línea debe rellenarse .para llenar el espacio restante.
Shaggy
1
@Shaggy 1) Sí, fes necesario porque el rango no puede aceptar argumentos flotantes (incluso con .0) 2) Eliminar Jno guarda ningún byte debido al relleno, así que elegí el formato de salida más bonito.
Sr. Xcoder
8

Japt , 15 14 10 bytes

Emite una matriz de líneas.

ò@°T¬v1Ãû.

Pruébalo | Verifique todos los casos de prueba


Explantacion

ò@     Ã       :Partition at characters where the following function returns true
  °T           :  Increment T (initially 0)
    ¬          :  Square root
     v1        :  Divisible by 1?
               :(Or, in other words, split after every character with a 1-based index that's a perfect square)
        û.     :Centre pad each element with .s to the length of the longest element

Solución original

ʬÆsTT±X+°XÃû.

Intentalo

Ê                  :Length of input
 ¬                 :Square root
  Æ        à       :Range [0,ʬ) and pass each X through a function
   s               :  Slice input
    T              :    from index T, initially 0
     T±X+°X        :    to index T incremented by X plus X incremented
            û.     :Centre pad each element with .s to the length of the longest element
Lanudo
fuente
7

Casco , 15 bytes

Ṡzö`JR2tR'.ṡCİ1

Pruébalo en línea!

Explicación

Ṡzö`JR2tR'.ṡCİ1  Implicit input, say s = "DfJ0vCq7G".
             İ1  List of odd positive integers: [1,3,5,7,..
            C    Cut s to those lengths: x = ["D","fJ0","vCq7G"]
           ṡ     Reversed indices of x: y = [3,2,1]
Ṡz               Zip x and y using this function:
                  Arguments are a string and a number, e.g. r = "fJ0" and n = 2.
        R'.       n copies of '.': ".."
       t          Drop first element: "."
     R2           Two copies of this: [".","."]
  ö`J             Join by r: ".fJ0."
                 Result is ["..D..",".fJ0.","vCq7G"]; implicitly print on separate lines.
Zgarb
fuente
7

05AB1E , 20 19 18 bytes

Salvó un byte gracias a Magic Octopus Urn

ā·<£õKRvy'.N×.ø}r»

Pruébalo en línea!

Explicación

ā                    # push the list [1 ... len(input)]
 ·<                  # multiply each by 2 and decrement each, making a list of odd numbers
   £                 # split the input into chunks of these sizes
    õK               # remove empty strings
      R              # reverse list
       vy      }     # for each y in the list
             .ø      # surround it with
         '.N×        # "." (dot) repeated N times, where N is the current iteration index
                r    # reverse the stack
                 »   # join stack by newlines
Emigna
fuente
ÅÉpara las probabilidades puede ayudar?
Urna mágica del pulpo
Algo así como g;ÅÉ£Rvy'.N×.ø}r»? Pero no es eso porque no está bien jajaja.
Urna mágica del pulpo
@MagicOctopusUrn: ÅÉdefinitivamente ayudaría si pudiéramos averiguar la longitud de la fila inferior en 2 bytes. Sin embargo, no sé si podemos. Podría ser otra forma de incorporarlo también.
Emigna
@MagicOctopusUrn: Tenía esta misma solución anteriormente, excepto que la usé en )Rlugar de la rcual no guardó ningún byte: /
Emigna
Estaba tratando de encontrar una manera de "revertir el ciclo" para simplemente imprimir como ocurre, sin embargo, no tengo ideas al respecto.
Urna de pulpo mágico
5

Jalea ,  22  19 bytes

J²‘Ṭœṗ⁸Ṛz”.Zµṙ"JC$Ṛ

Un enlace monádico que devuelve una lista de listas de caracteres (las líneas)

Pruébalo en línea!

¿Cómo?

J²‘Ṭœṗ⁸Ṛz”.Zµṙ"JC$Ṛ - Link: list of characters e.g. "DfJ0vCq7G"
J                   - range of length               [1,2,3,4,5,6,7,8,9]
 ²                  - square (vectorises)           [1,4,9,16,25,36,49,64,81]
  ‘                 - increment                     [2,5,10,17,26,37,50,65,82]
   Ṭ                - untruth (1s at those indices) [0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,...]
      ⁸             - chain's left argument         "DfJ0vCq7G"
    œṗ              - partition at indexes          ["D","fJ0","vCq7G"]
       Ṛ            - reverse                       ["vCq7G","fJ0","D"]
         ”.         - literal '.'                   '.'
        z           - transpose with filler         ["vfD","CJ.","q0.","7..","G.."]
           Z        - transpose                     ["vCq7G","fJ0..","D...."]
            µ       - start a new monadic chain
                 $  - last two links as a monad:
               J    -   range of length             [1,2,3]
                C   -   complement (vectorises)     [0,-1,-2]
              "     - zip with:
             ṙ      -   rotate left by              ["vCq7G",".fJ0.","..D.."]
                  Ṛ - reverse                       ["..D..",".fJ0.","vCq7G"]
Jonathan Allan
fuente
5

JavaScript (ES7), 82 78 bytes

f=(s,k=1-s.length**.5*2,p='')=>s&&f(s.slice(0,k),k+2,p+'.')+`
`+p+s.slice(k)+p

Casos de prueba

Comentado

f = (                       // f = recursive function taking:
  s,                        //   s = input string
  k = 1 - s.length**.5 * 2, //   k = additive inverse of the length of the base
  p = ''                    //   p = padding string
) =>                        //
  s &&                      // if s is not empty:
    f(                      //   do a recursive call with:
      s.slice(0, k),        //     s without the last -k characters
      k + 2,                //     the updated base length (2 less characters)
      p + '.'               //     the updated padding string
    ) +                     //   end of recursive call()
    `\n` +                  //   append a line feed
    p +                     //   append the left padding string
    s.slice(k) +            //   append the last -k characters of s
    p                       //   append the right padding string
Arnauld
fuente
[menor] el símbolo '/ n' se convirtió en un salto de línea real en el bloque de código en la parte superior - considere escapar para mayor claridad :)
G0BLiN
@ G0BLiN Esto es al revés: de hecho, se trata de un salto de línea literal en el código de golf, que se reemplazó con un salto de línea escapado en la versión sin golf para mayor claridad. :)
Arnauld
Ja, broma sobre mí, entonces ... :-)
G0BLiN
2

MATL , 21 bytes

tnX^eRP&1ZvGyg(46y~(!

Pruébalo en línea!

Explicación

Considere la entrada 'DfJ0vCq7G'como un ejemplo. El contenido de la pila se muestra separado por comas, con el elemento superior al final. Las filas en una matriz 2D usan punto y coma como separador.

t      % Implicit input: string. Duplicate
       % STACK: 'DfJ0vCq7G',
                'DfJ0vCq7G'
nX^    % Number of elements. Square root
       % STACK: 'DfJ0vCq7G',
                3
e      % Reshape with that many rows (in column major order)
       % STACK: ['D0q';
                 'fv7';
                 'JCG']
R      % Upper triangular part: set elements below diagonal to char(0)
       % (displayed as space)
       % STACK: ['D0q';
                 ' v7';
                 '  G']
P      % Flip vertically
       % STACK: ['  G';
                 ' v7';
                 'D0q']
&1Zv   % Reflect vertically
       % STACK: ['  G';
                 ' v7';
                 'D0q';
                 ' v7';
                 '  G']
G      % Push input again
       % STACK: ['  G';
                 ' v7';
                 'D0q';
                 ' v7';
                 '  G'],
                'DfJ0vCq7G'
yg     % Duplicate from below and convert to logical. This gives true for
       % for nonzero chars (the entries where input chars will be written)
       % STACK: ['  G';
                 ' v7';
                 'D0q';
                 ' v7';
                 '  G'],
                'DfJ0vCq7G',
                [0 0 1;
                 0 1 1;
                 1 1 1;
                 0 1 1;
                 0 0 1]
(      % Assignment indexing: write values at those positions
       % STACK: ['  v';
                 ' fC';
                 'DJq';
                 ' 07';
                 '  G']
46     % Push 46, which is ASCII for '.'
       % STACK: ['  v';
                 ' fC';
                 'DJq';
                 ' 07';
                 '  G'],
                 46
y~     % Duplicate from below and apply logical negate. This gives true
       % for char(0) (the entries where '.' will be written)
       % STACK: ['  G';
                 ' v7';
                 'D0q';
                 ' v7';
                 '  G'],
                46
                [1 1 0;
                 1 0 0;
                 0 0 0;
                 1 0 0;
                 1 1 0]
(      % Assignment indexing: write value at those positions
       % STACK: ['..G';
                 '.v7';
                 'D0q';
                 '.v7';
                 '..G'],
!      % Transpose. Implicit display
       % STACK: ['..D..';
                 '.fJ0.';
                 'vCq7G']
Luis Mendo
fuente
2

Limpio , 107 94 89 88 bytes

import StdEnv
@s _[]=s
@s n r= @([['.':l]++['.']\\l<-s]++[take n r])(n+2)(drop n r)

@[]1

Pruébalo en línea! Ejemplo de uso: @[]1 ['ABCDEF"$%& G8"F@'].

Laikoni
fuente
1

Haskell , 84 68 bytes

[]%1
(s%n)[]=s
(s%n)r=(['.':l++"."|l<-s]++[take n r])%(n+2)$drop n r

Pruébalo en línea!

Ejemplo de uso: []%1 $ "abcd"produce la lista de líneas [".a.","bcd"].

Laikoni
fuente
1

Perl, 56 52 bytes

Incluye +3para-p

#!/usr/bin/perl -p
$_=("."x y///c**.5)=~s%.%$'@{[$&x/$`$`./g]}$'
%rg

Dar entrada en STDIN (en principio sin nueva línea final, pero eso solo importa para la entrada vacía)

Ton Hospel
fuente
1
según las reglas de PCG -pcuesta solo 1 byte
mik
@mik Solo si el código no contiene '. Pero este código lo hace, por lo que debe colocarse en un archivo (o escapar en la línea de comando) que necesita 3 caracteres adicionales en comparación con la #!línea normal . Así que en este caso se trata +3(por código normal verá que de hecho sólo cuentan +para p)
Ton Hospel
1

Rojo , 227203 bytes

f: func[s][l: to-integer(length? s)** 0.5
n: 0 foreach m parse s[collect[(r: []repeat i l[append r reduce['keep i * 2 - 1
charset[not{Я}]]])r]][v: copy""insert/dup v"."l - n: n + 1 print rejoin[v m v]]]

Pruébalo en línea!

Sin golf:

f: func[s][
l: to-integer (length? s) ** 0.5
n: 0
foreach m parse s [ 
    collect [
        (r: []
        repeat i l [ append r reduce [
            'keep i * 2 - 1 charset [ not{Я} ]]])
    r ]] 
    [v: copy ""
    insert/dup v "." l - n: n + 1
    print rejoin [v m v]]
]
Galen Ivanov
fuente
1

Retina , 88 72 71 bytes

S1`
+m`^(.)+¶(?>(?<-1>.)+)..(?!¶)
$&¶
P^'.m`^.(?=(..)*)(?<-1>.)*
P'.`.+

Pruébalo en línea! Editar: Guardado 12 13 bytes gracias a @MartinEnder. Explicación:

S1`

Divide el primer personaje en su propia línea para hacer rodar la pelota.

+m`^(.)+¶(?>(?<-1>.)+)..(?!¶)
$&¶

Corta cada línea dos caracteres más que la anterior.

P^'.m`^.(?=(..)*)(?<-1>.)*

Izquierda la primera mitad de cada línea, centrándolas efectivamente.

P'.`.+

Relleno derecho de todas las líneas.

Neil
fuente
1

Carbón , 21 19 bytes

UB.F₂Lθ«P✂θXι²X⊕ι²↙

Pruébalo en línea! El enlace es a la versión detallada del código. Editar: Guardado 2 bytes por descubrimiento SquareRoot. Explicación:

UB.                 Set the background fill to `.`
      θ             (First) input
     L              Length
    ₂               Square root
   F   «            Loop over implicit range
            ι   ι   Current value
               ⊕    Incremented
             ²   ²  Literal 2
           X  X     Power
         ✂θ         Slice the (first) input string
        P           Print without moving the cursor
                  ↙ Move down left
Neil
fuente
: / Esto casi funciona pero parece que el carbón es un poco defectuoso. Sin embargo, esto funciona, creo.
Solo ASCII
@ Solo ASCII ... ¿qué magia negra es esta?
Neil
Básicamente, el relleno verifica los bytes nulos (es decir, el carácter utilizado para el espacio donde no se dibuja nada), por lo que puede dibujar un polígono con bytes nulos (bueno, si incluso funciona correctamente> _>) y completarlo. Obviamente, esto no es exactamente lo que se pretende, ya que puede ver los bytes nulos incluso antes del relleno por alguna razón> _>
Solo ASCII
esto debería funcionar correctamente el próximo tirón
solo ASCII el
0

Limpio , 123 bytes

import StdEnv
?n l#(a,b)=splitAt n l
|b>[]=[a: ?(n+2)b]=[a]
$s#s= ?1s
=[c++l++c\\l<-s&i<-[1..],c<-[repeatn(length s-i)'.']]

Pruébalo en línea!

Οurous
fuente
2
Alguna competencia amistosa .
Laikoni
@Laikoni Ooh, ese es mi tipo favorito de competencia!
Precioso
0

Ruby , 73 66 bytes

->s{(1..z=s.size**0.5).map{|q|s[q*q-2*q+1...q*q].center 2*z-1,?.}}

Pruébalo en línea!

-5 bytes: devuelve una matriz de cadenas en lugar de imprimirlas

-2 bytes: declarar zen su lugar en lugar de antes de tiempo

Sin golf:

->s{
  (1..z=s.size**0.5).map{|q|   # Map the range [1,sqrt(s.size)]
    s[q*q-2*q+1...q*q]         # To the relevant portion of s,
      .center 2*z-1, ?.        #   padded left and right with . characters
  }
}

Declarando una variable r=q-1para que pueda tomars[r*r...q*q] guarda exactamente cero bytes.

Usar en .centerlugar de rellenar manualmente también ahorra cero bytes, pero me gusta más.

benj2240
fuente