Régua de intervalo arbitrário

25

Faça um programa que tenha um comprimento e uma lista de intervalos e produza uma régua desse tamanho com tiques mais longos para cada intervalo usando os caracteres de desenho de linha ┌ ┬ ┐ │ ╵

  • A primeira linha da saída deve começar com o tick para 0 com e terminar com um tick para o comprimento com , sendo usado para cada caractere intermediário. Haverá um total de length+ 1 caracteres de desenho de linha nesta primeira linha.
  • Um tiquetaque deve ser alongado verticalmente por incrementos de meio caractere usando e com base nos intervalos de entrada.
  • Os intervalos são listados do menor para o maior, em relação ao intervalo anterior. Para elaborar:
    • O primeiro intervalo informa quantos ticks base (a primeira linha - um caractere por tick) estão no segundo menor intervalo (o menor intervalo é 1). Por exemplo, [3] aumentará a cada terceiro tick em meio caractere.
    • O segundo e os intervalos subsequentes são em termos do próximo menor intervalo. Por exemplo, [3, 5] aumentará a cada 15ª escala de base por um caractere completo e [3, 5, 2] aumentará a cada 30ª escala de base por um caractere e meio.
    • Um sub-intervalo de 1 é válido e significa efetivamente que as últimas linhas do intervalo são aumentadas por um caractere completo em vez de um meio-caractere.
  • Os casos de teste de exemplo devem ajudar a esclarecer como isso funciona.

Exemplos / Casos de Teste

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]

┌┐
│
│
│
│
╵

Outras regras / notas

  • Entrada e saída podem usar qualquer formato conveniente
  • A régua não precisa terminar em um grande tick
  • A lista de intervalos pode estar vazia
  • O zeroth está sempre dentro de todos os intervalos.
  • Você pode assumir que o comprimento da régua e os intervalos sempre serão inteiros positivos menores que 120
  • O espaço em branco à direita é bom, mas o espaço em branco à esquerda não é.
  • Qualquer espaço fixo de largura única é permitido como caractere de espaçamento se, por algum motivo, você desejar usar algo diferente de espaços ASCII.

Golfe feliz!

Beefster
fonte
Para saída, posso imprimir a primeira linha e retornar uma lista de colunas?
Modalidade de ignorância
@EmbodimentofIgnorance, vou dizer não a isso. A saída deve ser consistente.
Beefster
Podemos pegar os caracteres de desenho de caixa de uma codificação de byte único (desde que exista um contendo os necessários)?
Οurous 19/02
" qualquer formato conveniente " - podemos aceitar a lista de intervalos na ordem inversa?
ngn 20/02
@ngn: Não vejo por que não. Se isso de alguma forma ajuda você, vá em frente.
Beefster

Respostas:

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

Experimente online!

Use esta função como f(20)([5, 2]).


Obrigado Arnauld, economiza 4 bytes.

tsh
fonte
3

Perl 6 , 130 122 102 92 bytes

-10 bytes graças ao nwellnhof!

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

Experimente online!

Ah sim, muito mais curto que o meu método anterior. Este é um bloco de código anônimo que retorna uma lista de linhas.

Explicação:

{                                                   }   # 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
Brincadeira
fonte
3

Dyalog APL, 66 64 58 52 bytes

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

Experimente online!

¯2 ¯8 ¯14 bytes graças a ngn !

dzaima
fonte
∊'┌'(1↓⍵⍴'┬')'┐'->'┌┬┐'/⍨2⍵2-1
ngn 20/02
@ngn obrigado! Estes são os tipos de golfe que são bastante compreensíveis, mas eu nunca sei antecipar ou conhecer usos de
dzaima 20/02
finalmente, consegui encurtar um pouco a parte mais à direita ... +⌿0=(×\⍺)∘.|⍳1+⍵-> ⊥¨⍨0=(⍵+1)⍴⍳⌽⍺. aceitar em ordem inversa foi explicitamente permitido agora, então você também pode remover o
ngn
('┌┬┐'/⍨2⍵2-1)->'┌┬┐'[2,⍨×⍳⍵]
ngn 22/02
ou ainda melhor: ('┌┬┐'/⍨2⍵2-1)⍪⍉->'┌┐'@0⍵@0⍉'┬',
ngn 22/02
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))

Experimente online!

TFeld
fonte
2

05AB1E , 51 bytes

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

Não está muito satisfeito com a I¯Qiεõ}}solução alternativa para listas de entradas vazias. E também pode ser jogado em outras partes.

NOTA: Usa números inteiros compactados convertidos nos caracteres necessários, porque usar os caracteres necessários diretamente significa que terei que contar o programa inteiro em UTF-8, aumentando-o demais para todos os caracteres internos do 05AB1E.

Experimente online ou verifique todos os casos de teste .

Explicação:

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

Veja esta minha dica 05AB1E (seção Como comprimir números inteiros grandes? ) Para entender por que •5·W4•é 94749589e •áΣ=Yô•é 948495169488.

Kevin Cruijssen
fonte
×Spode serи
Magic Octopus Urn
@MagicOctopusUrn Eu também pensei primeiro no começo, mas infelizmente não (apenas tente com um dos outros casos de teste com uma lista não vazia). sиSfunciona, mas infelizmente é um byte mais longo, em vez de mais curto. É porque os números inteiros estão na pilha primeiro e as seqüências depois. Com ×isso, não importa se é int,stringou string,int, mas com иisso espera string,int.
Kevin Cruijssen 19/02
Oh, entendo, cara, esse aqui foi confuso hah. Bom trabalho, para ser honesto, passei 10 minutos apenas tentando descobrir o que estava acontecendo, perdi o boato и! Será bom saber no futuro, eu não o tinha visto antes de uma de suas outras respostas.
Magic Octopus Urn
2

Carvão , 50 bytes

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

Experimente online! Link é a versão detalhada do código. Os caracteres de desenho de caixa têm uma representação de 3 bytes no carvão, portanto, a string acima tem apenas 40 caracteres. Explicação:

≔EηΠ…η⊕κη

Calcular o produto cumulativo dos intervalos.

⪫┐┌×┬⊖θ↙

Imprima a primeira linha de marcas de escala. Os caracteres esquerdo e direito estão ao contrário, porque o resultado é refletido mais tarde.

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

Calcule o número de intervalos que são um fator de cada marca de escala. Gere uma sequência de s com metade desse comprimento e adicione comprimentos ímpares. Imprima cada sequência para baixo com as seqüências subsequentes nas colunas anteriores, ou seja, ordem inversa.

Reflita tudo para obter a régua na ordem da esquerda para a direita.

Neil
fonte
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 função como (f '(30 (5 2))).

Versão melhor legível:

(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
fonte
2

Geléia ,  42  41 bytes

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

Um programa completo.
Experimente online!

Ou consulte uma suíte de testes
Nota: esse código foi alterado de um programa completo - ñ(o próximo link como díade) foi substituído por (link no índice 1 como díade) para permitir que ele seja chamado várias vezes pelo rodapé .

Quão?

‘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
fonte
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)]}*''}}

Experimente online!

Parece bastante detalhado com tudo isso each_slice , mas servirá por enquanto, a menos que eu consiga encontrar uma abordagem mais eficiente.

Aceita a entrada como lpor comprimento e ipor intervalos, retorna uma matriz de seqüências de caracteres.

Kirill L.
fonte
1

R , 175 170 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)))

Experimente online!

Toma intervalos vazios como 0, retorna uma matriz de caracteres. O link TIO exibe a saída bem impressa.

Kirill L.
fonte
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]]

Experimente online! Abordagem diferente por golfe, 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

Experimente online! Ainda existem algumas redundâncias que parecem poder ser exploradas, mas até agora resistiram a todas as tentativas de golfe.


A solução anterior de 167 bytes é a mesma, exceto a manipulação de nova linha e provavelmente é um pouco melhor de ser lida:

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=[]

Experimente online!

Laikoni
fonte
1
Uma abordagem diferente de 158 bytes ( Experimente on-line! ) Provavelmente pode ser encurtada um pouco mais, pois eu não falo bem o Haskell.
Οurous 19/02
@ Obrigado Οurous!
Laikoni 19/02
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}

Experimente online!

Desenrolado:

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
confuso
fonte
1
Você está certo. 1) Não vi uma regra que permita rastrear nova linha no final. 2) e não gosto que o código às vezes adicione uma nova linha no final e às vezes não. :)
mazzy 18/07
0

C # (compilador interativo do 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?"╵":"|");}}

Experimente online!

Saídas, mas fica preso em um loop infinito.

Modalidade de ignorância
fonte
0

Limpo , 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]]]

Experimente online!

Retorna uma lista de listas de caracteres UTF-8 (como seqüências de caracteres, pois o Clean não tem suporte UTF-8 inato).

Funciona gerando a primeira linha e, em seguida, obtendo o produto dos prefixos da lista fornecida em grupos de dois e verifica quais marcações serão sorteadas com base no fato de o produto dividir a posição atual do caractere.

Ungolfed:

$ 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]
        ]
    ]
Furioso
fonte