Anzeige einer Abrechnung (in unterschiedlichen Basen)


16

Tallying ist ein einfaches Zählsystem, das in Basis 5 funktioniert. Es gibt verschiedene Zählsysteme auf der ganzen Welt, aber dasjenige, das in den meisten englischsprachigen Ländern verwendet wird, ist vielleicht das einfachste - Zählen von Einheiten durch Markieren vertikaler Linien, z Mit jeder fünften Markierung wird eine horizontale Linie durch die vorherige Vierergruppe gezogen. Dies gruppiert die Zählmarken in Gruppen von 5 (und erleichtert das schnelle Zählen).

Sie werden ein Programm schreiben, das Strichzahlen bis zu einem bestimmten Wert anzeigt. Aber es ist langweilig, nur in Basis 5 zu zählen! Daher sollte Ihr Programm auch in der Lage sein, Zahlen in verschiedenen Basen anzuzeigen.

Eingang

Die Eingabe besteht entweder aus einem oder zwei nicht negativen Ganzzahlwerten, die durch ein Komma (z . B. 9oder 8,4) getrennt sind. Die erste Zahl ist der Wert, der von der Zählung angezeigt werden soll. Der zweite Wert ist die Basis der Abrechnung. Wenn der zweite Wert nicht angegeben wird, verwenden Sie Basis 5 .

Ausgabe

Die Ausgabe ist der eingegebene Wert, der als ASCII-Art-Tally-Markierungen dargestellt wird. Hier sind einige Beispiele, mit denen Sie Ihr Programm testen können - Ihre Ausgabe sollte genau mit ihnen übereinstimmen!

Eingabe: 12oder12,5

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

Eingang: 7,3

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

Eingang: 4,2

 |   |
-+- -+-
 |   |

Eingabe: 6,1oder 6,10(beachten Sie die führenden Leerzeichen)

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

Beachten Sie auch, dass Basis 1 inkonsistent sein soll - nur vertikale Linien sollten verwendet werden.

Wenn einer der eingegebenen Werte 0 ist, sollte überhaupt keine Ausgabe erfolgen (und Ihr Programm sollte ordnungsgemäß beendet werden).

Regeln

  • Das ist , also gewinnt die kürzeste korrekte Implementierung (in Bytes).
  • Die Ein- / Ausgabe kann auf jedem geeigneten Medium erfolgen (z. B. stdin / stdout, file ...).
  • Die Eingabe kann in Form mehrerer Befehlszeilenargumente oder durch Leerzeichen usw. getrennt erfolgen, wenn dies für Ihre Zielsprache besser geeignet ist.
  • Nachgestellte Zeilenumbrüche sind in der Ausgabe zulässig. Nachgestellte Leerzeichen gibt es nicht. Diese Regel gilt nur, wenn eine Ausgabe vorliegt (dh nicht, wenn der eingegebene Wert 0 ist).
  • Ihr Code muss standardmäßig auf Basis 5 eingestellt sein, wenn keine Basis eingegeben wird.

3
Sollte die Ausgabe von nicht 6,1eher so aussehen -+- -+- -+- -+- -+- -+-?
Peter Taylor

3
Wenn Sie angeben "Die Eingabe besteht entweder aus einem oder zwei positiven Ganzzahlwerten, die durch ein Komma getrennt sind (z. B. 9 oder 8,4)." dann sollten wir das als gegeben ansehen können und uns keine Gedanken darüber machen müssen, dass "Ihr Programm robust sein sollte - Sie sollten die Eingabe validieren ..." und nicht nur eine oder zwei Zahlen verarbeiten müssen.
AndoDaan

1
@PeterTaylor -+-würde zwei darstellen, weil es eine vertikale Linie und eine horizontale Kerbe durch sie gibt. Basis 1 würde nur vertikale Linien haben. @AndoDaan gebessert.
Sean Latham

Ok --- --- --- --- --- ---dann. Um die Übereinstimmung mit den anderen Basen zu b-1gewährleisten, sollten Sie einen horizontalen Strich durch die vertikalen Linien machen. Wenn es inkonsistent sein soll, sollten Sie dies explizit angeben.
Peter Taylor

Ich habe das getan. Entschuldigung, ich dachte es wäre impliziert.
Sean Latham

Antworten:


4

CJam 103 85 72 Zeichen

Versuchen Sie es unter http://cjam.aditsu.net/ .

Original

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

Definiert eine Reihe von Reihen mit Leerzeichen, Linien und einem l für Leerzeichen, die Leerzeichen bleiben sollen. Nutzt dann die Funktion er (Transliteration), um die zweite Zeile zu erstellen. Der ineffizienteste Teil befasst sich mit den Sonderfällen 1 und 0. Wird bearbeitet, wenn ich es verbessere. Tipp Ich habe zu lange gebraucht, um zu realisieren: Da die zweite Eingabe 1 der Unendlichkeit oder die erste Eingabe +1 entspricht, spart die Neudefinition, wenn sie 1 entspricht, eine Menge Arbeit.

Die meisten wurden bisher durch Kommas getrennt verbessert

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

Die meisten wurden bisher durch durch Leerzeichen begrenzte Eingaben verbessert

Da ist CJam natürlich wirklich für raumbegrenzte Eingaben ausgelegt. Es ist ein großer Vorteil, den Eingang auf 20 3 anstatt auf 20,3 zu setzen.

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 - Probieren Sie es aus

Ok, lass es uns versuchen:

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)

Edit: Ich habe übersehen, dass es keine Ausgabe geben soll, wenn n==0oder b==0. Das kostet mich 11 Zeichen. :(

Edit: Ok, nachdem ich das zweite in den Kommentaren erwähnte Problem behoben habe, ist meine Lösung im Grunde der von BeetDemGuise angenähert.


Dies gibt Zeilenumbrüche aus, wenn eine der Eingaben (oder beide) Null sind, was entsprechend der Herausforderung unerwünscht ist. Was ist auch, wenn nur eine Nummer in das Programm eingegeben wird?
BeetDemGuise

1
Dies schlägt fehl, wenn der zweite Wert weggelassen wird ( bsollte in diesem Fall 5 sein). Ich werde es in der Frage klarer machen. Edit: oh, egal, du hast es gerade behoben, als ich diesen Kommentar abgegeben habe!
Sean Latham

Welches Python ist das?
Beta-Zerfall

Es ist Python 2.7.8. - Oh, ganz am Ende gab es einen winzigen Fehler ...
Falko

1
Wenn es sich um Python 2.x handelt, können Sie n/bstattdessen nicht noch ein Zeichen speichern, indem Sie verwenden n//b?
Emil

5

Bash, 239 228 199 189 188

Hier ist mein Versuch, es könnte viel Golf gespielt werden.

Hinweis: Die zweite Zeile subtrahiert nicht 5 von 2, sondern setzt einen Standardwert, wenn $2leer!

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"

Arbeitet {1..$n}statt `seq $n`?
FUZxxl

@ FuZxxl leider nicht, h=8;echo {1..$h}Ausgänge{1..8}

Das ist nicht gut.
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

Das Programm ist ziemlich einfach:

  • Holen Sie sich die Eingabe und versuchen Sie, in zu entpacken t,b. Wenn dies fehlschlägt, weisen Sie einfach die richtigen Werte zu.
  • Wenn dies der Fall war 1, ändern Sie den Wert in einen Wert, der alle vertikalen Linien problemlos verarbeiten kann ( t+1).
  • Legen Sie einige Variablen fest und erstellen Sie den unteren und oberen Bereich der Tallies.
  • Drucken Sie die Zahlen aus, wenn beide tund bnicht Null sind.

EDIT 1: Verwenden Sie die inputFunktion anstatt raw_inputnach einigem Herumspielen.

EDIT 2: Danke an Falko für den Hinweis auf einen kleinen Fehler bei meiner Nicht-Null-Prüfung. Jetzt ist unser Code im Grunde genommen identisch, abzüglich einiger Variablennamen und einer kleinen Logik.

EDIT 3: Dank dem Vergleich von Sequenzen und verschiedenen Typen in Python können wir einen Vergleich imit a anstellen list, um eine kürzere Version unseres try...exceptBlocks zu erhalten.

Hier ist die ungolfed Version:

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

Ich denke t&bist Falsefür 10,5. Ansonsten laufen unsere Lösungen zusammen! ;)
Falko

@Falko In beiden Punkten hast du Recht! Sie wissen, was sie über großartige Köpfe sagen.
BeetDemGuise

Es wäre großartig, wenn wir einen kurzen Weg finden könnten, um zu testen, ob ies sich um Skalar oder eine Liste handelt. Dann könnten wir das try ... exceptMonster fallen lassen.
Falko

@Falko Ich glaube, ich habe einen 1-Byte-besseren Check gefunden. A listist immer größer als ein int. Außerdem werden lists in lexikographischer Reihenfolge verglichen. Wenn wir also vergleichen, [0]<iwird immer zurückgegeben, Falseob ieine Zahl und Trueob ieine Liste ist (mit einem ersten Element ungleich Null).
BeetDemGuise

1
Groß! Ich habe Ihren Ansatz weiter verkürzt. Gute Teamarbeit! :)
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);}}

Weniger golfen:

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

Sie können , indem sie ein paar sparen iein , longso dass Sie es nicht separat deklarieren müssen. Ein paar mehr, indem Sie i++%b>0in Ihren Schleifen arbeiten, anstatt sie separat zu erhöhen (und i++<n%bin der dritten Schleife). Ein anderer mit 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

zeigt horizontale statt vertikaler Linien für Basis 1 an :(
chinese perl goth

@chineseperlgoth ja, das ist eine der anforderungen. Bitte lesen Sie die Kommentare zu Q.
Fozi

3

C - 193

Es tut mir Leid. Sich mit dem Spezialfall für 1 zu befassen, war ein schlechter Hack, also könnte man mit einer besseren Herangehensweise mehr Golf spielen. Außerdem enthält dieser Code eine neue Zeile am Anfang der Ausgabe. Wenn dies nicht zulässig ist, lassen Sie es mich bitte wissen.

Natürlich hilft das sehr hässlich aussehende definiert immer :)

Die Zeichenanzahl umfasst nur die erforderlichen Leerzeichen und neuen Zeilen.

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

Ihr Code scheint Zeilenumbrüche zu drucken, wenn einer der Werte Null ist. Dies ist ausdrücklich untersagt. Ihre Lösung stimmt nicht überein.
FUZxxl

@FUZxxl Du hast recht, das habe ich verpasst! Diese schlechte Schnellreparatur muss vorerst genügen. Ich hoffe, ich habe bald Zeit, einen besseren Weg zu finden.
Allbeert

Ich bin ziemlich sicher , dass Sie ein paar Zeichen durch Ersetzen sparen können printfmit putsund Ersetzen returnmit einem ternären Operator.
Millinon

@millinon Das Problem dabei putsist, dass jedes Mal eine neue Zeile hinzugefügt wird :(. Und für den ternären Operator ist es nicht möglich, returns oder fors in diese einzufügen !. Ihr Kommentar hat mich auf die Idee gebracht, sehr viele weitere Zeichen zu speichern leicht durch Entfernen der returnobwohl. Danke!
Allbeert

2

C # 271bytes

Nicht die kürzeste, ich konnte den Eingabewert nicht messen, da 0 als Eingabe akzeptiert werden musste.

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

Formatierter Code:

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 Bytes

Ich habe mich für die Erstellung von Kopien von Kopien von "|" entschieden und dann r Kopien von "|" hinzugefügt. Am Ende. Ich habe das Gefühl, ich hätte die "|" - Zahlen nacheinander auf die Saite bringen sollen.

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!

Stichprobe:

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
Könnten Sie eine etwas lesbarere und ungolfedere Version posten? Golfen in Lua sieht interessant aus!

@Alessandro fertig. Und danke, es hat ein paar Dinge ergeben, die ich verpasst habe.
AndoDaan

1

JavaScript (193)

Dies kann zu komplex sein.

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)

Kommentierte Version

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

Einfach mit einer etwas kürzeren Python-Version reinschleichen.

edit: Behoben: 0 druckt nichts und rejigger, endete gleich lang

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 Zeichen)

Die Newline direkt davor exitdient nur der Lesbarkeit.

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

scanfVerwendung schamlos von Allbeert gestohlen. Beachten Sie, dass diese Lösung nicht mit gcc kompiliert werden kann, da versucht wird, einen nicht vorhandenen Prototyp für zu erzwingen exit. Kompilieren Sie mit einem funktionierenden C-Compiler wietcc . Diese Funktion funktioniert möglicherweise auch auf 64-Bit-Plattformen. Mit Vorsicht anwenden.

Hier ist die ursprüngliche Implementierung ohne Golf, auf der dies basiert:

#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 Bytes

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)

Probieren Sie es online!

Alte Frage, die ich kenne, aber die Spaß macht, es trotzdem zu versuchen. Chance, ein paar Tricks auszuprobieren, die ich seit meinem Beitritt gelernt habe.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.