任意间隔尺


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,11,7,5,3,2,1]

┌┐
│
│
│
│
╵

其他规则/说明

  • 输入和输出可以使用任何方便的格式
  • 标尺不必在大刻度上结束
  • 间隔列表可能为空
  • 第零刻度始终在所有间隔内。
  • 您可以假设标尺的长度和间隔始终为小于120的正整数
  • 尾随空格可以,但前导空格则不能。
  • 如果出于某种原因要使用ASCII空格以外的其他字符,则允许使用任何固定的单宽空格作为空格字符。

高尔夫快乐!


为了输出,我可以打印第一行,然后返回列列表吗?
无知的体现

@EmbodimentofIgnorance,我要拒绝。输出应保持一致。
Beefster

我们可以从单字节编码中提取出箱形绘图字符吗(前提是存在一个包含所需字符的字符)?
很有可能

任何方便的格式 ”-我们可以反向接受间隔列表吗?
ngn

@ngn:我不明白为什么不这样。如果那可以帮助您,那就去吧。
Beefster

Answers:


5

JavaScript(Node.js),123字节

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

在线尝试!

将此功能用作f(20)([5, 2])


谢谢Arnauld,节省了4个字节。


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

@ngn谢谢!这些是非常容易理解的高尔夫球,但我从来不知道会预期或知道其用途
dzaima

最后,我设法将最右边的部分缩短了 +⌿0=(×\⍺)∘.|⍳1+⍵--> ⊥¨⍨0=(⍵+1)⍴⍳⌽⍺。现在已经明确允许以相反的顺序接受,因此您还可以删除
ngn

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

甚至更好:('┌┬┐'/⍨2⍵2-1)⍪⍉->'┌┐'@0⍵@0⍉'┬',
ngn

2

Python 3中173个 172字节

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

在线尝试!


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


×S可以是и
魔术章鱼缸

@MagicOctopusUrn起初我也是这么想的,但是不幸的是,它并没有(只是尝试使用其他非空列表的测试用例之一)。sиS确实可以工作,但不幸的是,它更长而不是更短。这是因为整数首先在堆栈上,然后在字符串上。随着×不要紧无论是int,stringstring,int,但и它预计string,int
Kevin Cruijssen

哦,我明白了,这家伙真让人困惑哈。做得很好,说实话,我花了10分钟只是想弄清楚发生了什么,错过了那条花絮и!将来会很高兴知道这一点,在您回答其他问题之前我还没有看到它的用处。
魔术章鱼缸

2

木炭,50字节

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

在线尝试!链接是详细版本的代码。箱形绘图字符在木炭中以3字节表示,因此上述字符串只有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

完整程序。
在线尝试!

或查看测试套件
说明:此代码已从完整程序更改为- ñ(下一个链接为dyad)已替换为(索引1的链接为dyad),以使页脚可以多次调用它。

怎么样?

‘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

R175170字节

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

在线尝试!稍微golfed不同的方法Ο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字节的其他方法(可以在线尝试!)可能会缩短很多,因为我的Haskell说得不好。
很有可能

@噢感谢!
Laikoni

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)我不喜欢代码有时在末尾添加新行,有时却不行。:)
mazzy


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

通过生成第一行,然后取两个一组的列表前缀的乘积来工作,并根据乘积是否划分当前字符位置来检查要绘制的标记。

取消高尔夫:

$ 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]
        ]
    ]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.