任意の間隔ルーラー


25

長さと間隔のリストを取得し、線描画文字を使用して各間隔の長い目盛りでその長さのルーラーを出力するプログラムを作成します ┌ ┬ ┐ │ ╵

  • 出力の最初の行は0のためのダニで始めるべきとの長さのためにダニを有すると端と、の間のすべての文字のために使用されています。lengthこの最初の行には、合計+ 1個の線画文字が含まれます。
  • 入力間隔を使用て、入力間隔に基づいて、半角刻みでティックを垂直方向に長くする必要があります。
  • 間隔は、その前の間隔に対して、最小から最大の順にリストされます。詳しく説明するには:
    • 最初の間隔は、2番目に小さい間隔(最小間隔は1)にある基本ティック(最初の行-ティックごとに1文字)の数を示します。たとえば、[3]は3文字ごとに半角だけ長くなります。
    • 2番目以降の間隔は、次に小さい間隔に基づいています。たとえば、[3、5]は15文字ごとに完全な文字だけ伸び、[3、5、2]は30文字ごとに1文字半ずつ伸びます。
    • サブ間隔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]

┌┐
│
│
│
│
╵

その他の規則/注意事項

  • 入力と出力は任意の便利な形式を使用できます
  • 定規は大目盛りで終わる必要はありません
  • 間隔リストは空の場合があります
  • 0番目のティックは常にすべての間隔内にあります。
  • ルーラーの長さと間隔は常に120未満の正の整数であると仮定できます。
  • 末尾の空白は問題ありませんが、先頭の空白はそうではありません。
  • 何らかの理由でASCIIスペース以外のものを使用する場合は、固定シングル幅スペースをスペース文字として使用できます。

ハッピーゴルフ!


出力の場合、最初の行を印刷してから列のリストを返すことはできますか?
無知の具体化

@EmbodimentofIgnorance、私はノーと言うつもりです。出力は一貫している必要があります。
ビーフスター

ボックス描画文字を1バイトエンコーディングから取得できますか(必要なものを含むものが存在する場合)。
Οurous

便利なフォーマット」-逆の順序で間隔リストを受け入れることができますか?
ngn

@ngn:なぜそうなのかわかりません。それがどういうわけかあなたを助けるならば、それのために行きなさい。
ビーフスター

回答:



3

Perl 6の130の122 102 92バイト

nwellnhofのおかげで-10バイト!

{'┌'~'┬'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ありがとう!これらはかなり理解しやすいですが、私はの使用予期または知っている知っていることはありませんgolfsの種類があります
dzaima

最後に、右端の部分を少し短くすることができました...- +⌿0=(×\⍺)∘.|⍳1+⍵> ⊥¨⍨0=(⍵+1)⍴⍳⌽⍺逆順での受け入れは現在明示的に許可されているため、次を削除することもできます
ngn

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

またはそれ以上:('┌┬┐'/⍨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でカウントする必要があるため、必要な文字に変換された圧縮整数を使用します。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

Ý             # 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•is 94749589および•áΣ=Yô•is を理解してください948495169488


×S可能性がありますи
マジックタコUr

@MagicOctopusUrn最初私も最初はそう思っていましたが、残念ながらそうではありません(空でないリストを持つ他のテストケースの1つで試してみてください)。sиS動作しますが、残念ながら、短いのではなく、長いバイトです。整数が最初にスタックにあり、その後に文字列があるためです。で×、それそれはだかどうかは関係ありませんint,stringstring,int、しかし、でи、それは期待しstring,int
ケビンクルーッセン

なるほど、これは紛らわしいですね。素晴らしく、正直に言って、何が起こっているのかを理解しようとして10分を費やしましたи。それは将来知っておくと良いでしょう。他の答えの前に使われるのを見たことがありませんでした。
マジックタコop

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

完全なプログラム。
オンラインでお試しください!

またはテストスイートを見る
ください注:このコードは完全なプログラムから変更されています- ñ(ダイアドとしての次のリンク)は(フッターによって複数回呼び出されるように(ダイアドとしてのインデックス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

R175 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

ハスケル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バイトの異なるアプローチ(オンラインで試してみてください!)は、Haskellが上手に話せないため、おそらくかなり短縮できます。
Οurous

@Ο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サポートがないため、文字列として)。

最初の行を生成してから、2つのグループで提供されるリストのプレフィックスの積を取得し、その積が現在の文字位置を分割するかどうかに基づいて描画するマークを確認します。

ゴルフをしていない:

$ 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]
        ]
    ]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.