Hiển thị một kiểm đếm (trong các cơ sở khác nhau)


16

Kiểm đếm là một hệ thống đếm đơn giản hoạt động ở cơ sở 5. Có nhiều hệ thống kiểm đếm khác nhau được sử dụng trên khắp thế giới, nhưng hệ thống được sử dụng ở hầu hết các quốc gia nói tiếng Anh có lẽ là đơn vị đếm đơn giản nhất bằng cách đánh dấu các đường thẳng đứng, sau đó cho mỗi điểm thứ 5 đặt một đường ngang qua bộ sưu tập bốn trước đó. Điều này tập hợp các dấu kiểm đếm trong nhóm 5 (và làm cho chúng dễ dàng hơn để đếm nhanh).

Bạn sẽ viết một chương trình hiển thị các dấu kiểm đếm lên đến một giá trị nhất định. Nhưng, kiểm đếm chỉ trong cơ sở 5 là nhàm chán! Do đó, chương trình của bạn cũng sẽ có thể hiển thị các số đo trong các căn cứ khác nhau.

Đầu vào

Đầu vào sẽ là một hoặc hai giá trị nguyên không âm được phân tách bằng dấu phẩy (ví dụ 9hoặc 8,4). Số đầu tiên là giá trị sẽ được hiển thị bằng kiểm đếm. Giá trị thứ hai là cơ sở của kiểm đếm. Nếu giá trị thứ hai không được đưa ra, sử dụng cơ sở 5 .

Đầu ra

Đầu ra sẽ là giá trị được nhập vào được biểu thị dưới dạng dấu kiểm nghệ thuật ASCII. Dưới đây là một số ví dụ bạn có thể kiểm tra chương trình của mình - đầu ra của bạn phải khớp chính xác với chúng!

Đầu vào: 12hoặc12,5

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

Đầu vào: 7,3

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

Đầu vào: 4,2

 |   |
-+- -+-
 |   |

Đầu vào: 6,1hoặc 6,10(chú ý các khoảng trắng hàng đầu)

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

Cũng lưu ý rằng cơ sở 1 được dự định là không nhất quán - chỉ nên sử dụng các đường thẳng đứng.

Nếu một trong hai giá trị được nhập là 0, sẽ không có đầu ra nào (và chương trình của bạn sẽ kết thúc một cách duyên dáng).

Quy tắc

  • Đây là , do đó, việc thực hiện chính xác ngắn nhất (tính bằng byte) sẽ thắng.
  • Đầu vào / đầu ra có thể ở bất kỳ phương tiện phù hợp nào (ví dụ: stdin / stdout, tệp ...).
  • Đầu vào có thể ở dạng nhiều đối số dòng lệnh hoặc được phân tách bằng dấu cách, v.v. nếu nó phù hợp hơn với ngôn ngữ đích của bạn.
  • Trailing newlines được cho phép trong đầu ra. Không gian lưu trữ là không. Quy tắc này chỉ áp dụng khi có đầu ra (nghĩa là không phải khi giá trị nhập vào là 0).
  • Mã của bạn phải mặc định là cơ sở 5 khi không có cơ sở nào được nhập.

3
Không nên đầu ra của 6,1trông giống như -+- -+- -+- -+- -+- -+-?
Peter Taylor

3
Nếu bạn nói "Đầu vào sẽ là một hoặc hai giá trị nguyên dương được phân tách bằng dấu phẩy (ví dụ: 9 hoặc 8.4)." sau đó chúng ta sẽ có thể coi đó là một điều nhất định và không phải lo lắng về "Chương trình của bạn phải mạnh mẽ - bạn nên xác thực đầu vào ..." ngoài việc xử lý một hoặc hai số.
AndoDaan

1
@PeterTaylor -+-sẽ đại diện cho hai, bởi vì có một đường thẳng đứng và điểm ngang qua nó. Cơ sở 1 sẽ chỉ có các đường thẳng đứng. @AndoDaan bị tấn công.
Sean Latham

Được --- --- --- --- --- ---rồi Để thống nhất với các căn cứ khác, bạn nên đặt một cú đánh ngang qua b-1các đường thẳng đứng. Nếu nó có ý định không nhất quán, bạn nên nói rõ điều đó.
Peter Taylor

Tôi đã làm điều đó. Xin lỗi, tôi nghĩ đó là ngụ ý.
Sean Latham

Câu trả lời:


4

CJam 103 85 72 ký tự

Hãy thử tại http://cjam.aditsu.net/ .

nguyên

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

Hoạt động bằng cách xác định một bộ kiểm đếm có khoảng trắng, đường thẳng và l cho các khoảng trắng nên giữ nguyên khoảng trắng. Sau đó tận dụng chức năng er (tranliteration) để tạo dòng thứ hai. Phần không hiệu quả nhất là xử lý các trường hợp đặc biệt 1 và 0. Sẽ chỉnh sửa khi tôi cải thiện nó. Mẹo tôi mất quá nhiều thời gian để nhận ra: vì đầu vào thứ hai là 1 giống như vô cực hoặc đầu vào +1 đầu tiên, xác định lại nó khi nó bằng 1 tiết kiệm rất nhiều công việc.

cải thiện nhất cho đến nay với dấu phẩy được phân cách

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

cải thiện nhất cho đến nay với đầu vào phân cách không gian

Đương nhiên, vì CJam thực sự được thiết kế cho đầu vào phân cách không gian. Đặt đầu vào ở 20 3 thay vì 20,3 là một lợi ích rất lớn.

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

5

Python 2 - 111 108 119 144 140 136 135 134 - Hãy thử

Ok, hãy thử xem:

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)

Chỉnh sửa: Tôi đã bỏ qua rằng sẽ không có đầu ra nếu n==0hoặc b==0. Điều này có giá 11 ký tự. :

Chỉnh sửa: Ok, sau khi sửa vấn đề thứ hai được đề cập trong các bình luận, giải pháp của tôi về cơ bản đã hội tụ đến vấn đề từ BeetDemGuise.


Điều này in các dòng mới khi một trong hai đầu vào (hoặc cả hai) bằng 0 mà theo thách thức là không mong muốn. Ngoài ra, nếu chỉ có một số được nhập vào chương trình thì sao?
BeetDemGuise

1
Điều này không thành công khi giá trị thứ hai bị bỏ qua ( bnên là 5 trong trường hợp này). Tôi sẽ làm cho nó rõ ràng hơn trong câu hỏi. Chỉnh sửa: oh, đừng bận tâm, bạn đã sửa nó giống như tôi đã nhận xét này!
Sean Latham

Đây là Python gì?
Beta Decay

Đó là Python 2.7.8. - Ồ, cuối cùng đã có một lỗi nhỏ ...
Falko

1
Nếu đó là Python 2.x, bạn không thể lưu thêm một ký tự bằng cách sử dụng n/bthay vì n//b?
Emil

5

Bash, 239 228 199 189 188

Đây là nỗ lực của tôi, nó có thể được đánh gôn rất nhiều.

Lưu ý: dòng thứ hai không trừ 5 từ 2, nó đặt giá trị mặc định nếu $2trống!

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}làm việc thay vì `seq $n`?
FUZxxl

@FUZxxl rất tiếc là không, h=8;echo {1..$h}đầu ra{1..8}

Điều đó không tốt.
FUZxxl

3

Con trăn - 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

Chương trình này khá đơn giản:

  • Nhận đầu vào và cố gắng giải nén vào t,b. Nếu thất bại, chỉ cần gán các giá trị chính xác.
  • Nếu cơ sở là 1, thay đổi giá trị của nó thành một cái gì đó có thể xử lý tất cả các đường thẳng đứng một cách dễ dàng ( t+1).
  • Đặt một số biến và tạo các phần dưới cùng và trên cùng của các nàng tiên.
  • In ra các số đo nếu cả hai tbkhác không.

CHỈNH SỬA 1: Sử dụng inputchức năng thay vì raw_inputsau khi chơi xung quanh.

EDIT 2: Cảm ơn Falko đã chỉ ra một lỗi nhỏ với kiểm tra khác không của tôi. Bây giờ mã của chúng tôi về cơ bản là giống hệt nhau, ít một số tên biến và một số logic nhỏ.

EDIT 3: Nhờ cách Python so sánh trình tự và các loại khác nhau , chúng ta có thể so sánhi với a listđể có phiên bản ngắn hơn của try...exceptkhối.

Đây là phiên bản chưa được chỉnh sửa:

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ôi nghĩ t&bFalsecho 10,5. Nếu không các giải pháp của chúng tôi đang hội tụ! ;)
Falko

@Falko Bạn đúng cả hai tính! Bạn biết những gì họ nói về tâm trí tuyệt vời.
BeetDemGuise

Sẽ thật tuyệt nếu chúng ta có thể tìm ra một cách ngắn để kiểm tra xem ilà vô hướng hay danh sách. Sau đó chúng ta có thể thả try ... exceptquái vật.
Falko

@Falko Tôi nghĩ rằng tôi đã tìm thấy kiểm tra 1byte tốt hơn. A listluôn luôn lớn hơn một int. Ngoài ra, lists được so sánh theo thứ tự từ điển. Vì vậy, nếu chúng ta so sánh [0]<iđiều này sẽ luôn trả về Falsenếu ilà một số và Truenếu ilà một danh sách (với phần tử đầu tiên khác không).
BeetDemGuise

1
Tuyệt quá! Tôi tiếp tục rút ngắn cách tiếp cận của bạn. Làm việc nhóm tốt :)
Falko

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

Ít chơi gôn hơn:

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

Bạn có thể tiết kiệm một vài bằng cách làm imột long, do đó bạn không cần phải khai báo nó riêng rẽ. Một vài điều nữa bằng cách thực hiện i++%b>0trong các vòng lặp của bạn thay vì tăng nó một cách riêng biệt (và i++<n%btrong vòng lặp thứ ba). Một số khác bằng cách sử dụng b=b<2?(int)2e9:b.
Geobits

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

vô dụng

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

hiển thị các đường ngang thay vì các đường thẳng đứng cho cơ sở 1 :(
tiếng Trung Quốc perl goth

@chineseperlgoth vâng, đó là một trong những yêu cầu. Xin vui lòng đọc ý kiến ​​về Q.
Fozi

3

C - 193

Tôi rất xin lỗi Đối phó với trường hợp đặc biệt cho 1 là một chút hack, vì vậy tôi đoán điều này có thể được đánh gôn nhiều hơn với cách tiếp cận tốt hơn. Ngoài ra, mã này bao gồm một dòng mới ở đầu ra, vì vậy nếu điều này không được phép, xin vui lòng cho tôi biết.

Tất nhiên, định nghĩa rất xấu xí luôn luôn giúp đỡ :)

Số lượng ký tự chỉ bao gồm các không gian cần thiết và dòng mới.

#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;}
}

Mã của bạn dường như in dòng mới khi một trong các giá trị bằng không. Điều này là không được phép. Giải pháp của bạn không phù hợp.
FUZxxl

@FUZxxl Bạn nói đúng, tôi đã bỏ lỡ điều đó! Sửa chữa nhanh chóng xấu này sẽ phải làm ngay bây giờ. Tôi hy vọng tôi có thời gian sớm để tìm ra một cách tốt hơn.
Allbeert

Tôi chắc rằng bạn có thể tiết kiệm một vài ký tự bằng cách thay thế printfvới puts, và thay thế returnvới một nhà điều hành ternary.
millinon

@millinon Vấn đề với putsnó là nó luôn thêm một dòng mới :(. Và đối với toán tử ternary, không thể thêm returns hoặc fors bên trong chúng!. Nhận xét của bạn đã cho tôi ý tưởng để tiết kiệm thêm một vài ký tự dễ dàng bằng cách loại bỏreturn mặc dù. Cảm ơn!
Allbeert

2

C # 271byte

Không phải là ngắn nhất, tôi không thể đánh golf đọc đầu vào do nó cần chấp nhận 0 làm đầu vào.

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;}}

Mã định dạng:

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 - 219 203 byte

Tôi đã tạo ra các bản sao của b bản sao của "|", sau đó thêm bản sao của "|" cuối cùng. Tôi cảm thấy như có lẽ tôi nên đi cùng với "'" "đến" chuỗi "một lần.

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)

vô dụng:

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!

Mẫu vật:

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
Bạn có thể đăng một phiên bản dễ đọc và dễ đọc hơn không? Chơi golf ở Lua có vẻ thú vị!

@Alessandro đã làm xong. Và cảm ơn, nó đã tìm thấy một vài điều tôi đã bỏ lỡ.
AndoDaan

1

JavaScript (193)

Điều này có thể quá phức tạp.

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)

Phiên bản đã bình luận

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

Con trăn - 127 123 122

Chỉ cần lẻn vào với một phiên bản python ngắn hơn một chút.

chỉnh sửa: Đã sửa 0 không in gì và khởi động lại, kết thúc cùng chiều dài

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 ký tự)

Dòng mới ngay trước đây exitchỉ dành cho mức độ dễ đọc.

#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("| ")}

scanfsử dụng không biết xấu hổ bị đánh cắp từ Allbeert. Lưu ý rằng giải pháp này không biên dịch với gcc vì nó cố gắng thực thi một nguyên mẫu không tồn tại choexit . Biên dịch với trình biên dịch C hoạt động như thế nào tcc. Ngoài ra, chức năng này có thể hoặc không thể hoạt động trên nền tảng 64 bit. Sử dụng cẩn thận.

Đây là cách thực hiện vô căn cứ ban đầu này dựa trên:

#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

Python 2 , 134 126 123 114 byte

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)

Hãy thử trực tuyến!

Câu hỏi cũ tôi biết nhưng rất vui khi có một đi. Cơ hội để thử một vài thủ thuật tôi đã học được từ khi tham gia.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.