Произвольный интервал линейки


25

Создайте программу, которая берет длину и список интервалов и выводит линейку этой длины с более длинными галочками для каждого интервала, используя символы рисования линий ┌ ┬ ┐ │ ╵

  • Первая строка вывода должна начинаться с отметки 0 с и заканчиваться галочкой для длины с , используемой для каждого символа между ними. Всего lengthв этом первом ряду будет + 1 символ рисования линий.
  • Тик должен быть удлинен по вертикали на полсимвольные приращения с использованием и на основе интервалов ввода.
  • Интервалы перечислены от наименьшего к наибольшему относительно интервала перед ним. Разработать:
    • Первый интервал сообщает, сколько базовых тиков (первая строка - один символ на тик) находятся во втором наименьшем интервале (наименьший интервал равен 1). Например, [3] будет удлинять каждый третий тик на половину символа.
    • Второй и последующие интервалы соответствуют следующему наименьшему интервалу. Например, [3, 5] будет удлинять каждый 15-й базовый тик на полный символ, а [3, 5, 2] будет удлиняться на каждый 30-й базовый тик на полтора символа.
    • Подинтервал 1 действителен и фактически означает, что последние строки интервала удлиняются на полный символ вместо полусимвола.
  • Примеры тестов должны помочь уточнить, как это работает.

Примеры / Тестовые случаи

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]

┌┐
│
│
│
│
╵

Другие правила / примечания

  • Ввод и вывод может использовать любой удобный формат
  • Правитель не должен заканчиваться на главном тике
  • Список интервалов может быть пустым
  • Нулевой тик всегда во всех интервалах.
  • Можно предположить, что длина линейки и интервалы всегда будут положительными целыми числами меньше 120
  • Конечный пробел - это хорошо, но ведущий пробел - нет.
  • Любой пробел с фиксированной шириной в одну допускается как пробел, если вы по какой-то причине хотите использовать что-то кроме пробелов ASCII.

Счастливого гольфа!


Для вывода могу ли я напечатать первую строку, а затем вернуть список столбцов?
Воплощение Невежества

@EmbodimentofIgnorance, я скажу нет на это. Вывод должен быть согласованным.
Beefster

Можем ли мы взять символы рисования блоков из однобайтовой кодировки (при условии, что существуют символы, содержащие требуемые)?
Οurous

« любой удобный формат » - можем ли мы принять список интервалов в обратном порядке?
СПП

@ngn: не понимаю, почему нет. Если это как-то поможет вам, сделайте это.
Beefster

Ответы:



3

Perl 6 , 130 122 102 92 байта

-10 байт благодаря nwellnhof!

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

Попробуйте онлайн!

Ах да, намного короче, чем мой предыдущий метод. Это блок анонимного кода, который возвращает список строк.

Объяснение:

{                                                   }   # 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 байта

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

Попробуйте онлайн!

¯2 ¯8 ¯14 байтов благодаря ngn !


∊'┌'(1↓⍵⍴'┬')'┐'->'┌┬┐'/⍨2⍵2-1
НГН

@ngn спасибо! Это виды гольфа, которые довольно понятны, но я никогда не знаю, предвидеть или не знаю, как их использовать
dzaima

наконец, мне удалось немного укоротить правую часть ... +⌿0=(×\⍺)∘.|⍳1+⍵-> ⊥¨⍨0=(⍵+1)⍴⍳⌽⍺. прием в обратном порядке теперь явно разрешен , так что вы также можете удалить
ngn

('┌┬┐'/⍨2⍵2-1)->'┌┬┐'[2,⍨×⍳⍵]
НГН

или даже лучше: ('┌┬┐'/⍨2⍵2-1)⍪⍉->'┌┐'@0⍵@0⍉'┬',
ngn


2

05AB1E , 51 байт

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

Не слишком доволен, I¯Qiεõ}}как обходной путь для пустых входных списков .. И, безусловно, может играть в гольф и в некоторых других частях ..

ПРИМЕЧАНИЕ. Использует сжатые целые числа, преобразованные в требуемые символы, поскольку непосредственное использование требуемых символов означает, что мне придется считать всю программу в UTF-8, увеличивая ее слишком сильно для всех встроенных символов 05AB1E.

Попробуйте онлайн или проверьте все тесты .

Объяснение:

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

Посмотрите эту подсказку 05AB1E (раздел Как сжать большие целые числа? ), Чтобы понять, почему •5·W4•есть 94749589и •áΣ=Yô•есть 948495169488.



@MagicOctopusUrn Сначала я тоже так думал вначале, но, к сожалению, этого не происходит (попробуйте сделать это с одним из других тестовых случаев с непустым списком). sиSработает, но, к сожалению, это байт больше, а не короче. Это потому, что целые числа сначала находятся в стеке, а строки - после. При ×этом не имеет значения, будет это int,stringили нет string,int, но с иэтим ожидает string,int.
Кевин Круйссен

О, я вижу, чувак, этот смущает, ха. Хорошая работа на этом, честно говоря, я потратил 10 минут, пытаясь понять, что происходит, пропустил этот лакомый кусочек и! Это будет полезно узнать в будущем, я не видел, чтобы он использовался раньше, чем один из ваших других ответов.
Волшебная Урна Осьминога

2

Древесный уголь , 50 байтов

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

Попробуйте онлайн! Ссылка на подробную версию кода. Символы рисования прямоугольников имеют 3-байтовое представление в Charcoal, поэтому длина приведенной выше строки составляет всего 40 символов. Объяснение:

≔EηΠ…η⊕κη

Рассчитайте накопленное произведение интервалов.

⪫┐┌×┬⊖θ↙

Напечатайте первый ряд отметок. Левый и правый символы неправильные, потому что результат отражается позже.

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

Рассчитайте количество интервалов, которые являются фактором для каждой отметки. Создайте строку s из половины этой длины и добавьте для нечетных длин. Выведите каждую строку вниз с последующими строками в предыдущих столбцах, т.е. в обратном порядке.

Отразите все, чтобы получить правителя в порядке слева направо.



2

Emacs Lisp , 303 байта

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

Используйте эту функцию как (f '(30 (5 2))).

Лучше читаемая версия:

(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

Желе ,  42  41 байт

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

Полная программа.
Попробуйте онлайн!

Или посмотрите комплект тестов.
Примечание: этот код был изменен из полной программы - ñ(следующая ссылка как диада) была заменена на (ссылка на индекс 1 как диада), чтобы нижний колонтитул мог вызывать его несколько раз ,

Как?

‘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

Рубин , 126 байт

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

Попробуйте онлайн!

Выглядит довольно многословно со всем этим each_slice , но пока подойдет, если мне не удастся найти подход к игре в гольф.

Принимает ввод как lдля длины, так и iдля интервалов, возвращает массив строк.


1

R , 175 170 байт

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

Попробуйте онлайн!

Берет пустые интервалы как 0, возвращает матрицу символов. Ссылка TIO отображает вывод довольно напечатано.


1

Haskell , 167 164 149 байт

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

Попробуйте онлайн! Слегка по гольфу другой подход от Ο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

Попробуйте онлайн! Есть еще некоторые увольнения, которые выглядят так, как будто они могут быть использованы, но до сих пор они выдерживали все дальнейшие попытки игры в гольф.


Предыдущее 167-байтовое решение аналогично обработке новой строки и, вероятно, немного лучше читается:

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

Попробуйте онлайн!


1
Другой подход на 158 байтов ( попробуйте онлайн! ), Вероятно, может быть сокращен еще немного, так как я плохо говорю на Хаскеле.
Οurous

@ Спасибо!
Лайкони

1

PowerShell , 152 байта

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}

Попробуйте онлайн!

раскатали:

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
Вы правы. 1) Я не видел правила, позволяющего завершать новую строку в конце. 2) и мне не нравится, что код иногда добавляет новую строку в конце, а иногда нет. :)
Маззи


0

Чистый , 221 201 195 162 байта

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

Попробуйте онлайн!

Возвращает список списков символов UTF-8 (в виде строк, поскольку Clean не имеет встроенной поддержки UTF-8).

Работает, генерируя первую строку, затем беря произведение префиксов из списка, представленного группами по два, и проверяет, какую метку рисовать, основываясь на том, разделяет ли продукт текущую позицию символа.

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]
        ]
    ]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.