Regla de intervalo arbitrario

25

Haga un programa que tome una longitud y una lista de intervalos y genere una regla de esa longitud con marcas más largas para cada intervalo utilizando los caracteres de dibujo lineal. ┌ ┬ ┐ │ ╵

  • La primera fila de la salida debe comenzar con el tic para 0 con y terminar con un tic para la longitud con , con un uso para cada carácter intermedio. Habrá un total delength + 1 caracteres de dibujo lineal en esta primera fila.
  • Una marca debe alargarse verticalmente en incrementos de medio carácter usando y función de los intervalos de entrada.
  • Los intervalos se enumeran de menor a mayor, en relación con el intervalo anterior. Elaborar:
    • El primer intervalo indica cuántas marcas base (la primera fila, un carácter por marca) hay en el segundo intervalo más pequeño (el intervalo más pequeño es 1). Por ejemplo, [3] alargará cada tercer tic en medio carácter.
    • El segundo intervalo y los posteriores son en términos del siguiente intervalo más pequeño. Por ejemplo, [3, 5] alargará cada tick base 15 por un carácter completo y [3, 5, 2] alargará cada tick base 30 por un carácter y medio.
    • Un subintervalo de 1 es válido y efectivamente significa que las últimas líneas de intervalo se alargan con un carácter completo en lugar de un medio carácter.
  • Los ejemplos de casos de prueba deberían ayudar a aclarar cómo funciona esto.

Ejemplos / Casos de prueba

3, []:

┌┬┬┐

9, [3]:

┌┬┬┬┬┬┬┬┬┐
╵  ╵  ╵  ╵

30, [5, 2]:

┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│    ╵    │    ╵    │    ╵    │

32, [4, 2, 2, 2]:

┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│   ╵   │   ╵   │   ╵   │   ╵   │
│               ╵               │

48, [5, 3, 2]

┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│    ╵    ╵    │    ╵    ╵    │    ╵    ╵    │
╵                             ╵

24, [7, 3]

┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│      ╵      ╵      │

17, [3, 2, 1]

┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│  ╵  │  ╵  │  ╵
╵     ╵     ╵

1, [23, 19, 13, 11, 7, 5, 3, 2, 1]

┌┐
│
│
│
│
╵

Otras reglas / notas

  • La entrada y salida pueden usar cualquier formato conveniente
  • La regla no tiene que terminar con una marca importante
  • La lista de intervalos puede estar vacía.
  • El tic cero siempre está dentro de todos los intervalos.
  • Puede suponer que la longitud de la regla y los intervalos siempre serán enteros positivos menores que 120
  • El espacio en blanco final está bien, pero el espacio en blanco inicial no lo está.
  • Se permite cualquier espacio fijo de ancho único como un carácter de espaciado si, por alguna razón, desea utilizar algo distinto de los espacios ASCII.

¡Feliz golf!

Carne de res
fuente
Para la salida, ¿puedo imprimir la primera fila y luego devolver una lista de columnas?
Encarnación de la ignorancia
@EmbodimentofIgnorance, voy a decir que no a eso. La salida debe ser consistente.
Beefster
¿Podemos tomar los caracteres de dibujo de caja de una codificación de un solo byte (siempre que exista uno que contenga los requeridos)?
horrible
" cualquier formato conveniente ": ¿podemos aceptar la lista de intervalos en orden inverso?
NGN
@ngn: No veo por qué no. Si eso de alguna manera te ayuda, hazlo.
Beefster

Respuestas:

5

JavaScript (Node.js) , 123 bytes

l=>g=([p,q,...t],h='┌'.padEnd(l,'┬')+`┐
`)=>p?h+g(t,h.replace(/\S/g,c=>'╵│ '[c>'╴'||++i%p?2:i/p%q<1|0],i=-1)):h

Pruébalo en línea!

Use esta función como f(20)([5, 2]).


Gracias Arnauld, ahorra 4 bytes.

tsh
fuente
3

Perl 6 , 130122102 92 bytes

-10 bytes gracias a nwellnhof!

{'┌'~'┬'x$^a-1~'┐',|map {[~] <<' ' │>>[:1[$_ X%%@_]for 0..$a]},batch [\*] @^b: 2}

Pruébalo en línea!

Ah sí, mucho más corto que mi método anterior. Este es un bloque de código anónimo que devuelve una lista de líneas.

Explicación:

{                                                   }   # Anonymous code block
 '┌'~'┬'x$^a-1~'┐',     # Return the first line
 |[\*] @^b          # Get the cumulative product of the input list
              .batch(2) # And split it into pairs
  .map:{                                      }  # Map each pair to
                                    for 0..$a    # For each interval
                        :1[$_ X%%@_]    # Whether it is divisible by none of the pair, one of the pair, or both
            <<' ' │>>[                     ]      # Map to a list of characters
        [~]        # And join
Jo King
fuente
3

Dyalog APL, 66 64 58 52 bytes

{'┌┐'@0⍵@0⍉('┬│',⎕UCS 9589)/⍤11,⍉0 2⊤⊥¨⍨0=(⍵+1)⍴⍳⍺}

Pruébalo en línea!

2 8 14 bytes gracias a NGN !

dzaima
fuente
∊'┌'(1↓⍵⍴'┬')'┐'->'┌┬┐'/⍨2⍵2-1
NGN
@ngn gracias! Estos son los tipos de golf que son bastante comprensibles, pero nunca sé anticipar o conocer los usos de
dzaima
Finalmente, logré acortar un poco la parte derecha ... +⌿0=(×\⍺)∘.|⍳1+⍵-> ⊥¨⍨0=(⍵+1)⍴⍳⌽⍺. ahora se permite explícitamente la aceptación en orden inverso , por lo que también puede eliminar el
ngn
('┌┬┐'/⍨2⍵2-1)->'┌┬┐'[2,⍨×⍳⍵]
ngn
o incluso mejor: ('┌┬┐'/⍨2⍵2-1)⍪⍉->'┌┐'@0⍵@0⍉'┬',
ngn
2

Python 3 , 173 172 bytes

def f(w,n):
 print('┌'+'┬'*~-w+'┐');R=r=range(w+1)
 for i,j in zip(*[iter(n+[0])]*2):a=r[::i];r=j*[0]and a[::j];print(''.join(' ╵│'[(v in a)+(v in r)]for v in R))

Pruébalo en línea!

TFeld
fuente
2

05AB1E , 51 bytes

ÝεyIηPÖO2‰•5·W4•2äç×SI¯Qiεõ}}•áΣ=Yô•3äçy¹QyĀ+èš}ζJ»

No estoy muy contento con la I¯Qiεõ}}solución alternativa para listas de entrada vacías ... Y definitivamente también se puede jugar golf en otras partes ...

NOTA: Utiliza enteros comprimidos convertidos a los caracteres requeridos, porque usar los caracteres requeridos directamente significa que tendré que contar todo el programa en UTF-8, incrementándolo demasiado para todos los caracteres incorporados de 05AB1E también.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

Ý             # Create a list in the range [0, first (implicit) input-integer]
 ε            # Map each value `y` to:
   Iη         #  Get the prefixes of the second input-list
     P        #  Get the product of each prefix
  y   Ö       #  Check for each if its evenly dividing the value `y`
       O      #  Take the sum of that
        2    #  And then the divmod 2
  5·W4      #  Push compressed integer 94749589
        2ä    #  Split into two equal-sized parts: [9474,9589]
          ç   #  Convert each to a character: ["│","╵"]
           ×  #  Repeat each based on the divmod 2 result
            S #  And convert it to a flattened list of characters
  I¯Qi   }    #  If the second input-list was empty:
      εõ}     #   Map each list to an empty string
              #   (for some reason `€õ` doesn't work here..)
  •áΣ=Yô•     #  Push compressed integer 948495169488
         3ä   #  Split into three equal-sized parts: [9484,9516,9488]
           ç  #  Convert each to a character: ["┌","┬","┐"]
  y¹Q         #  Check if the value `y` is equal to the first input-integer
              #  (1 if truthy; 0 if falsey)
     yĀ       #  Check if the value `y` is NOT 0 (1 if truthy; 0 if falsey)
       +      #  Add both checks together
        è     #  Use it to index into the list ["┌","┬","┐"]
         š    #  And prepend the result in front of the other characters
            # After the map: zip/transpose; swapping rows and columns (with space filler)
   J          # Join every inner list together to a single string
    »         # Join the lines with newline delimiter (and output implicitly)

Vea esta sugerencia mía 05AB1E (sección ¿Cómo comprimir enteros grandes? ) Para comprender por qué •5·W4•es 94749589y •áΣ=Yô•es 948495169488.

Kevin Cruijssen
fuente
×Spuede serи
Urna de pulpo mágico
@MagicOctopusUrn Primero lo pensé también al principio, pero desafortunadamente no lo hace (solo pruébalo con uno de los otros casos de prueba con una lista no vacía). sиSfunciona, pero desafortunadamente es un byte más largo en lugar de más corto. Es porque los enteros están en la pila primero, y las cadenas después. Con ×eso no importa si es int,stringo string,int, pero con иeso espera string,int.
Kevin Cruijssen
Oh, ya veo, hombre, este era confuso, ja. Buen trabajo, honestamente. Pasé 10 minutos tratando de averiguar qué estaba pasando, ¡perdí ese dato и! Será bueno saberlo en el futuro, no lo había visto usado antes de una de sus otras respuestas.
Urna mágica de pulpo
2

Carbón de leña , 50 bytes

≔EηΠ…η⊕κη⪫┐┌×┬⊖θ↙↓EE⊕θΣEη¬﹪ιλ⁺×│⊘ι×╵﹪ι²‖

Pruébalo en línea! El enlace es a la versión detallada del código. Los caracteres de dibujo de recuadro tienen una representación de 3 bytes en Carbón, por lo que la cadena anterior tiene solo 40 caracteres de longitud. Explicación:

≔EηΠ…η⊕κη

Calcular el producto acumulativo de los intervalos.

⪫┐┌×┬⊖θ↙

Imprima la primera fila de marcas de graduación. Los caracteres izquierdo y derecho están al revés porque el resultado se refleja más tarde.

↓EE⊕θΣEη¬﹪ιλ⁺×│⊘ι×╵﹪ι²

Calcule el número de intervalos que son un factor de cada marca de verificación. Genere una cadena de s de la mitad de esa longitud y agregue para longitudes impares. Imprima cada cadena hacia abajo con las siguientes en columnas anteriores, es decir, en orden inverso.

Refleje todo para obtener la regla en orden de izquierda a derecha.

Neil
fuente
2

Emacs Lisp , 303 bytes

(defun f(a)(princ'┌)(dotimes(i(1-(car a)))(princ'┬))(princ'┐)(let((m 1))(while(cadr a)(let((q(caadr a))(w (cadadr a)))(princ"\n")(dotimes(i(1+(car a)))(cond((if w(= 0(mod i(* m q w))))(princ'│))((= 0(mod i (* m q)))(princ'╵))(t(princ" "))))(setq m(* m q(if w w 1)))(setcdr a`(,(cddadr a)))))))

Use esta función como (f '(30 (5 2))).

Versión mejor legible:

(defun f (a)
  (princ '┌)
  (dotimes (i (1- (car a)))
    (princ '┬))
  (princ '┐)
  (let ((m 1))
    (while (cadr a)
      (let ((q (caadr a)) (w (cadadr a)))
    (princ "\n")
    (dotimes (i (1+ (car a)))
      (cond ((if w (= 0 (mod i (* m q w))))
        (princ '│))
       ((= 0 (mod i (* m q)))
        (princ '╵))
       (t
        (princ " "))))
    (setq m (* m q (if w w 1)))
    (setcdr a `(,(cddadr a)))))))
adl
fuente
2

Jalea ,  42  41 bytes

‘Rm×\}Ṭ€+2/
⁽!ṣ;“½¥÷I‘ÄỌṙ-;⁶
Ḷ¬;.Ḥ~W;ñị¢Y

Un programa completo
Pruébalo en línea!

O vea un paquete de prueba
Nota: este código ha sido alterado de un programa completo - ñ(el siguiente enlace como una díada) ha sido reemplazado por (enlace en el índice 1 como díada) para permitir que el pie de página lo llame varias veces .

¿Cómo?

‘Rm×\}Ṭ€+2/ - Link 1, lower interval tick types: length; intervals  e.g. 7; [3,2]
‘           - increment length                                           8
 R          - range                                                      [1,2,3,4,5,6,7,8]
     }      - use right argument for this monad as if it were a dyad:
   ×\       -   cumulative reduce by multiplication                      [3,6]
  m         - modulo slice (vectorises)                                  [[1,4,7],[1,7]]
      Ṭ€    - untruth €ach                               [[1,0,0,1,0,0,1],[1,0,0,0,0,0,1]]
        +2/ - pairwise reduce with addition                              [[2,0,0,1,0,0,2]]
            -   -- yielding a list of types for each row of characters below the first
            -      where 0 is a space, 1 is a short tick-mark and 2 is a long tick-mark

⁽!ṣ;“½¥÷I‘ÄỌṙ-;⁶ - Link 2, make character set: no arguments
⁽!ṣ              - literal 9474
    “½¥÷I‘       - list of code-page indices   = [10,4,28,73]
   ;             - concatenate              [9474,10,4,28,73]
          Ä      - cumulative addition      [9474,9484,9488,9516,9589]
           Ọ     - to characters            "│┌┐┬╵"
            ṙ-   - rotate left by -1        "╵│┌┐┬"
               ⁶ - literal space character  ' '
              ;  - concatenate              "╵│┌┐┬ "

Ḷ¬;.Ḥ~W;ñị¢Y - Main link: length, L; intervals, I
Ḷ            - lowered range         [ 0, 1, 2, ..., L-1]
 ¬           - logical Not           [ 1, 0, 0, ..., 0]
   .         - literal 0.5
  ;          - concatenate           [ 1, 0, 0, ..., 0, 0.5]
    Ḥ        - double                [ 2, 0, 0, ..., 0, 1]
     ~       - bitwise NOT           [-3,-1,-1, ...,-1,-2]
      W      - wrap that in a list  [[-3,-1,-1, ...,-1,-2]]
        ñ    - call next Link (1) as a dyad (f(L, I))
       ;     - (left) concatenated with (right)
          ¢  - call last Link (2) as a nilad (f())
         ị   - (left) index into (right)  (1-indexed and modular)
           Y - join with newline characters
             - implicit print
Jonathan Allan
fuente
1

Ruby , 126 bytes

->l,i{y=1;[?┌+?┬*~-l+?┐]+i.each_slice(2).map{|j,k|x=y*j;y=k&&x*k;(0..l).map{|z|'│╵ '[(z%x<=>0)+(k ?z%y<=>0:1)]}*''}}

Pruébalo en línea!

Parece bastante detallado con todas esas each_slicecosas, pero lo hará por ahora, a menos que logre encontrar un enfoque más golfista.

Toma datos en cuanto la longitud e iintervalos, devuelve una matriz de cadenas.

Kirill L.
fuente
1

R , 175170 bytes

function(l,i,`&`=rep)rbind(c('┌','┬'&l-1,'┐'),if(i)sapply(rowSums(!outer(0:l,cumprod(i),`%%`)),function(j,x=j%/%2,y=j%%2)c('│'&x,'╵'&y,' '&(1+sum(1|i))/2-x-y)))

Pruébalo en línea!

Toma intervalos vacíos como 0, devuelve una matriz de caracteres. El enlace TIO muestra la salida impresa.

Kirill L.
fuente
1

Haskell , 167 164 149 bytes

n%l=unlines$("┌"++([2..n]>>"┬")++"┐"):[do p<-[0..n];let(j#a)b|1>p`rem`product(take j l)=a|1>0=b in(i-1)#(i#"│"$"╵")$" "|i<-[1,3..length l]]

Pruébalo en línea! Un enfoque diferente ligeramente golfista por Οurous .


n%l|let c=take(n+1).cycle;m&(x:y:r)=c('│':init([1..y]>>(m*x)!" "++"╵"))++'\n':(m*x*y)&r;m&[x]=c$'╵':(m*x)!" ";m&e=[]='┌':n!"┬"++"┐\n"++1&l
n!s=[2..n]>>s

Pruébalo en línea! Todavía hay algunas redundancias que parecen que podrían explotarse, pero hasta ahora resistieron todos los intentos de golf adicionales.


La solución anterior de 167 bytes es la misma, aparte del manejo de nueva línea y probablemente sea un poco mejor legible:

n%l=unlines$('┌':n!"┬"++"┐"):(take(n+1)<$>1&l)
n!s=[2..n]>>s
m&(x:y:r)=cycle('│':init([1..y]>>(m*x)!" "++"╵")):(m*x*y)&r
m&[x]=[cycle$'╵':(m*x)!" "]
m&e=[]

Pruébalo en línea!

Laikoni
fuente
1
Un enfoque diferente a 158 bytes (¡ Pruébelo en línea! ), Probablemente se puede acortar un poco más ya que no hablo bien Haskell.
horrible
@ Οurous Gracias!
Laikoni
1

PowerShell , 152 bytes

param($t,$i)"┌$('┬'*--$t)┐"
$i|%{$s=++$s*$_-1;$p=".(.{$s}|.*$)"
if($r){$r-replace$p,'│$1';rv r}else{$r=' '*($t+2)-replace$p,'╵$1'}}
if($r){$r}

Pruébalo en línea!

Desenrollado:

param($ticks,$intervals)
"┌$('┬'*--$ticks)┐"                         # implicit output
$intervals|%{
    $step=++$step*$_-1
    $pattern=".(.{$step}|.*$)"
    if($row){
        $row-replace$pattern,'│$1'          # implicit output
        Remove-Variable row
    }else{
        $row=' '*($ticks+2)-replace$pattern,'╵$1'
    }
}
if($row){$row}                              # implicit output
mazzy
fuente
1
Tienes razón. 1) No vi una regla que permita seguir una nueva línea al final. 2) y no me gusta que el código a veces agregue una nueva línea al final, y otras veces no. :)
mazzy
0

C # (compilador interactivo de Visual C #) , 204 bytes

a=>b=>{Write("┌"+"┐\n".PadLeft(++a,'┬'));for(int i=1;;i++,WriteLine())for(int j=0;j<a;){var m=b.Select((c,d)=>b.Take(d+1).Aggregate((e,f)=>e*f)).Count(c=>j++%c<1);Write(m<1|i>m?" ":m<2?"╵":"|");}}

Pruébalo en línea!

Salidas, pero se atasca en un bucle infinito.

Encarnación de la ignorancia
fuente
0

Limpio , 221 201 195 162 bytes

import StdEnv
$n l=[["┌":repeatn(n-1)"┬"]++["┐"]:[[if(?(i-1))if(?i&&l%(i,i)>[])"│""╵"" "\\p<-[0..n],let?j=1>p rem(prod(l%(0,j)))
]\\i<-[1,3..length l]]]

Pruébalo en línea!

Devuelve una lista de listas de caracteres UTF-8 (como cadenas, ya que Clean no tiene soporte UTF-8 innato).

Funciona generando la primera línea, luego tomando el producto de los prefijos de la lista proporcionada en grupos de dos, y comprueba qué marca dibujar en función de si el producto divide la posición actual del personaje.

Sin golf:

$ n l
    = [
        ["┌": repeatn (n - 1) "┬"] ++ ["┐"]:
        [
            [
                if(? (i - 1))
                    if(? i && l%(i, i) > [])
                        "│"
                        "╵"
                    " "
                \\ p <- [0..n]
                , let
                    ? j = 1 > p rem (prod (l%(0, j)))
            ]
            \\ i <- [1, 3.. length l]
        ]
    ]
Οurous
fuente