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!


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.


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

3

Dyalog APL, 66 64 58 52 bajtów

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

Wypróbuj online!

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


∊'┌'(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!


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.


×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.



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

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 przez1ŀ (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

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.


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.


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!


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


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

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]
        ]
    ]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.