Arbitrary Interval Ruler

25

Stwórz program, który pobiera długość i listę interwałów i wyświetla linijkę o tej długości z dłuższymi tyknięciami dla każdego interwału, używając znaków rysowania linii ┌ ┬ ┐ │ ╵

  • Pierwszy wiersz wyniku powinien rozpoczynać się od tiku dla 0 z i kończyć tikiem dla długości z , z użyciem dla każdego znaku pomiędzy. W lengthtym pierwszym rzędzie będzie łącznie + 1 znaków rysowania linii.
  • Tyk należy wydłużyć w pionie o pół znaku, stosując i na podstawie interwałów wejściowych.
  • Odstępy są wyświetlane od najmniejszej do największej, w stosunku do przedziału przed nim. Opracować:
    • Pierwszy interwał informuje, ile podstawowych tików (pierwszy wiersz - jeden znak na tik) znajduje się w drugim najmniejszym interwale (najmniejszy interwał to 1). Na przykład [3] wydłuży co trzeci tik o pół znaku.
    • Drugi i kolejne przedziały dotyczą następnego najmniejszego przedziału. Na przykład [3, 5] wydłuży co 15 bazowych tików o pełny znak, a [3, 5, 2] wydłuży co 30 bazowych tików o półtora znaku.
    • Pod-interwał 1 jest prawidłowy i skutecznie oznacza, że ​​ostatnie linie interwału są przedłużane o pełny znak zamiast o pół znaku.
  • Przykładowe przypadki testowe powinny pomóc wyjaśnić, jak to działa.

Przykłady / przypadki testowe

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]

┌┐
│
│
│
│
╵

Inne zasady / uwagi

  • Dane wejściowe i wyjściowe mogą mieć dowolny dogodny format
  • Linijka nie musi kończyć się znacznym tyknięciem
  • Lista interwałów może być pusta
  • Zerowy pask zawsze znajduje się we wszystkich przedziałach.
  • Możesz założyć długość linijki, a odstępy zawsze będą dodatnimi liczbami całkowitymi mniejszymi niż 120
  • Końcowe białe znaki są w porządku, ale nie ma wiodących białych znaków.
  • Wszelkie spacje o stałej-pojedynczej szerokości są dozwolone jako spacje, jeśli z jakiegoś powodu chcesz użyć czegoś innego niż spacje ASCII.

Wesołego golfa!

Wołowina
źródło
Czy w przypadku danych wyjściowych mogę wydrukować pierwszy wiersz, a następnie zwrócić listę kolumn?
Embodiment of Ignorance
@EmbodimentofIgnorance, powiem nie. Dane wyjściowe powinny być spójne.
Beefster
Czy możemy pobrać znaki rysunkowe z kodowania jednobajtowego (pod warunkiem, że istnieje taki, który zawiera wymagane)?
Οurous
dowolny dogodny format ” - czy możemy zaakceptować listę interwałów w odwrotnej kolejności?
ngn
@ngn: Nie rozumiem, dlaczego nie. Jeśli to ci w jakiś sposób pomoże, idź.
Beefster

Odpowiedzi:

5

JavaScript (Node.js) , 123 bajty

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

Wypróbuj online!

Użyj tej funkcji jako f(20)([5, 2]).


Dzięki Arnauld, oszczędza 4 bajty.

tsh
źródło
3

Perl 6 , 130 122 102 92 bajty

-10 bajtów dzięki nwellnhof!

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

Wypróbuj online!

Ach tak, znacznie krótszy niż moja poprzednia metoda. Jest to anonimowy blok kodu, który zwraca listę wierszy.

Wyjaśnienie:

{                                                   }   # 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
źródło
3

Dyalog APL, 66 64 58 52 bajtów

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

Wypróbuj online!

¯2 ¯8 ¯14 bajtów dzięki ngn !

dzaima
źródło
∊'┌'(1↓⍵⍴'┬')'┐'->'┌┬┐'/⍨2⍵2-1
ngn
@ngn dzięki! Są to rodzaje golfów, które są dość zrozumiałe, ale nigdy nie wiem, czy mogę przewidzieć lub poznać zastosowania
dzaima,
wreszcie udało mi się trochę skrócić prawą część ... +⌿0=(×\⍺)∘.|⍳1+⍵-> ⊥¨⍨0=(⍵+1)⍴⍳⌽⍺. akceptowanie w odwrotnej kolejności jest teraz wyraźnie dozwolone , więc możesz również usunąć
ngn
('┌┬┐'/⍨2⍵2-1)->'┌┬┐'[2,⍨×⍳⍵]
ngn
lub nawet lepiej: ('┌┬┐'/⍨2⍵2-1)⍪⍉->'┌┐'@0⍵@0⍉'┬',
ngn
2

Python 3 , 173 172 bajty

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

Wypróbuj online!

TFeld
źródło
2

05AB1E , 51 bajtów

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

Nie jestem zbyt zadowolony z tego, I¯Qiεõ}}jak można obejść puste listy danych wejściowych .. I na pewno można grać w golfa w niektórych innych częściach ..

UWAGA: Używa skompresowanych liczb całkowitych przekonwertowanych na wymagane znaki, ponieważ bezpośrednie użycie wymaganych znaków oznacza, że ​​będę musiał policzyć cały program w UTF-8, zwiększając go zbyt mocno dla wszystkich wbudowanych znaków 05AB1E.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

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

Zobacz moją wskazówkę 05AB1E (rozdział Jak skompresować duże liczby całkowite? ), Aby zrozumieć, dlaczego •5·W4•jest 94749589i •áΣ=Yô•jest 948495169488.

Kevin Cruijssen
źródło
×Smoże byćи
Magic Octopus Urn
@MagicOctopusUrn Na początku też tak myślałem, ale niestety (po prostu spróbuj z jednym z innych przypadków testowych z niepustą listą). sиSdziała, ale niestety jest to bajt dłuższy niż krótszy. To dlatego, że liczby całkowite są najpierw na stosie, a łańcuchy po nim. Z ×nim nie ma znaczenia, czy jest to int,stringalbo string,int, ale иoczekuje string,int.
Kevin Cruijssen
Och, rozumiem, ten człowiek był mylący, hah. Dobra robota, szczerze mówiąc, spędziłem 10 minut próbując dowiedzieć się, co się dzieje, przegapiłem tę ciekawostkę и! Będzie dobrze wiedzieć w przyszłości, nie widziałem, żeby była używana przed jedną z twoich pozostałych odpowiedzi.
Magic Octopus Urn
2

Węgiel drzewny , 50 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Znaki rysujące w ramce mają 3-bajtową reprezentację w grafice, więc powyższy ciąg ma tylko 40 znaków. Wyjaśnienie:

≔EηΠ…η⊕κη

Oblicz skumulowany iloczyn przedziałów.

⪫┐┌×┬⊖θ↙

Wydrukuj pierwszy rząd znaczników. Lewy i prawy znak są niewłaściwe, ponieważ wynik jest odzwierciedlany później.

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

Obliczyć liczbę interwałów, które są współczynnikiem każdego znaku podziałki. Wygeneruj ciąg s o połowie tej długości i dodaj dla nieparzystych długości. Wydrukuj każdy ciąg w dół z kolejnymi ciągami w poprzednich kolumnach, tj. W odwrotnej kolejności.

Odzwierciedlaj wszystko, aby ustawić linijkę w kolejności od lewej do prawej.

Neil
źródło
2

Emacs Lisp , 303 bajty

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

Użyj tej funkcji jako (f '(30 (5 2))).

Wersja lepiej czytelna:

(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
źródło
2

Galaretka ,  42  41 bajtów

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

Pełny program.
Wypróbuj online!

Lub zobacz pakiet testowy
Uwaga: ten kod został zmieniony z pełnego programu - ñ(następny link jako diada) został zastąpiony przez (link o indeksie 1 jako diada), aby umożliwić wielokrotne wywoływanie go przez stopkę .

W jaki sposób?

‘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
źródło
1

Rubin , 126 bajtów

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

Wypróbuj online!

Wygląda to dość gadatliwie each_slice rzeczami, ale na razie to zrobi, chyba że uda mi się znaleźć bardziej golfistę.

Pobiera dane ldotyczące długości i iprzedziałów, zwraca tablicę ciągów.

Kirill L.
źródło
1

R , 175 170 bajtów

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

Wypróbuj online!

Pobiera puste interwały jako 0, zwraca macierz znaków. Łącze TIO wyświetla wydruk całkiem ładnie.

Kirill L.
źródło
1

Haskell , 167 164 149 bajtów

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

Wypróbuj online! Lekko golfa inne podejście przez Ο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

Wypróbuj online! Nadal istnieją pewne zwolnienia, które wyglądają, jakby można je wykorzystać, ale jak dotąd wytrzymywały wszystkie dalsze próby gry w golfa.


Poprzednie 167 bajtowe rozwiązanie jest takie samo oprócz obsługi nowej linii i prawdopodobnie jest nieco lepiej czytelne:

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

Wypróbuj online!

Laikoni
źródło
1
Inne podejście przy 158 bajtach ( Wypróbuj online! ), Prawdopodobnie może zostać znacznie skrócone, ponieważ nie mówię dobrze w języku Haskell.
Οurous
@ Οurous Thanks!
Laikoni
1

PowerShell , 152 bajty

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}

Wypróbuj online!

Rozwinięty:

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
źródło
1
Masz rację. 1) Nie widziałem reguły, która pozwala na zakończenie nowej linii na końcu. 2) i nie podoba mi się, że kod czasami dodaje nowy wiersz na końcu, a czasem nie. :)
mazzy
0

C # (interaktywny kompilator Visual C #) , 204 bajty

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?"╵":"|");}}

Wypróbuj online!

Wyjście, ale utknie w nieskończonej pętli.

Wcielenie ignorancji
źródło
0

Czysty , 221 201 195 162 bajtów

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

Wypróbuj online!

Zwraca listę list znaków UTF-8 (jako ciągi znaków, ponieważ Clean nie ma wrodzonej obsługi UTF-8).

Działa, generując pierwszą linię, a następnie biorąc iloczyn prefiksów listy podanych w grupach po dwa i sprawdza, który znak rysować, na podstawie tego, czy produkt dzieli bieżącą pozycję znaku.

Nie golfowany:

$ 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]
        ]
    ]
Obrzydliwe
źródło