Encuadre (ajuste al cuadrado más pequeño posible)

8

Introducción

Más complejo que un cuadrado de texto ya que esto requiere relleno y la entrada tiene un tipo de datos desconocido.

Cada año, Dyalog Ltd. celebra una competencia estudiantil. El desafío es escribir un buen código APL. Esta es una edición de agnóstico del lenguaje del décimo problema de este año.

Tengo permiso explícito para publicar este desafío aquí del autor original de la competencia. No dude en verificar siguiendo el enlace proporcionado y contactando al autor.

Problema

Escriba un programa / función que cambie la forma de una cadena o lista numérica dada en el cuadrado más pequeño que contendrá todos los elementos de la entrada, rellenando con elementos adicionales si es necesario. El elemento de relleno debe ser el elemento de relleno predeterminado para el tipo de datos dado, o cualquier elemento que elija. Los elementos del cuadrado deben estar en un orden tal que al aplanarlo se obtenga el orden original de los datos de entrada (con elementos de relleno finales, si los hay).

Casos de prueba

[1,2,3,4]

[[1,2],
 [3,4]]

[1,2,3,4,5]

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

"Dyalog APL"

[["Dyal"],       [["D","y","a","l"],
 ["og A"],   or   ["o","g"," ","A"],
 ["PL  "],        ["P","L"," "," "],
 ["    "]]        [" "," "," "," "]]

[100]

[[100]]

[]

el equivalente más cercano de su idioma a una matriz vacía, por ejemplo []o[[]]


Adán
fuente
¿Tenemos que poder manejar tanto cadenas como matrices como entrada o solo una? ¿Puede la salida ser una cadena que contenga nuevas líneas? ¿La salida para [100] no debe ser [[1,0], [0,0]]? Si no, ¿es [[100,1], [2,0]] la salida esperada para la entrada [100,1,2]?
Shaggy
@ Shaggy Sí, listas numéricas y cadenas / listas de caracteres (cualquiera que sea su idioma). Salida por reglas predeterminadas. "100" da [["1", 0 "], [" 0 "," "]] (o lo que sea el elemento de relleno. Sí, [100,1,2] → [[100,1], [2 , 0]].
Adám
Hola Adám, tengo tres preguntas ... 1. ¿Qué significa "El elemento de relleno debe ser el elemento de relleno predeterminado para el tipo de datos dado, o cualquier elemento de su elección". es decir, ¿es restringido o gratuito (parece contradictorio o redundante)? 2. ¿Cuál debería ser la salida para una entrada como [1,2,3,4,'O'], o se garantiza que no ocurra? 3. ¿El orden requerido después del requisito de aplanamiento ignora los elementos de la almohadilla (por ejemplo, ¿podría una entrada de [1,2,3,4,5]rendimiento [[0,0,0],[0,1,2],[3,4,5]]o incluso [[0,1,0],[2,0,3],[0,4,5]])?
Jonathan Allan
1
@JonathanAllan 1. Algunos idiomas se rellenarán automáticamente. Lo que sea que rellenen está bien. Si no lo hace, elija un elemento. 2. cadena o lista numérica . 3. Los elementos de relleno deben estar detrás.
Adám

Respuestas:

4

MATL , 12 9 bytes

Guardado tres bytes gracias a Luis. heen lugar de UGwewe, pero agregando un tal principio.

tnX^Xkthe

Pruébalo en línea!

Esto devuelve los resultados, pero se transpone en comparación con el resultado en la publicación de OP (que está bien).

Explicación:

Esto funciona de la misma manera para entradas numéricas y de cadena, ya que MATL las trata de la misma manera.

Suponga que la entrada es 'Dyalog APL'

                % Implicit: Take string or numeric array as input
                % Stack: 'Dyalog APL'
t               % Duplicate
                % Stack: 'Dyalog APL'
                %        'Dyalog APL'
 n              % Number of elements in last element. 
                % Stack: 'Dyalog APL'
                %        10
  X^            % Take the square root of the number of elements
                % Stack: 'Dyalog APL'
                % Stack: 3.16...
    Xk          % Ceil last number
                % Stack: 'Dyalog APL'
                %        4
      t         % Duplicate element
                % Stack: 'Dyalog APL'
                %        4
                %        4
       h        % Concatenate the last to elements horizontally
                % Stack: 'Dyalog APL'
                %        4  4
        e       % reshape into 4 rows, and 4 columns. Pads the input with zeros or spaces
                % if necessary.
                % Stack: (Note that there's a trailing column not shown below)
                %        DoP 
                %        ygL 
                %        a   
                %        lA  

Esto no genera nada para la entrada vacía, que resulta ser que MATL genera matrices / cadenas vacías.

Stewie Griffin
fuente
¿Qué genera para la entrada vacía?
Adám
Esto no genera nada para la entrada vacía, que resulta ser que MATL genera matrices / cadenas vacías.
Stewie Griffin
1
Creo que también tnX^Xkt3$ehace el trabajo
Luis Mendo
1
O, mejor,tnX^Xkthe
Luis Mendo
1
@LuisMendo busqué una manera de pasar tres entradas a reshapey no se dio cuenta de la muy obvia: $: Specified inputs. Y no sabía que podías pasar las dimensiones como un vector. Yo sabía que tenía que haber una manera sin tener que pasar por dos remodelamientos. ¡Gracias! :)
Stewie Griffin
3

JavaScript (ES7), 70 bytes

a=>[...Array((a.length-1)**.5+1|0)].map((_,$,b)=>b.map(_=>a[i++]),i=0)

Devuelve []para una matriz / cadena vacía. Usos undefinedcomo el valor de relleno. Para ES6, reemplace (...)**.5con Math.sqrt(...)(+5 bytes).

Neil
fuente
2

Brachylog , 10 bytes

;Ac~c.\l~l

Pruébalo en línea!

Toma cadenas como listas de caracteres (el autor de la pregunta ha confirmado que esto está bien).

Esto es muy ineficiente en entradas más largas, ya que fuerza de forma bruta todas las posibles remodelaciones de la entrada, intentando progresivamente más relleno, hasta que encuentra una que resulta ser cuadrada.

Explicación

;Ac~c.\l~l
;Ac         Append {the shortest list possible}.
   ~c       Split into a list of lists
      \l    such that it's rectangular, and the number of columns
     .  ~l  equals the number of rows

Los elementos de relleno utilizados son el valor "cualquier valor" de Prolog _, que normalmente se representa como _Gmás algunos dígitos aleatorios en la salida (para que el motor Prolog pueda expresar relaciones entre esos valores de propósito general).

Por cierto, hubo una corrección de errores en SWI-Prolog hace solo unos días que hace posible este programa (aunque todavía parece funcionar en versiones anteriores con errores); la restricción "es rectangular" implicada \anteriormente se rompió, pero se solucionó a tiempo para el desafío.


fuente
1

Python 2 , 105 bytes

def f(a):b=len(a)and int((len(a)-1)**.5)+1;return[(a+[[0],' ']["'"in`a`]*b*b)[b*i:][:b]for i in range(b)]

Pruébalo en línea!

Monja permeable
fuente
¿Qué genera para la entrada vacía?
Adám
44
@ Adám La respuesta correcta.
Leaky Nun
Ahora puede simplificar usando solo un elemento de relleno.
Adám
1

PHP, 139 bytes

Cadena de salida como matriz de caracteres 2D

funciona con una []matriz vacía

$r=[];for($z=ceil(sqrt($n=(($b=is_array($g=$_GET[0]))?count:strlen)($g)));$c<$z*$z;$c++)$r[$c/$z^0][]=$c<$n?$g[+$c]:($b?0:" ");print_r($r);

Pruébalo en línea!

PHP, 143 bytes

necesita [[]]como matriz vacía

Cadena de salida como matriz de cadena 1D

$z=ceil(sqrt((($b=is_array($g=$_GET[0]))?count:strlen)($g)));print_r($b?array_chunk(array_pad($g,$z**2,0),$z):str_split(str_pad($g,$z**2),$z));

Pruébalo en línea!

Jörg Hülsermann
fuente
1

Jalea , 13 bytes

L½Ċẋ€`
0ṁ;@ṁÇ

Un enlace monádico que toma una lista plana y devuelve una lista de listas.

Test suite en Pruébelo en línea!

¿Cómo?

Agrega tantos ceros (el elemento de relleno) como elementos hay en la entrada y luego cambia la forma a un cuadrado, eliminando cualquier exceso de ceros a los requisitos en el proceso.

L½Ċẋ€` - Link 1, create a square list of lists of the required size: list a
L      - length of a
 ½     - square root
  Ċ    - ceiling (the required side length, S)
     ` - repeat argument (S) for the dyadic operation:
   ẋ€  -   repeat list for €ach (implicit range [1,2,...,S] on both its left and right)
       -   note: if the input list has no length then an empty list is yielded here

0ṁ;@ṁÇ - Main link: list a (strings are lists of characters in Jelly)
0      - literal zero
 ṁ     - mould like a (makes a list of zeros of the same length as the flat list a)
  ;@   - concatenate a with that
     Ç - call the last link (1) as a monad with argument a
    ṁ  - mould the (possibly oversized) flat array with extra zeros like the square array
Jonathan Allan
fuente
1

R, 91 bytes

function(x){if(!is.double(x))x=strsplit(x,'')[[1]];matrix(x,r<-ceiling(sqrt(length(x))),r)}

Por defecto, R rellena las matrices reciclando elementos del vector de entrada y codifica las matrices en el orden de columnas principales. Devolverá una 0x0matriz para una entrada de double(0)(una matriz doble vacía) o ''.

La primera línea (la ifdeclaración) divide una cadena en un vector de sus caracteres constituyentes; si puedo tomar ese vector, esa línea se puede eliminar.

Pruébalo en línea!

Giuseppe
fuente
@ JonathanAllan gracias, arreglado.
Giuseppe
0

Bash , 91 77 69 67 bytes

L=`dc -e${#1}\ 1-v1+p`
[ -z "$1"]||printf %-$[$L*$L]s "$1"|fold -$L

Pruébalo en línea!

Formatos de texto, pads con espacios. No emite nada para stdout en la entrada vacía.

Actualización : robó algunos trucos de las respuestas aquí .

eush77
fuente
0

Haskell, 87 bytes

import Data.Lists
f x|c:_<-[n|n<-[1..],n^2>=length x]=take c$chunksOf c$x++(error[]<$x)

Pruébalo en línea!

El elemento de relleno es error[], el valor más corto que es de cualquier tipo ( undefinedes un poco más largo).

Notas sobre el enlace TIO:

  • no puede imprimir error, así que concateno matrices con elementos de relleno de nuevo en una lista e imprimo su longitud

  • TIO no tiene Data.Lists, solo Data.List.Splitque muestra 5 bytes más.

Cómo funciona: calcule la longitud cde la matriz c-por-c. Tome los primeros celementos de la lista de fragmentos de longitud cde la lista de entrada seguido de una lista de elementos de relleno que tiene la misma longitud que la lista de entrada. P.ej :

[1,2,3,4,5]                                        -- Input 
[1,2,3,4,5,error,error,error,error,error]          -- fill elements appended
[[1,2,3],[4,5,error],[error,error,error],[error]]  -- chunks of length 3
[[1,2,3],[4,5,error],[error,error,error]]          -- take 3
nimi
fuente