Tampilkan hitungan (dalam berbagai basis)

16

Tallying adalah sistem penghitungan sederhana yang bekerja di basis 5. Ada berbagai sistem penghitungan yang berbeda yang digunakan di seluruh dunia, tetapi sistem penghitungan yang digunakan di sebagian besar negara berbahasa Inggris mungkin merupakan yang paling sederhana - unit penghitungan dengan menandai garis vertikal, lalu untuk setiap tanda ke-5 letakkan garis horizontal melalui koleksi sebelumnya yang terdiri dari empat. Ini mengelompokkan tanda penghitungan dalam kelompok 5 (dan membuatnya lebih mudah untuk dihitung dengan cepat).

Anda akan menulis sebuah program yang menampilkan tanda penghitungan hingga nilai yang diberikan. Tapi, menghitung hanya di base 5 itu membosankan! Karena itu, program Anda juga harus dapat menampilkan penghitungan di pangkalan yang berbeda.

Memasukkan

Input akan berupa satu atau dua nilai integer non-negatif yang dipisahkan oleh koma (misalnya 9atau 8,4). Angka pertama adalah nilai yang harus ditampilkan oleh penghitungan. Nilai kedua adalah basis penghitungan. Jika nilai kedua tidak diberikan, gunakan basis 5 .

Keluaran

Keluarannya adalah nilai yang dimasukkan sebagai tanda penghitungan ASCII. Berikut adalah beberapa contoh yang dapat Anda uji terhadap program Anda - output Anda harus sama persis!

Masukan: 12atau12,5

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

Memasukkan: 7,3

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

Memasukkan: 4,2

 |   |
-+- -+-
 |   |

Input: 6,1atau 6,10(perhatikan spasi utama)

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

Perhatikan juga bahwa basis 1 dimaksudkan tidak konsisten - hanya garis vertikal yang harus digunakan.

Jika salah satu dari nilai yang dimasukkan adalah 0, seharusnya tidak ada output apa pun (dan program Anda harus berakhir dengan anggun).

Aturan

  • Ini adalah , sehingga implementasi terpendek yang benar (dalam byte) menang.
  • Input / output dapat dalam media yang sesuai (mis. Stdin / stdout, file ...).
  • Input dapat berupa beberapa argumen baris perintah atau dipisahkan dengan spasi, dll. Jika lebih cocok untuk bahasa target Anda.
  • Trailing newlines diizinkan dalam output. Ruang tambahan tidak. Aturan ini hanya berlaku ketika ada output (yaitu tidak ketika nilai yang dimasukkan adalah 0).
  • Kode Anda harus default ke basis 5 ketika tidak ada basis dimasukkan.
Sean Latham
sumber
3
Bukankah seharusnya output dari 6,1lebih mirip -+- -+- -+- -+- -+- -+-?
Peter Taylor
3
Jika Anda menyatakan "Input akan berupa satu atau dua nilai integer positif yang dipisahkan oleh koma (mis. 9 atau 8,4)." maka kita harus bisa menganggapnya sebagai pemberian, dan tidak perlu khawatir tentang "Program Anda harus kuat - Anda harus memvalidasi input ..." di luar menangani satu atau dua angka.
AndoDaan
1
@PeterTaylor -+-akan mewakili dua, karena ada garis vertikal dan skor horizontal melaluinya. Basis 1 hanya akan memiliki garis vertikal. @AndoDaan diamandemen.
Sean Latham
Baiklah kalau --- --- --- --- --- ---begitu. Untuk konsistensi dengan pangkalan lain, Anda harus melakukan pukulan horizontal melalui b-1garis vertikal. Jika dimaksudkan tidak konsisten, Anda harus menyatakannya secara eksplisit.
Peter Taylor
Saya sudah melakukan itu. Maaf, saya pikir itu tersirat.
Sean Latham

Jawaban:

4

CJam 103 85 72 karakter

Cobalah di http://cjam.aditsu.net/ .

asli

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

Bekerja dengan mendefinisikan satu set penghitungan dengan spasi, garis dan l untuk spasi yang harus tetap spasi. Kemudian manfaatkan fungsi er (tranliteration) untuk membuat baris kedua. Bagian yang paling tidak efisien adalah berurusan dengan kasus khusus 1 dan 0. Akan mengedit saat saya memperbaikinya. Kiat saya terlalu lama untuk disadari: karena input kedua adalah 1 sama dengan tak terbatas atau input pertama +1, mendefinisikannya kembali sama dengan 1 menghemat banyak pekerjaan.

paling baik sejauh ini dengan dibatasi koma

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

paling ditingkatkan sejauh ini dengan input terbatas ruang

Tentu saja CJam benar-benar dirancang untuk input terbatas ruang. Menempatkan input pada 20 3 bukannya 20,3 adalah manfaat besar.

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

Python 2 - 111 108 119 144 140 136 135 134 - Cobalah

Ok, mari kita coba:

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)

Sunting: Saya telah mengabaikan bahwa seharusnya tidak ada output jika n==0atau b==0. Harganya 11 karakter. :(

Sunting: Ok, setelah memperbaiki masalah kedua yang disebutkan dalam komentar solusi saya pada dasarnya konvergen dengan yang ada di BeetDemGuise.

Falko
sumber
Ini mencetak baris baru ketika salah satu input (atau keduanya) nol yang menurut tantangan tidak diinginkan. Juga, bagaimana jika hanya satu nomor yang dimasukkan ke dalam program?
BeetDemGuise
1
Ini gagal ketika nilai kedua dihilangkan ( bharus 5 dalam kasus ini). Saya akan membuatnya lebih jelas dalam pertanyaan. Sunting: oh, sudahlah, Anda memperbaikinya sama seperti saya membuat komentar ini!
Sean Latham
Python manakah ini?
Beta Decay
Ini Python 2.7.8. - Oh, ada kesalahan kecil di akhir ...
Falko
1
Jika itu Python 2.x tidak bisakah Anda menyimpan satu karakter lagi dengan menggunakan n/bbukan n//b?
Emil
5

Pesta, 239 228 199 189 188

Ini usaha saya, bisa banyak bermain golf.

Catatan: baris kedua tidak mengurangi 5 dari 2, ini menetapkan nilai default jika $2kosong!

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"

sumber
Apakah itu {1..$n}berfungsi `seq $n`?
FUZxxl
@FUZxxl sayangnya tidak, h=8;echo {1..$h}output{1..8}
Itu tidak baik.
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

Program ini sangat mudah:

  • Dapatkan input dan coba bongkar t,b. Jika gagal, cukup berikan nilai yang benar.
  • Jika dasarnya 1, ubah nilainya menjadi sesuatu yang dapat menangani semua garis vertikal dengan mudah ( t+1).
  • Atur beberapa variabel dan buat bagian bawah dan atas dari penghitungan.
  • Cetak penghitungan jika keduanya tdan bbukan nol.

EDIT 1: Gunakan inputfungsi alih-alih raw_inputsetelah beberapa bermain-main.

EDIT 2: Terima kasih kepada Falko untuk menunjukkan bug kecil dengan pengecekan tidak nol saya. Sekarang kode kita pada dasarnya identik, kurang beberapa nama variabel dan beberapa logika kecil.

EDIT 3: Berkat cara Python membandingkan sekuens dan tipe yang berbeda , kita dapat membandingkannya idengan listuntuk mendapatkan versi yang lebih pendek dari try...exceptblok kita .

Ini adalah versi yang tidak dikoleksi:

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
BeetDemGuise
sumber
Saya pikir t&badalah Falseuntuk 10,5. Kalau tidak, solusi kami sedang berkumpul! ;)
Falko
@Falko Anda benar dalam kedua hal ini! Anda tahu apa yang mereka katakan tentang pikiran hebat.
BeetDemGuise
Akan sangat bagus jika kita dapat menemukan cara singkat untuk menguji apakah iitu skalar atau daftar. Lalu kita bisa menjatuhkan try ... exceptmonster itu.
Falko
@ Talko Saya pikir saya menemukan cek 1byte lebih baik. A listselalu lebih besar dari int. Juga, lists dibandingkan dalam urutan leksikografis. Jadi jika kita membandingkan [0]<iini akan selalu kembali Falsejika iadalah angka dan Truejika iadalah daftar (dengan elemen pertama yang tidak nol).
BeetDemGuise
1
Bagus! Saya selanjutnya memperpendek pendekatan Anda. Kerja tim yang bagus! :)
Falko
3

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

Kurang bermain golf:

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);
  }
}
Ypnypn
sumber
Anda dapat menyimpan beberapa dengan membuat isebuah longsehingga Anda tidak harus menyatakan secara terpisah. Beberapa lagi dengan melakukan i++%b>0di loop Anda alih-alih menambahkannya secara terpisah (dan i++<n%bdi loop ketiga). Satu lagi dengan menggunakan 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

ungolfed

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
Fozi
sumber
menampilkan garis horizontal alih-alih yang vertikal untuk basis 1 :(
chinese perl goth
@ chineseperlgoth ya, itu salah satu persyaratan. Silakan baca komentar di Q.
Fozi
3

C - 193

Saya minta maaf. Berurusan dengan kasus khusus untuk 1 adalah sedikit hack yang buruk jadi saya kira ini bisa bermain golf lebih dengan pendekatan yang lebih baik. Juga, kode ini termasuk baris baru di awal output, jadi jika ini tidak diizinkan, beri tahu saya.

Tentu saja, definisi yang sangat jelek selalu membantu :)

Hitungan karakter hanya mencakup spasi yang diperlukan dan baris baru.

#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;}
}
Allbeert
sumber
Kode Anda tampaknya mencetak baris baru ketika salah satu nilainya nol. Ini jelas-jelas dilarang. Solusi Anda tidak sesuai.
FUZxxl
@ FuZxxl Anda benar, saya melewatkan itu! Perbaikan cepat yang buruk ini harus dilakukan untuk saat ini. Saya harap saya punya waktu segera untuk menemukan cara yang lebih baik.
Allbeert
Saya cukup yakin Anda dapat menyimpan beberapa karakter dengan mengganti printfdengan puts, dan mengganti returndengan operator ternary.
milinon
@ Millinon Masalahnya putsadalah ia menambahkan baris baru setiap kali :(. Dan untuk operator ternary, tidak mungkin untuk menambahkan returns atau fors di dalamnya !. Komentar Anda memang memberi saya ide untuk menyimpan beberapa karakter lebih banyak lagi. mudah dengan menghapus return
though.Terima
2

C # 271bytes

Bukan yang terpendek, saya tidak bisa memasukkan input bacaan karena perlu menerima 0 sebagai input.

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

Kode yang diformat:

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;
    }
}
VisualMelon
sumber
1

Lua - 219 203 byte

Saya mencari salinan d dari b salinan "|", lalu menambahkan r salinan "|" pada akhirnya. Saya merasa mungkin saya harus pergi dengan 'tally' the | | s ke string satu per satu.

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)

ungolfed:

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!

Sampel:

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


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


c:\Programming\AnarchyGolfMine>lua test.lua
18,1
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |
AndoDaan
sumber
1
Bisakah Anda memposting versi sligthly lebih mudah dibaca dan ungolfed? Golf di Lua terlihat menarik!
@Alessandro selesai. Dan terima kasih, itu membuat saya menemukan beberapa hal yang saya lewatkan.
AndoDaan
1

JavaScript (193)

Ini mungkin terlalu rumit.

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)

Versi yang dikomentari

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)
Mika Lammi
sumber
1

Python - 127 123 122

Hanya menyelinap masuk dengan versi python yang sedikit lebih pendek.

sunting: Memperbaiki 0 tidak mencetak apa-apa dan bergabung kembali, berakhir dengan panjang yang sama

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))
Aneh
sumber
0

C (207 karakter)

Baris baru sebelum exitini hanya untuk keterbacaan.

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

scanfpenggunaan tanpa malu-malu dicuri dari Allbeert. Perhatikan bahwa solusi ini tidak dapat dikompilasi dengan gcc karena mencoba untuk menegakkan prototipe yang tidak ada exit. Kompilasi dengan kompiler C yang berfungsi sepertitcc . Selain itu, fungsi ini mungkin atau mungkin tidak berfungsi pada platform 64 bit. Gunakan dengan hati-hati.

Berikut ini adalah implementasi ungolfed asli berdasarkan ini:

#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);
}
FUZxxl
sumber
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)

Cobalah online!

Pertanyaan lama yang saya tahu tetapi tetap menyenangkan untuk dicoba. Peluang untuk mencoba beberapa trik yang saya pelajari sejak bergabung.

ElPedro
sumber