集計を表示します(さまざまなベースで)


16

タリーは、ベース5で機能するシンプルなカウントシステムです。世界中でさまざまな集計システムが使用されていますが、ほとんどの英語圏の国で使用されているものは、おそらく最もシンプルです。 5番目のマークごとに、前の4つのコレクションに水平線が引かれます。これにより、タリーマークが5つのグループにクラスター化されます(また、カウントが簡単になります)。

指定した値までの集計マークを表示するプログラムを作成します。しかし、ベース5だけで集計するのは退屈です!したがって、プログラムは異なるベースで集計を表示することもできなければなりません。

入力

入力は、コンマ(またはまたは)で区切られた1つまたは2つの負でない整数値です。最初の数値は、集計によって表示される値です。2番目の値は集計のベースです。2番目の値が指定されていない場合、基数5を使用します98,4

出力

出力は、ASCIIアートタリーマークとして表される入力値になります。以下に、プログラムをテストできるいくつかの例を示します-出力はそれらと正確に一致するはずです!

入力:12または12,5

 | | | |   | | | |   | |
-+-+-+-+- -+-+-+-+-  | |
 | | | |   | | | |   | |

入力: 7,3

 | |   | |   |
-+-+- -+-+-  |
 | |   | |   |

入力: 4,2

 |   |
-+- -+-
 |   |

入力:6,1または6,10(先頭のスペースに注意してください)

 | | | | | |
 | | | | | |
 | | | | | |

また、ベース1は一貫性がないことを意図していることに注意してください-垂直線のみを使用する必要があります。

入力された値のいずれかが0の場合、出力はまったくありません(プログラムは正常に終了するはずです)。

ルール

  • これはなので、最短の正しい実装(バイト単位)が優先されます。
  • 入力/出力は、任意の適切な媒体(たとえば、stdin / stdout、file ...)にあります。
  • 入力は、ターゲット言語により適している場合、複数のコマンドライン引数の形式にするか、スペースなどで区切ることができます。
  • 出力では末尾の改行が許可されます。末尾のスペースはそうではありません。このルールは、出力がある場合にのみ適用されます(つまり、入力値が0の場合は適用されません)。
  • 基数が入力されていない場合、コードはデフォルトで基数5にする必要があります。

3
の出力は6,1もっと似ているべきではありません-+- -+- -+- -+- -+- -+-か?
ピーターテイラー14

3
「入力は、カンマで区切られた1つまたは2つの正の整数値(9または8,4など)になります」と述べた場合。そうすれば、1つまたは2つの数字を処理する以外に、「プログラムは堅牢である必要があります-入力を検証する必要があります...」ということを心配する必要はありません。
AndoDaan

1
@PeterTaylor -+-は2つを表します。これは、垂直線と水平線が通っているからです。ベース1には垂直線のみがあります。@AndoDaanが修正しました。
ショーンレイサム14

[OK]を、--- --- --- --- --- ---それから。他のベースとの一貫性を保つために、b-1垂直線を水平方向に打つ必要があります。矛盾することを意図している場合は、明示的に述べる必要があります。
ピーターテイラー14

私はそれをやった。申し訳ありませんが、私はそれが暗示されていると思った。
ショーンレイサム14

回答:


4

CJam 103 85 72文字

http://cjam.aditsu.net/で試してください

元の

q","/(i:A\_,{~i}{;5}?:B_@*{(_{" |"*S"l"++AB/*AB%}{;MA}?\:J" |l""-+ "er\" |"*N+_J\+@2$+@J\+++"l"Ser}{;}?

スペースを保持する必要があるスペースに対して、スペース、ライン、およびlを含む1セットの集計を定義することによって機能します。次に、er(翻字)関数を利用して2行目を作成します。最も非効率的な部分は、1および0の特殊なケースを処理することです。改善したら編集します。ヒント:2番目の入力が1の場合は無限大または1番目の入力が+1の場合と同じであるため、1に等しい場合に再定義すると多くの作業を節約できます。

これまでのところ、カンマ区切りで最も改善されています

l",":G/(i:A\_5a?~i:B_@*{(_" |":K*\{SG++AB/*AB%}{A}?\_KG+"-+ "er[\GSer_@@M]\K*N+*}{;}?

これまでのところスペースで区切られた入力で最も改善されています

当然、CJamはスペースで区切られた入力用に設計されています。入力を20,3ではなく20 3に配置することは大きな利点です。

ri:Aq_5s?S-i(_)A)?:B*{B(" |":K*STs++ABmd@@*_K"-+"er[\_@@M]\K*N+*TsSer}M?

5

パイソン2 - 111 108 119 144 140 136 135 134 - それを試してみてください

OK、試してみましょう:

i=input()
n,b=[(i,5),i][i>[]]
o=b-1
a=[n,n%b][b>1]*' |'
m=(b>1)*n/b
s=(' |'*o+'  ')*m+a
print(s+'\n'+('-+'*o+'- ')*m+a+'\n'+s)*(b*n>0)

編集:n==0またはの場合、出力が表示されないことを見落としていましたb==0。これには11文字かかります。:(

編集: OK、コメントで言及されている2番目の問題を修正した後、私のソリューションは基本的にBeetDemGuiseのソリューションに収束しました。


これは、入力のいずれか(または両方)がゼロのときに改行を出力しますが、チャレンジによっては望ましくありません。また、プログラムに入力される数字が1つだけの場合はどうなりますか?
BeetDemGuise 14

1
2番目の値を省略すると、これは失敗します(bこの場合は5にする必要があります)。質問でそれをより明確にします。編集:ああ、気にしないでください、あなたは私がこのコメントをしたようにそれを修正しました!
ショーンレイサム14

これはどのPythonですか?
ベータ崩壊

Python 2.7.8です。-ああ、非常に最後の小さな間違いが...あった
ファルコ

1
Python 2.xの場合n/bn//b?の代わりにを使用してもう1つの文字を保存できませんでした。
エミール14

5

バッシュ、 239228199189 188

ここに私の試みがあります、それはたくさんゴルフすることができました。

注:2行目は2から5を減算せず、空の場合はデフォルト値を設定します$2

n=$1
b=${2-5}
((n<1&b<1))&&exit
while ((n>b&b>1));do
n=$[n-b]
x+=\
y+=-
for i in `seq $[b-1]`;{
x+='| '
y+=+-
}
x+=\
y+=\
done
for j in `seq $n`;{
x+=' |'
y+=' |'
}
echo -e "$x\n$y\n$x"

{1..$n}の代わりに仕事を`seq $n`
FUZxxl

@FUZxxl残念ながらそうではありません、h=8;echo {1..$h}出力{1..8}

それは良いことではありません。
FUZxxl

3

Python- 171 143

i=input();t,b=i if[0]<i else(i,5);b=[b,t+1][b==1];l,d,m,o=' |',t/b,t%b,b-1;r=(l*o+'  ')*d+l*m
if t*b>0:print r,'\n',('-+'*o+'- ')*d+l*m,'\n',r

プログラムは非常に簡単です。

  • 入力を取得し、に解凍してみてくださいt,b。それが失敗した場合、単純に正しい値を割り当てます。
  • ベースがの場合、1すべての垂直線を簡単に処理できる値に変更します(t+1)。
  • いくつかの変数を設定し、集計の下部と上部のセクションを作成します。
  • 両方の場合は集計をプリントアウトtし、b非ゼロです。

編集1:いくつか遊んだ後ではinputなく、関数を使用しますraw_input

編集2:私のゼロ以外のチェックで小さなバグを指摘してくれたファルコに感謝します。これで、コードは基本的に同一になり、変数名と小さなロジックが減りました。

編集3:Pythonがシーケンスと異なるタイプを比較する方法のおかげでi、a listと比較してtry...exceptブロックの短いバージョンを取得できます。

以下は、バージョン化されていないバージョンです。

i=input()

# If True, `i` must be a list
if [0]<i:
    t,b=i
# Otherwise, we know its a number (since `list` comes after `int` lexicographically.)
else:
    b=5
    t=i

b = b if b==1 else t+1
l=' |'
d=t/b
m=t%b
o=b-1

r=(l*o+'  ')*d+l*m
if t and b:
    print r,'\n',('-+'*o+'- ')*d+l*m,'\n',r

私が考えてt&bいるFalse10,5のために。そうでなければ、私たちのソリューションは収束しています!;)
ファルコ14

@Falkoあなたは両方の点で正しいです!あなたは彼らが偉大な心について言っていることを知っています。
BeetDemGuise 14

iスカラーかリストかをテストする簡単な方法を見つけることができれば、本当に素晴らしいことです。その後、try ... exceptモンスターをドロップできます。
ファルコ14

@Falko 1byteのより良いチェックを見つけたと思う。A listは常にintより大きいです。また、listsは辞書式順序で比較されます。したがって、比較する場合、[0]<iこれは常にFalseif iが数値でTrueif iがリスト(ゼロ以外の最初の要素を持つ)を返します。
BeetDemGuise

1
すごい!あなたのアプローチをさらに短縮しました。素晴らしいチームワーク!:)
ファルコ

3

Java、343

class C{public static void main(String[]a){long n=new Long(a[0])+1,b=a.length>1?new Long(a[1]):5;if(b>0){if(b<2)b=(int)2e9;int i;for(i=1;i<n;i++)p(i%b>0?" |":"  ");p("\n");for(i=1;i<n-n%b;i++)p(i%b>0?"-+":"- ");if(n>b)p("- ");for(i=1;i<n%b;i++)p(" |");p("\n");for(i=1;i<n;i++)p(i%b>0?" |":"  ");}}static void p(String s){System.out.print(s);}}

少ないゴルフ:

class C {
  public static void main(String[] a) {
    long n=new Long(a[0])+1, b=a.length>1 ? new Long(a[1]) : 5;
    if(b>0) {
      if(b<2) b=(int)2e9; // if the base is 1, pretend the base is 2 billion
      int i;
      for(i=1;i<n;i++) p(i%b>0 ? " |" : "  ");
      p("\n");
      for(i=1;i<n-n%b;i++) p(i%b>0 ? "-+" : "- ");
      if(n>b) p("- ");
      for(i=1;i<n%b;i++) p(" |");
      p("\n");
      for(i=1;i<n;i++) p(i%b>0 ? " |" : "  ");
    }
  }
  static void p(String s) {
    System.out.print(s);
  }
}

aを作成iするlongことでいくつかを保存できるため、個別に宣言する必要はありません。i++%b>0ループを個別にインクリメントするのではなく、ループで(およびi++<n%b3番目のループで)実行することで、さらにいくつかのことができます。を使用して別のものb=b<2?(int)2e9:b
ジオビット14

3

Perl- 167 165 156

my($n,$b)=($ARGV[0]=~/(\d+)(?:,(\d+))?/,5);print$b>1?map{join(" ",($_ x($b-1))x int($1/$b)," | "x($1%$b))."\n"}(" | ","-+-"," | "):join" ",("---")x$1if$1*$b

食べない

my($n,$b) = ($ARGV[0] =~ /(\d+)(?:,(\d+))?/, 5);
print($b>1 ?
    map{ 
        join(" ",($_ x ($b-1)) x int($1/$b)," | " x ($1%$b))."\n"
    } (" | ","-+-"," | ") :
    join " ", ("---") x $1
) if $1 * $b

ベース1の垂直線の代わりに水平線を表示します:(
chinese perl goth 14

@chineseperlgothはい、それは要件の1つです。Qに関するコメントをお読みください。
Fozi 14

3

C-193

ごめんなさい。1の特別なケースに対処するのは少し悪いハックだったので、より良いアプローチでこれをもっとゴルフできると思います。また、このコードには出力の先頭に新しい行が含まれているため、これが許可されていない場合はお知らせください。

もちろん、非常にい見た目は常に助けになります:)

文字数には、必要なスペースと改行のみが含まれます。

#define P printf(
#define L P" |")
#define A P"\n");for(i=0;i<a;)b==1?i++,L:i++&&i%b==0?P
i;
main(a,b)
{
    scanf("%d,%d",&a,&b)<2?b=5:!b?a=0:a;
    if(a){
    A"  "):L;
    A"- "):a%b&&i>a/b*b?L:P"-+");
    A"  "):L;}
}

値の1つがゼロの場合、コードは改行を印刷するようです。これは明示的に禁止されています。ソリューションが適合していません。
FUZxxl

@FUZxxlそうですね、私はそれを見逃しました!この悪いクイック修正は今のところしなければならないでしょう。すぐにもっと良い方法を見つける時間があることを願っています。
Allbeert

私はかなりあなたが交換することにより、いくつかの文字を保存することができると確信していprintfputs、および交換return三項演算子で。
ミリノン14

@millinonの問題putsは、毎回新しい行を追加することです:(そして、三項演算子の場合、その中にreturnsまたはfors を追加することはできません!。簡単に除去することによって、returnしかしをありがとうございました。!
Allbeert

2

C#271バイト

最短ではありませんが、入力として0を受け入れる必要があるため、入力の読み取りをゴルフできませんでした。

using C=System.Console;class P{static void Main(){var L=C.ReadLine().Split(',');int t=int.Parse(L[0]),f=L.Length>1?int.Parse(L[1]):5,r=3,i;for(var R="";t*f>0&r-->0;C.WriteLine(R.TrimEnd()))for(R="",i=0;i<t;R+=r==1&i++<t-t%f?(i%f<1?"- ":"-|"):i%f<1?"  ":" |")f+=f<2?t:0;}}

フォーマットされたコード:

using C=System.Console;

class P
{
    static void Main()
    {
        var L=C.ReadLine().Split(',');
        int t=int.Parse(L[0]),f=L.Length>1?int.Parse(L[1]):5,r=3,i;

        for(var R="";t*f>0&r-->0;C.WriteLine(R.TrimEnd()))
            for(R="",i=0;i<t;R+=r==1&i++<t-t%f?(i%f<1?"- ":"-|"):i%f<1?"  ":" |")
                f+=f<2?t:0;
    }
}

1

Lua- 219203バイト

「|」のbコピーのdコピーを作成し、「|」のrコピーを追加しました 最後に。多分、「|」を文字列に1つずつ「タリーアップ」していくべきだったと思います。

l=' |'s=string.rep _,_,a,b=io.read():find'(%d+)%D*(%d*)'b=tonumber(b)or 5 d=(a-a%b)/b f=b>1 and s(s(l,b-1)..'  ',d)g=b>1 and s(s('-+',b-1)..'- ',d)r=b>1 and a%b or a e=s(l,r)..'\n'print(f..e..g..e..f..e)

なし:

l=' |'          --the base string
s=string.rep    --string.rep will be used a lot, so best shorten it

_,_,a,b=io.read():find'(%d+)%D*(%d*)' --reads a,b I'm probably way of the mark with this one

b=tonumber(b)or 5

d=(a-a%b)/b -- shorter than math.floor(a/b), d equal the vertical mark

f=b>1 and s(s(l,b-1)..'  ',d) or '' --creates d multiples of b multiples of "|" more or less
g=b>1 and s(s('-+',b-1)..'- ',d)or''--same as above but with the middle "-+-"

r=b>1 and a%b or a --idk maybe i should set r before d(a- a%b )/b

e=s(l,r)..'\n'  -- makes the remainder string, notice that if b==1  then e will output all the "|" 

print(f..e..g..e..f..e) -- here's where the real magic happens!

サンプル:

c:\Programming\AnarchyGolfMine>lua test.lua
13,5
 | | | |   | | | |   | | |
-+-+-+-+- -+-+-+-+-  | | |
 | | | |   | | | |   | | |


c:\Programming\AnarchyGolfMine>lua test.lua
6,2
 |   |   |
-+- -+- -+-
 |   |   |


c:\Programming\AnarchyGolfMine>lua test.lua
18,1
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |

1
わずかに読みやすく、権利のないバージョンを投稿できますか?ルアでのゴルフは面白そう!

@アレッサンドロ完了。おかげで、私が見逃したいくつかのことが見つかりました。
AndoDaan

1

JavaScript(193)

これは非常に複雑かもしれません。

s=prompt().split(",");a=+s[0];b=s[1];b=b?+b:5;o=b>1;v=" | ";q=w="";for(g=~~(a/b),c=o?a-g:a;g+1;g--,q+=" ",w+=" ")for(i=o;c&&i<b;i++)c--,q+=v,w+=g&&o?"-+-":v;if(a&&b)console.log(q+'\n'+w+'\n'+q)

コメント版

s=prompt().split(",");
a=+s[0];
b=s[1];
b=b?+b:5;   // convert b to int and default to 5
o=b>1;      // special handling for b0 and b1
v=" | ";
q=w="";
// calculate number of lines and number of groups
for(g=~~(a/b),c=o?a-g:a;g+1;g--,q+=" ",w+=" ")
    for(i=o;c&&i<b;i++)
        c--,  // decrease line count
        q+=v,
        w+=g&&o?"-+-":v; // use " | " for last group and "-+-" for others
if(a&&b) // handle b0
    console.log(q+'\n'+w+'\n'+q)

1

Python- 127 123 122

わずかに短いpythonバージョンに忍び込みます。

編集:0が何も印刷しないと修正し、同じ長さになってしまう

k=input()
k=i,j=((k,5),k)[k>[]]
for m in[' |','-+',' |']*all(k):
 print(m*(j-1)+m[0]+' ')*(i/j*(j>1))+' |'*(i%(j+(j<2)*i))

0

C(207文字)

直前の改行exitは読みやすくするためのものです。

#define P printf(
#define t(v)for(a=c;b<=a;a-=b)a-c&&P" "),P v+1),q(b,v);q(a," |");P"\n");
q(n,c){while(n--)P c);}a;b;c;main(){scanf("%d,%d",&c,&b)<2?b=5:0;b&&c||
exit();b==1?b=32767:0;t("| ")t("+-")t("| ")}

scanfAllbeertから盗まれた使用恥知らず。このソリューションは、gccを使用してコンパイルしないことに注意してください。exit。のような動作するCコンパイラでコンパイルしtccます。また、この関数は64ビットプラットフォームで動作する場合と動作しない場合があります。注意して使用してください。

以下は、これに基づいた元の未実装の実装です。

#include <stdio.h>
#include <stdlib.h>

static void
tally_line(int base, int count, const char *str)
{
     int follower = 0, i;

     /* full tallies first */
     for (; count >= base; count -= base) {
          if (follower++)
               putchar(' ');

          /* only print second character */
          printf(str + 1);

          for (i = 0; i < base; i++)
               printf(str);
     }

     /* partial tally */
     for (i = 0; i < count; i++)
          printf(" |");

     /* newline */
     puts("");
}

extern int
main(int argc, char **argv)
{
     int base, count;

     /* do away with program name */
     count = atoi(*++argv);

     base = argc - 3 ? 5 : atoi(*++argv);

     /* remove 0 later */
     base | count || exit(0);

     /* a crossed-out tally never appears for large numbers */
     if (base == 1)
          base = 32767;

     tally_line(base, count, "| ");
     tally_line(base, count, "+-");
     tally_line(base, count, "| ");

     return (EXIT_SUCCESS);
}

0

パイソン2134の 126 123 114バイト

lambda i,j=5,a=" |":"\n".join(("",(a*~-j+"  ","-+"*~-j+"- ")[x%2]*(i/j))[j>1]+a*(i,i%j)[j>1]for x in(0,1,2)if i*j)

オンラインでお試しください!

私が知っている古い質問ですが、とにかくやってみるのは楽しいです。入社してから学んだいくつかのトリックを試すチャンス。

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