Wyświetl podsumowanie (w różnych bazach)

16

Tallying to prosty system liczenia, który działa w bazie 5. Na całym świecie stosuje się różne różne systemy liczenia, ale ten, który jest używany w większości krajów anglojęzycznych, jest być może najprostszy - zliczanie jednostek poprzez oznaczenie linii pionowych, a następnie każdy piąty znak przekreśla poziomą linię przez poprzedni zbiór czterech. To grupuje znaczniki w grupach po 5 (i ułatwia ich szybkie liczenie).

Zamierzasz napisać program, który wyświetla znaczniki do określonej wartości. Ale liczenie tylko w bazie 5 jest nudne! Dlatego twój program powinien także być w stanie wyświetlać dane statystyczne w różnych bazach.

Wejście

Dane wejściowe będą jedną lub dwie nieujemne wartości całkowite oddzielone przecinkiem (np. 9Lub 8,4). Pierwsza liczba to wartość, która powinna być wyświetlana przez licznik. Druga wartość jest podstawą sumy. Jeśli nie podano drugiej wartości, użyj podstawy 5 .

Wynik

Wyjściową wartością będzie wprowadzona wartość reprezentowana jako znaczniki artystyczne ASCII. Oto kilka przykładów, z którymi możesz przetestować swój program - wyniki powinny dokładnie do nich pasować!

Dane wejściowe: 12lub12,5

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

Wejście: 7,3

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

Wejście: 4,2

 |   |
-+- -+-
 |   |

Wejście: 6,1lub 6,10(zauważ spacje wiodące)

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

Należy również zauważyć, że podstawa 1 ma być niespójna - należy stosować tylko pionowe linie.

Jeśli jedna z wprowadzonych wartości wynosi 0, nie powinno być żadnych wyników (a twój program powinien zakończyć się z wdziękiem).

Zasady

  • To jest , więc wygrywa najkrótsza poprawna implementacja (w bajtach).
  • Wejście / wyjście może być na dowolnym odpowiednim nośniku (np. Stdin / stdout, plik ...).
  • Dane wejściowe mogą mieć postać wielu argumentów wiersza polecenia lub być oddzielone spacjami itp., Jeśli są bardziej odpowiednie dla języka docelowego.
  • Końcowe znaki nowej linii są dozwolone w danych wyjściowych. Końcowe spacje nie są. Ta reguła ma zastosowanie tylko wtedy, gdy istnieje wyjście (tj. Nie wtedy, gdy wprowadzona wartość wynosi 0).
  • Twój kod musi być ustawiony domyślnie na base 5, gdy nie wprowadzono żadnej bazy.
Sean Latham
źródło
3
Czy wyjście nie powinno 6,1wyglądać bardziej -+- -+- -+- -+- -+- -+-?
Peter Taylor,
3
Jeśli powiesz „Dane wejściowe będą jedną lub dwiema dodatnimi liczbami całkowitymi oddzielonymi przecinkiem (np. 9 lub 8,4)”. wtedy powinniśmy być w stanie przyjąć to jako dane i nie martwić się o „Twój program powinien być solidny - powinieneś zweryfikować dane wejściowe ...” poza obsługą jednej lub dwóch liczb.
AndoDaan,
1
@PeterTaylor -+-reprezentowałby dwa, ponieważ istnieje linia pionowa i pozioma ocena przez nią. Baza 1 miałaby tylko pionowe linie. @AndoDaan poprawione.
Sean Latham,
Okej --- --- --- --- --- ---więc. Aby zachować spójność z innymi bazami, powinieneś uderzać b-1poziomo w linie pionowe. Jeśli ma to być niespójne, należy to wyraźnie zaznaczyć.
Peter Taylor,
To zrobiłem. Przepraszam, myślałem, że to sugerowane.
Sean Latham,

Odpowiedzi:

4

CJam 103 85 72 znaki

Wypróbuj na http://cjam.aditsu.net/ .

oryginalny

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

Działa poprzez zdefiniowanie jednego zestawu wysokości ze spacjami, liniami i l dla spacji, które powinny pozostać spacjami. Następnie korzysta z funkcji er (tranliteracji), aby utworzyć drugą linię. Najbardziej nieefektywna część dotyczy przypadków specjalnych 1 i 0. Będę edytować, gdy go poprawię. Wskazówka Za długo zajęłam sobie sprawę: ponieważ drugie wejście to 1 jest takie samo jak nieskończoność lub pierwsze wejście +1, ponowne zdefiniowanie go, gdy jest równe 1, oszczędza dużo pracy.

najbardziej ulepszony jak dotąd z przecinkiem

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

jak dotąd ulepszony z wprowadzaniem rozdzielanym spacjami

Oczywiście, ponieważ CJam jest naprawdę zaprojektowany do wprowadzania danych rozdzielanych spacjami. Umieszczenie wkładu na 20 3 zamiast 20,3 to ogromna korzyść.

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

Python 2 - 111 108 119 144 140 136 135 134 134 - Spróbuj

Ok, spróbujmy:

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)

Edycja: Przeoczyłem, że nie powinno być żadnych wyników, jeśli n==0lub b==0. To kosztuje mnie 11 znaków. :(

Edycja: Ok, po naprawieniu drugiego problemu wymienionego w komentarzach moje rozwiązanie zasadniczo zbiegło się z rozwiązaniem BeetDemGuise.

Falko
źródło
Drukuje znaki nowej linii, gdy jedno z wejść (lub oba) jest równe zero, co zgodnie z wyzwaniem jest niepożądane. A co, jeśli tylko jeden numer zostanie wprowadzony do programu?
BeetDemGuise,
1
Nie powiedzie się to, gdy druga wartość zostanie pominięta ( bw tym przypadku powinna wynosić 5). Wyjaśnię to bardziej w pytaniu. Edycja: och, nieważne, naprawiłeś to tak, jak zrobiłem ten komentarz!
Sean Latham,
Który to Python?
Beta Decay
To jest Python 2.7.8. - Och, na samym końcu był mały błąd ...
Falko,
1
Jeśli to jest Python 2.x, czy nie możesz zapisać jeszcze jednej postaci, używając n/bzamiast niej n//b?
Emil,
5

Grzmotnąć, 239 228 199 189 188

Oto moja próba, może być dużo golfa.

Uwaga: drugi wiersz nie odejmuje 5 od 2, ustawia wartość domyślną, jeśli $2jest pusty!

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"

źródło
Czy {1..$n}działa zamiast `seq $n`?
FUZxxl,
@FUZxxl niestety nie, dane h=8;echo {1..$h}wyjściowe{1..8}
To nie jest dobrze.
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 jest bardzo prosty:

  • Uzyskaj dane wejściowe i spróbuj rozpakować t,b. Jeśli to się nie powiedzie, po prostu przypisz prawidłowe wartości.
  • Jeśli podstawą była 1, zmień jej wartość na coś, co z łatwością poradzi sobie ze wszystkimi liniami pionowymi ( t+1).
  • Ustaw niektóre zmienne i utwórz dolną i górną sekcję podsumowań.
  • Wydrukować identyfikacyjne, gdy oba ti bsą niezerowe.

EDYCJA 1: Użyj inputfunkcji zamiast raw_inputpo zabawie.

EDYCJA 2: Dziękuję Falko za wskazanie małego błędu za pomocą mojej kontroli niezerowej. Teraz nasz kod jest w zasadzie identyczny, bez niektórych nazw zmiennych i pewnej małej logiki.

EDYCJA 3: Dzięki temu, jak Python porównuje sekwencje i różne typy , możemy porównać ido a, listaby uzyskać krótszą wersję naszego try...exceptbloku.

Oto wersja bez golfa:

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
źródło
Myślę, że t&bjest Falseza 10,5. W przeciwnym razie nasze rozwiązania będą zbieżne! ;)
Falko,
@Falko Masz rację w obu sprawach! Wiesz, co mówią o wielkich umysłach.
BeetDemGuise,
Byłoby naprawdę świetnie, gdybyśmy mogli znaleźć krótki sposób na sprawdzenie, czy ijest to skalar, czy lista. Wtedy moglibyśmy upuścić try ... exceptpotwora.
Falko,
@ Falko Myślę, że znalazłem 1-bajtowy czek lepszy. A listjest zawsze większe niż int. Również listsą porównywane w porządku leksykograficznym. Więc jeśli porównamy, [0]<ito zawsze zwróci, Falsejeśli ijest liczbą, a Truejeśli ijest listą (z niezerowym pierwszym elementem).
BeetDemGuise
1
Świetny! Skróciłem twoje podejście. Niezła praca zespołowa! :)
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);}}

Mniej golfa:

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
źródło
Można zapisać kilka dokonując więc nie trzeba go zadeklarować osobno. Kilka więcej, wykonując pętle zamiast zwiększać je osobno (i w trzeciej pętli). Kolejny za pomocą . ilongi++%b>0i++<n%bb=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

bez golfa

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
źródło
wyświetla linie poziome zamiast pionowych dla podstawy 1 :(
chiński perl goth
@chineseperlgoth tak, to jeden z wymagań. Przeczytaj komentarze na temat Q.
Fozi
3

C - 193

Tak mi przykro. Radzenie sobie ze specjalnym przypadkiem dla 1 było trochę kiepskim hackem, więc myślę, że można by to pograć w golfa przy lepszym podejściu. Ponadto ten kod zawiera nowy wiersz na początku danych wyjściowych, więc jeśli nie jest to dozwolone, daj mi znać.

Oczywiście bardzo brzydkie definicje zawsze pomagają :)

Liczba znaków obejmuje tylko niezbędne spacje i nowe linie.

#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
źródło
Twój kod wydaje się drukować znaki nowej linii, gdy jedna z wartości wynosi zero. Jest to wyraźnie zabronione. Twoje rozwiązanie jest niezgodne.
FUZxxl,
@FUZxxl Masz rację, tęskniłem! Ta zła szybka poprawka będzie musiała na razie wystarczyć. Mam nadzieję, że wkrótce będę mógł znaleźć lepszy sposób.
Allbeert,
Jestem całkiem pewien, można zaoszczędzić kilka znaków zastępując printfz puts, i zastępowanie returnz operatora potrójnego.
millinon
@millinon Problem putspolega na tym, że dodaje za każdym razem nową linię :(. A dla operatora trójskładnikowego nie jest możliwe dodanie w nich returns lub fors !. Twój komentarz dał mi pomysł, aby zapisać kilka dodatkowych znaków bardzo łatwo usuwając returnchociaż. Dzięki!
Allbeert
2

C # 271 bajtów

Nie najkrócej, nie mogłem odczytywać odczytu wejściowego, ponieważ musiał zaakceptować 0 jako wejście.

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

Sformatowany kod:

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
źródło
1

Lua - 219 203 bajtów

Poszedłem zrobić make d kopii b kopii „|”, a następnie dodać r kopii „|” na końcu. Czuję, że może powinienem był pójść z „podsumowaniem” „|” po strunie pojedynczo.

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)

bez golfa:

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!

Próba:

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
źródło
1
Czy możesz napisać nieco bardziej czytelną i nie golfową wersję? Gra w golfa w Lua wygląda interesująco!
@Alessandro gotowe. I dzięki, znalazłem kilka rzeczy, za którymi tęskniłem.
AndoDaan,
1

JavaScript (193)

To może być zbyt skomplikowane.

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)

Skomentowana wersja

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
źródło
1

Python - 127 123 122

Po prostu wkradam się z nieco krótszą wersją Pythona.

edycja: Naprawiono 0, że nic się nie drukowało i rejestrator, skończyło się na tej samej długości

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))
Biżuteria
źródło
0

C (207 znaków)

Nowa linia tuż przed nią exitsłuży wyłącznie czytelności.

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

scanfbezwstydne użycie skradzione Allbeertowi. Zauważ, że to rozwiązanie nie kompiluje się z gcc, ponieważ próbuje wymusić nieistniejący prototyp exit. Skompiluj za pomocą działającego kompilatora C.tcc . Ponadto ta funkcja może, ale nie musi działać na platformach 64-bitowych. Używaj ostrożnie.

Oto oryginalna nie golfowa implementacja oparta na:

#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
źródło
0

Python 2 , 134 126 123 114 bajtów

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)

Wypróbuj online!

Stare pytanie, które znam, ale i tak fajnie jest spróbować. Szansa na wypróbowanie kilku sztuczek, których nauczyłem się od czasu dołączenia.

ElPedro
źródło