Quipu zählen: Basis 10 in der neuen Welt

41

Quipus ist ein altes Gerät, mit dem die Inka im präkolumbischen Zeitalter Zahlen in einem Zehn-Knoten-System an einer Schnur aufzeichnen. Es funktioniert wie folgt:

Jeder Knotenblock ist eine Ziffer, und es gibt drei Hauptknotentypen: einfache Überhandknoten; "lange Knoten", bestehend aus einem Überhandknoten mit einer oder mehreren zusätzlichen Windungen; und acht Knoten.

  • Zehnerpotenzen werden durch die Position entlang der Schnur angezeigt, und diese Position wird zwischen aufeinanderfolgenden Strängen ausgerichtet.
  • Stellen in Positionen für 10 und höhere Potenzen werden durch Cluster von einfachen Knoten dargestellt (z. B. 40 sind vier einfache Knoten in einer Reihe in der "Zehner" -Position).
  • Ziffern in der Position "Einsen" werden durch lange Knoten dargestellt (z. B. 4 ist ein Knoten mit vier Umdrehungen). Aufgrund der Art und Weise, wie die Knoten gebunden sind, kann die Ziffer 1 nicht auf diese Weise angezeigt werden und wird in dieser Position durch einen Achterknoten dargestellt.
  • Null wird durch das Fehlen eines Knotens in der entsprechenden Position dargestellt.

Einzelheiten

Für diese Herausforderung stellt jeder Strang eines quipu eine einzelne Zahl (obwohl, wie die Wikipedia Artikel besagt, Sie können viele Zahlen auf einem Strang, in dieser Herausforderung darstellen, so werden wir nicht).

Knoten

Jeder Knoten wird durch ein einzelnes ASCII-Zeichen dargestellt.

  • . repräsentiert einen einfachen Knoten
  • : stellt eine Umdrehung eines langen Knotens dar
  • 8 repräsentiert einen Achterknoten
  • | Stellt das Fehlen eines Knotens sowie eines Trennzeichens zwischen den Ziffern dar.

Quipus bauen

Quipu werden nach diesen Regeln konstruiert.

  1. Die Stränge verlaufen von oben nach unten in absteigender Reihenfolge (wie in dargestellt, befindet sich die Einheitenziffer am unteren Ende eines Strangs). Ziffern entlang eines Strangs werden durch das Zeichen ( |) getrennt.
  2. Die Potenz von 10, die eine Ziffer darstellt, wird durch ihre Position entlang des Strangs auf dieselbe Weise bestimmt, wie die Potenz einer Ziffer von 10 unter Verwendung ihres Index in einer Zahl mit unserem Zahlensystem berechnet würde. Das heißt, 24mit a 2in der Zehnerstelle und a 4in der Einheitsstelle werden zwei Knoten dargestellt, ein Begrenzer ( |) und dann vier Knoten.
  3. Ziffern in der gleichen Position sind am unteren Ende des Strangs ausgerichtet. Wenn eine Ziffer an einer Position weniger Knoten hat als andere Ziffern anderer Zahlen an derselben Position, wird das Fehlen dieser Knoten durch ( |) dargestellt.
  4. Aufeinanderfolgende einfache Knoten ( .) repräsentieren einen Wert in ihrer Position.
  5. Jede Ziffer wird durch mindestens 1 Zeichen dargestellt. Wenn ein Ziffernwert für alle Zahlen in einem Quipu 0 ist, wird dies durch das Fehlen eines Knotens ( |) dargestellt.
  6. Der Geräteplatz wird speziell behandelt. Eine Eins an der Stelle der Einheit wird durch einen Achterknoten ( 8) dargestellt. Ein Wert von zwei oder mehr an der Stelle der Einheit wird durch aufeinanderfolgende lange Knoten ( :) dargestellt.
  7. Wenn die Einheitenziffer für alle Zahlen in einem Quipu 0 ist, wird das Fehlen eines Knotens nicht gedruckt, aber das nachgestellte Trennzeichen für die Zehnerstelle wird beibehalten.
  8. Nach der Einerstelle folgt kein Trennzeichen.

Regeln

  • Die Eingabe besteht aus einer nicht leeren Liste nicht negativer Ganzzahlen, die über eine der Standardeingabemethoden empfangen werden können . Sie können davon ausgehen, dass diese ganzen Zahlen kleiner oder gleich 2147483647oder sind 2^31-1. Während die Testfälle durch Leerzeichen getrennt sind, kann Ihr Eingabeformat Eingaben in einer für Ihre Sprache geeigneten Weise trennen, sei es durch Kommas oder Zeilenumbrüche getrennt, in einem Array usw.
  • Die Ausgabe besteht aus einem einzelnen Quipu, der nach den oben beschriebenen Regeln aufgebaut ist. Die Ausgabe kann über eine der Standardausgabemethoden erfolgen .
  • Ihr Code sollte ein Programm oder eine Funktion sein, obwohl es keine benannte Funktion sein muss.
  • Das Binden von Knoten nimmt einige Zeit in Anspruch, um Zeit zu sparen und Ihren Code so kurz wie möglich zu halten.

Wie immer, wenn das Problem unklar ist, lassen Sie es mich bitte wissen. Viel Glück und gutes Golfen!

Beispiele

Eingang:

5 3 1 0

Ausgabe:

:|||
:|||
::||
::||
::8|

Eingang:

50 30 10 0

Ausgabe:

.|||
.|||
..||
..||
...|
||||

Eingang:

330

Ausgabe:

.
.
.
|
.
.
.
|

Eingang:

204 1

Ausgabe:

.|
.|
||
||
||
:|
:|
:|
:8

Eingang:

201 0 100 222

Ausgabe:

.||.
.|..
||||
|||.
|||.
||||
|||:
8||:

Eingang:

1073741823 2147483647

Ausgabe:

|.
..
||
|.
||
.|
.|
.|
..
..
..
..
||
|.
|.
|.
|.
..
..
..
||
.|
.|
.|
..
..
..
..
||
|.
|.
|.
|.
..
..
..
..
||
|.
|.
..
||
.|
.|
..
..
..
..
..
..
||
|.
|.
..
..
||
|:
|:
|:
|:
::
::
::

Eingang:

0

Ausgabe:

|

Längere Testfälle

Weitere Lektüre

Sherlock9
quelle

Antworten:

3

Pyth, 64 Bytes

=QjRTQjCmj\|+:R"[8:]"\.PdedCmm+*\|-h.MZdk*?tk\:\8kdC.[L0h.MZlMQQ

Probieren Sie es online!

Wie es funktioniert

=QjRTQ   Converts each number in input to decimal (as a list)
         123 becomes [1,2,3]

----

jCmj\|+:R"[8:]"\.PdedCmm+*\|-h.MZdk*?tk\:\8kdC.[L0h.MZlMQQ

                                              .[L0       Q  0-leftpad each #
                                                  h.MZlMQ   (max length) times

                                             C              transpose

                      mm                    d    for each digit:
                        +                        [convert to] sum of
                         *\|                     "|" repeated
                            -                    the difference of
                             h.MZd               maximum digit in same row
                                  k              and itself.. that many times
                                   *?tk\:\8      and (digit > 1 then ":" or "8") repeated
                                           k     itself many times


the list:
[11,23,52]
->[[1,1],[2,3],[5,2]]
->[[1,2,5],[1,3,2]]
->[["||||8","|||::",":::::"],["||8",":::","|::"]]

                     C      transpose

->[["||||8","||8"],["|||::",":::"],[":::::","|::"]]

  m                          for each number
      +                      [convert to] sum of
                 Pd          every element but the last
       :R"[8:]"\.            with "8" and ":" replaced by "."
                   ed        and the last element
   j\|                       joined with "|"

  C                          transpose
 j                           join (with newlines)
Undichte Nonne
quelle
Dies ist eine hervorragende Antwort mit Ausnahme eines Problems. Der letzte Knoten ist nicht immer ein Achterknoten 8. Tatsächlich ist es nur ein 8Knoten, wenn die letzte Ziffer eine 1 ist (siehe Regel 6). Sie konvertieren alle Endknoten und das stimmt nicht mit der Spezifikation überein. Versuchen Sie es auch online! Der Link hat einen anderen Code als der, der anscheinend hier gepostet wurde
Sherlock9
22

Nicht lesbar , 3183 3001 Bytes

Es war eine lustige Herausforderung, zwischen den Weihnachtsfeiern hin und her zu arbeiten. Vielen Dank für die Veröffentlichung! Das Golfen war interessant, da die Spezifikation viele Ausnahmen und Sonderfälle enthält, für die viele Bedingungen erforderlich waren. Auch wenn ich dieses Mal nicht in und von Dezimalstellen konvertieren musste, benötigte ich eine Art "Max" -Funktion, um die größte Anzahl von Ziffern in jeder Zahl und den größten Wert der Ziffern an jeder Stelle zu bestimmen.

Die erste Version davon war 4844 Bytes, nur um Ihnen eine Vorstellung davon zu geben, wie viel ich das gespielt habe.

Das Programm erwartet die Eingabe als durch Kommas getrennte Liste von Ganzzahlen. Keine Leerzeichen oder Zeilenumbrüche. Die Verwendung dieser führt zu undefiniertem Verhalten.

"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "

Erläuterung

Ich werde Sie durch die Funktionsweise des Programms führen, indem ich Ihnen zeige, wie es die spezifischen Eingaben verarbeitet 202,100,1.

Zu Beginn konstruieren wir einige Werte, die wir später benötigen werden - hauptsächlich die ASCII-Codes der Zeichen, die wir ausgeben werden.

Bildbeschreibung hier eingeben

Wie Sie sehen können '8'und '.'bereits verfügbar sind. '|'ist jedoch 124, nicht 14. Wir verwenden eine while-Schleife, um den doppelten temporären Wert in Slot # 1 zu addieren und 124 zu erhalten (das ist 14 + 55 × 2, da die while-Schleife für 56−1 = 55 läuft Iterationen). Dies spart einige Bytes, da große Integer-Literale wie 124 sehr lang sind. Im folgenden Diagramm zeige ich die Position jeder vom Programm verwendeten Variablen.

Bildbeschreibung hier eingeben

Als nächstes wollen wir alle Zeichen eingeben und sie ab Zelle 12 auf dem Band speichern ( p ist der laufende Zeiger dafür). Gleichzeitig möchten wir wissen, wie lang die längste Nummer ist (wie viele Ziffern). Um dies zu erreichen, führen wir eine laufende Summe in unary beginnend bei Zelle # −1 nach links (wir verwenden q als laufenden Zeiger). Nach der ersten eingegebenen Nummer ( 202) sieht das Band nun so aus:

Bildbeschreibung hier eingeben

Sie werden bemerkt haben, dass die Zahlen um 4 abweichen. Nun, wenn wir sie zum ersten Mal eingeben, handelt es sich um ihre ASCII-Werte, also sind sie um 48 "ausgeschaltet" und das Komma ist 44. Für jedes Zeichen kopieren wir die 46 von '.'in r und subtrahieren es dann mit einer while-Schleife (die 45 subtrahiert) und dann addieren wir 1. Wir machen das so, dass das Komma (unser Trennzeichen) 0 ist, so dass wir eine Bedingung verwenden können, um es zu erkennen.

Außerdem haben Sie bemerkt, dass wir die Zelle Nr. 11 auf 0 belassen. Dies ist erforderlich, um die Grenze der ersten Zahl zu erkennen.

Das nächste Zeichen ist ein Komma, also speichern wir eine 0 in # 15, aber dieses Mal rücken wir natürlich q nicht vor . Stattdessen setzen wir q auf 0 zurück und “überschreiben” die 1, die wir bereits platziert haben.

Nachdem alle verbleibenden Zeichen verarbeitet wurden, erhalten wir Folgendes:

Bildbeschreibung hier eingeben

Wie Sie sehen, geben die von q geschriebenen Einsen (in unary) die Länge der längsten Zahl an.

Wir verwenden jetzt eine while-Schleife, um q ganz nach links zu verschieben und platzieren dann einen anderen Zeiger, den ich r2 nennen werde . Der Zweck von r2 wird später klar.

Bildbeschreibung hier eingeben

Lassen Sie mich an dieser Stelle die Terminologie klarstellen, die ich in dieser gesamten Beschreibung verwenden werde.

  • Mit Nummer meine ich eine der Eingabenummern, die durch Kommas getrennt sind. In unserem Beispiel sind das 202, 100 und 1.
  • Mit Ziffer meine ich eine einzelne Ziffer in einer bestimmten der Zahlen. Die erste Nummer besteht aus 3 Ziffern.
  • Mit Ort meine ich den einen Ort, den Zehnerort, den Hunderterort usw. Wenn ich also „die Ziffern am aktuellen Ort“ sage und der aktuelle Ort derjenige ist, sind diese Ziffern darin 2, 0 und 1 Bestellung.

Nun zurück zu unserer regulären Programmierung. Der gesamte Rest des Programms ist eine große Schleife, die q vorwärts bewegt , bis sie die Zelle # 0 erreicht. Jede der Zellen auf dem Weg stellt einen Ort dar, wobei sich der eine ganz rechts befindet und q am signifikantesten beginnt. In unserem Beispiel ist das die Hunderterstelle.

Wir fahren fort, indem wir die q- Punkte der Zelle inkrementieren (d. H. * Q ).

Bildbeschreibung hier eingeben

Wir sind jetzt auf "Stufe 2" für den Hundertplatz. In dieser Phase werden wir herausfinden, welche der hundert Stellen die größte unter allen Stellen ist. Wir verwenden dafür denselben unären Zähltrick, außer dass der Zeiger dieses Mal r heißt und der Zeiger r2 seine Startposition markiert, auf die wir ihn jedes Mal zurücksetzen müssen, wenn wir zur nächsten Zahl übergehen.

Beginnen wir mit der ersten Zahl. Wir beginnen mit der Einstellung von p auf 11 (die fest codierte Startposition aller Zahlen). Wir benutzen dann eine while-Schleife, um das Ende der Zahl zu finden und setzen dort p2 , um die Position zu markieren. Gleichzeitig setzen wir q2 auf 0:

Bildbeschreibung hier eingeben

Lassen Sie sich nicht von der Tatsache ablenken, dass q2 in die Vars zeigt. Wir haben dort kein Auffüllen einer leeren Zelle, weil wir die Zelle 0 erkennen können, nur weil sie die Nummer Null ist.

Als nächstes gehen wir die aktuelle Zahl durch, indem wir p und q2 zusammen dekrementieren, bis * p Null ist. An jeder Stelle gibt der Wert von * q2 an , was zu tun ist. 1 bedeutet „nichts tun“, also machen wir weiter. Schließlich begegnen wir der 2 in Zelle # -3. Jedes Mal, wenn * q2 ungleich 1 ist, ist q2 immer gleich q .

Bildbeschreibung hier eingeben

Wie ich bereits sagte, ist Stufe 2 "die größte Ziffer an dieser Stelle bestimmen". Also setzen wir r auf r2 , dekrementieren * p mit einer while-Schleife, bewegen r nach links und füllen das Band mit 1s und verwenden dann eine andere while-Schleife, um r zurück nach rechts zu bewegen und * p erneut zu erhöhen, um den Wert wiederherzustellen. Denken Sie daran, dass jede while-Schleife eine Iteration kürzer als der Wert ist, für den sie verwendet wird. Aus diesem Grund ist die Anzahl der geschriebenen Einsen um 3 höher (anstatt um 4 höher) als der Ziffernwert, und der in * p zurückgespeicherte Endwert ist um 2 höher. Dies hat also effektiv * p um 2 dekrementiert .

Danach setzen wir p auf den Wert von p2 und machen das alles noch einmal. Setzen Sie q2 zum zweiten Mal auf 0, suchen Sie das Ende der Zahl, indem Sie p nach rechts bewegen , und gehen Sie dann die Ziffern dieser Zahl durch, indem Sie p und q2 zusammen dekrementieren . Wieder werden wir in Zelle # −3 auf die 2 stoßen und so viele Einsen von * r schreiben, wie noch vorhanden sind .

Bei der dritten Zahl machen wir nichts, weil sie keine Hunderterstelle hat (also q2 nie q erreicht ), aber das ist in Ordnung, weil das die Berechnung des maximalen Ziffernwerts nicht beeinflusst.

Bildbeschreibung hier eingeben

Wir setzen auch die Zelle * (r - 4) , die ich hier mit einem unbeschrifteten Pfeil markiert habe, auf 1 (obwohl sie bereits auf 1 steht). Ich werde dir noch nicht sagen warum, aber vielleicht hast du es schon erraten?

Das nächste Inkrement von * q führt uns zu Stufe 3, in der „die maximale Ziffer von allen Ziffern an der aktuellen Stelle subtrahiert“ wird. Wie zuvor setzen wir p auf 11 und q2 auf 0 zurück und gehen dann alle Zahlen durch, wie wir es in der vorherigen Stufe getan haben; außer diesmal * q = 3 statt 2. Jedes Mal, wenn q2 auf q trifft und p an einer Hunderterstelle liegt, dekrementieren wir * p mit einer while-Schleife so oft, wie der Block von * r2 (5) noch Einsen enthält in unserem Beispiel) mit rals laufender Zeiger. Wir dekrementieren es tatsächlich noch einmal, damit die größte Ziffer bei -2 endet, aus einem Grund, der später noch klar wird:

Bildbeschreibung hier eingeben

Nachdem wir alle Zahlen verarbeitet haben, sind wir nun am Ende von Stufe 3. Hier führen wir zwei singuläre Dinge durch.

  • Zuerst subtrahieren wir auch die Größe des r- Blocks (plus 1) von * q , verwenden aber den r2- Zeiger, der ihn links belässt. * q wird auf diese Weise negativ. In unserem Fall hat der r- Block fünf Einsen, also wird * q −3.
  • Zweitens haben wir eine Variable out auf einen Wert ungleich Null , um anzuzeigen , dass man nun die Ausgangsstufe eintreten. (Technisch gesehen zeigt die Tatsache, dass * q negativ ist, bereits die Ausgangsstufe an, aber dies ist zu schwierig zu überprüfen, daher die zusätzliche Variable.)

Sie verstehen jetzt, dass wir die Zahlen durchgehen, die aktuelle Position (angegeben durch den Wert * q ungleich 1 ) in jeder Zahl finden und abhängig vom Wert * q etwas unternehmen . Wir sehen, dass * q zuerst auf 2 inkrementiert wird (= Maximalziffernwert berechnen), dann auf 3 (Maximalziffernwert von jeder Ziffer an dieser Stelle subtrahieren) und dann von dieser subtrahieren, um sie negativ zu machen. Von dort steigt es weiter an, bis es 1 erreicht, wodurch der Wert wiederhergestellt wird, der bedeutet, dass Sie nichts tun. An diesem Punkt gehen wir weiter zum nächsten Ort.

Wenn nun * q negativ ist, geben wir aus. * q hat genau den richtigen Wert, sodass die richtige Anzahl von Zeichenzeilen ausgegeben wird, bevor 1 erreicht wird. Wenn die größte Ziffer 2 ist, müssen 3 Zeilen ausgegeben werden. Mal sehen, was bei jedem Wert von * q passiert :

  • * q = −2:
    • Für die erste Zahl ist * p −2, was anzeigt, dass wir einen '.'(Punkt) oder einen ':'(Doppelpunkt) ausgeben müssen . Wir entscheiden, was durch Betrachten von q : Wenn es −1 ist, sind wir an der richtigen Stelle, also geben Sie a aus ':'(was wir als '8'+2 berechnen ), andernfalls a '.'.
    • Für die zweite Zahl ist * p -3. Alles, was nicht −2 ist, bedeutet, dass wir eine '|'(Pipe) ausgeben und dann den Wert erhöhen . Auf diese Weise erreicht es −2 an der richtigen Stelle und wir geben '.'s / ':'s für den Rest dieser Ziffer aus.
    • In jedem Fall setzen wir auch eine Variable pd auf 0, bevor wir die Zahl verarbeiten, und setzen pd (= "gedruckt") auf einen Wert ungleich Null, um anzuzeigen, dass wir ein Zeichen gedruckt haben.
    • Bei der dritten Nummer findet keine Verarbeitung statt, da die dritte Nummer keinen Platz für Hunderte hat. In diesem Fall ist pd nach der Verarbeitung der Zahl immer noch 0, was darauf hinweist, dass wir immer noch a ausgeben müssen '|'(aber nur, wenn out nicht Null ist, da wir uns sonst immer noch in Stufe 2 oder 3 befinden).
    • Wenn out nicht Null ist, geben Sie nach der Verarbeitung aller Zahlen eine neue Zeile aus. Beachten Sie, dass wir die Variable out benötigen , damit wir die Newline in Stufe 2 oder 3 nicht ausgeben.
  • * q = −1: Wie zuvor, mit der Ausnahme, dass * p für beide ersten beiden Zahlen −2 ist, sodass beide a ausgeben'.'(und der dritte a'|'wie zuvorausgeben).
  • * q = 0: Wenn * q 0 ist, bedeutet dies, dass Sie nichts tun, wenn Sie an der richtigen Stelle sind, andernfalls eine Zeile mit'|'s unabhängig von * p ausgeben. Auf diese Weise erhalten wir den Abstand zwischen den Ziffern.

Jetzt erhöhen wir q , um zur nächsten Stelle, der Zehnerstelle, zu gelangen, und erhöhen dort * q . Zu Beginn von Stufe 2 sieht das Band folgendermaßen aus:

Bildbeschreibung hier eingeben

Dann führen wir Stufe 2 wie zuvor durch. Denken Sie daran, dass dies effektiv 2 von jeder Ziffer an dieser Stelle subtrahiert und außerdem eine unäre Zahl von * r2 übrig lässt , die die maximale Ziffer angibt. Wir lassen die vorherige unäre Nummer in Ruhe und verlängern das Band einfach weiter nach links. Es würde nur unnötigen zusätzlichen Code kosten, um "aufzuräumen". Wenn wir fertig sind und * q erhöhen, lautet das Band zu Beginn von Stufe 3 wie folgt:

Bildbeschreibung hier eingeben

Eigentlich ist das eine Lüge. Weißt du noch, wo ich sagte, wir hätten * (r - 4) auf 1 gesetzt, und ich habe dir nicht gesagt, warum? Jetzt sage ich dir warum. Dies gilt für Fälle wie diesen, in denen die größte Ziffer tatsächlich 0 ist, was bedeutet, dass alle Ziffern an dieser Stelle 0 sind. Wenn Sie * (r - 4) , angezeigt durch den nicht gekennzeichneten Pfeil oben, auf 1 setzen, wird die unäre Zahl um 1 erweitert. aber nur in diesem speziellen Fall. Auf diese Weise tun wir so, als ob die größte Ziffer 1 wäre, was bedeutet, dass wir eine zusätzliche Zeile ausgeben.

Nach Stufe 3 (maximale Stelle von allen Stellen an der aktuellen Stelle abziehen), einschließlich des zusätzlichen Schritts, der * q negativ macht, sieht das Band so aus. Beim letzten Mal wurde die größte Ziffer im * p- Block durch –2 dargestellt , aber diesmal sind sie alle –3, weil sie eigentlich alle Nullen sind, aber wir tun so, als wäre die maximale Ziffer eine 1.

Bildbeschreibung hier eingeben

Nun wollen wir sehen, was passiert, wenn * q auf 1 zugeht :

  • Wenn * q = −1, sind die * p- Werte alle −3, was bedeutet, dass wir '|'s ausgeben und inkrementieren.
  • Wenn * q = 0, geben wir aus, '|'weil wir dies immer tun, wenn * q = 0, unabhängig von * p .

So erhalten wir zwei Rohrreihen.

Schließlich bewegen wir uns * q an die eigene Stelle. Dies wird interessant, weil wir ':'s ausgeben müssen, wenn die tatsächliche Ziffer nicht 1 ist, sondern '8'1. Mal sehen, wie das Programm abläuft. Zuerst erhöhen wir * q , um Stufe 2 einzuleiten:

Bildbeschreibung hier eingeben

Nach Stufe 2 („Maximaler Ziffernwert berechnen“) bleibt Folgendes übrig:

Bildbeschreibung hier eingeben

Nach Stufe 3 ("Maximaler Stellenwert von allen Stellen an der aktuellen Stelle subtrahieren") sieht das Band folgendermaßen aus:

Bildbeschreibung hier eingeben

Gehen wir nun nacheinander jede Iteration von * q durch:

  • * q = −2:
    • Erste Zahl: bereits bei −2, also gib a aus ':'(anstatt a, '.'weil q = −1).
    • Zweite Zahl: bei -4, also a ausgeben '|'und inkrementieren.
    • Dritte Zahl: bei -3, also gib a aus '|'. Diesmal wird jedoch ein Sonderfall ausgelöst, anstatt ihn zu erhöhen. Nur wenn wir den letzten Platz ausgeben ( q = −1) und dafür in der vorletzten Zeile stehen ( * q = −2) und die Ziffer tatsächlich eine 1 ist ( * p = −3) , dann , anstatt sie auf -2 erhöht wird , setzen wir es auf -1. Mit anderen Worten, wir verwenden −1 als speziellen Wert, um anzuzeigen, dass wir in der nächsten Iteration '8'statt ausgeben müssen ':'.
  • * q = −1:
    • Erste Zahl: bereits bei −2, also gib a aus ':'.
    • Zweite Zahl: bei -3, also gib a aus '|'. Die Sonderbedingung wird nicht ausgelöst, weil * q nicht mehr −2 ist. Daher inkrementieren.
    • Dritte Zahl: bei -1, also Ausgabe '8'.
  • * q = 0: Normalerweise würden wir hier die Auffüllzeile von'|'sausgeben, aber in dem speziellen Fall, in dem wir uns an der einen Stelle befinden ( q = −1), überspringen wir diese.

Danach wird q auf 0 erhöht und die große while-Schleife endet.

Jetzt wissen Sie, wie eine Eingabe 202,100,1funktioniert. Es gibt jedoch einen weiteren Sonderfall, den wir noch nicht behandelt haben. Sie erinnern sich vielleicht, dass wir während der Verarbeitung des letzten Platzes, als * p −3 war, diesen Wert auf −1 gesetzt haben 1(anstatt ihn auf −2 zu erhöhen), damit bei der nächsten Iteration '8'stattdessen ein ausgegeben wird. Dies funktioniert nur, weil wir eine Iteration haben, in der * p −3 ist, und wir entscheiden, ob wir es inkrementieren oder auf −1 setzen. Wir nicht haben eine solche Iteration , wenn alle der Ziffern in der Einerstelle 0 oder 1. In einem solchen Fall werden alle * p - Werte für die 1s würde beginnen bei -2; Es gibt keine Möglichkeit, sich zu entscheiden, es auf -1 zu setzenanstatt es von -3 zu erhöhen . Aus diesem Grund gibt es innerhalb von Stufe 3 eine weitere Sondergehäusebedingung ("maximale Ziffer von jeder Ziffer an der aktuellen Stelle subtrahieren"). Ich habe behauptet, dass wir nach dem Subtrahieren des maximalen Ziffernwerts von jeder Ziffer (an diesem Punkt liegt die maximale Ziffer bei -1) nur noch einmal dekrementieren, aber tatsächlich gibt es eine Bedingung dafür, die wie folgt lautet:

Wenn die Ziffer, die wir betrachten, gleich der maximalen Ziffer an dieser Stelle ist ( * p = −1) und diese Stelle die Einerstelle ist ( q = −1) und die maximale Ziffer ist 1 ( * (r +) 5) = 0, dh der unäre Block ganz links ist nur 5 Zellen lang), nur dann belassen wir * p bei -1, um anzuzeigen, dass die einzige Iteration der Ausgabe ein ausgeben muss '8'. In allen anderen Fällen verringern wir es noch einmal.

Getan. Frohes neues Jahr!

  • Edit 1 (3183 → 3001): Frohes Neues Jahr beim Golfen! Ich habe es geschafft, die Variablen p2 und r2 komplett loszuwerden ! p rast nun hin und her, um den Anfang und das Ende von Zahlen zu finden, aber der Code scheint kürzer zu sein. Ich habe versucht, auch Q2 loszuwerden , aber ich konnte den Code auf diese Weise nicht kürzer machen.

    Ich habe auch ein paar weitere Stellen gefunden, an denen ich typische Unreadable-Golftricks anwenden kann, beispielsweise den letzten Wert einer while-Schleife erneut verwenden. Um Ihnen ein Beispiel zu geben, anstatt

    while *(++p) { 1 }         // just increment p until *p is 0; the 1 is a noop
    if (pd) { x } else { y }   // where pd is a variable
    

    Ich kann das '""""(mache das erste, dann das zweite) und das '"""(konstante 1) retten , indem ich es auf eine Art schreibe, die der gleichen ist

    if (while *(++p) { pd }) { x } else { y }
    

    Dies funktioniert natürlich nur, wenn ich weiß, dass die while-Schleife für mindestens eine Iteration ausgeführt wird, aber wenn dies der Fall ist, ist ihr Rückgabewert pd, sodass ich das als Bedingung für das if verwenden kann.

Timwi
quelle
"Unleserlich" ist sicherlich ein passender Name ...
Alex A.
9
-1 nicht genug Erklärung
Der Kerl mit dem Hut
7

Javascript (ES6) 750 744 690 604 498 346 245 234 Bytes

Ich bin neu in PPCG und dachte, ich könnte es versuchen, weil ich dachte, es sei ziemlich einfach. Junge, habe ich mich geirrt !! Ich arbeite schon eine Weile daran und habe viel zu golfen ...
Vorschläge werden ermutigt! - obwohl es keine leichte Aufgabe ist, dies zu verstehen.

Gibt Seile aus, wenn die Eingabe ein Array von Zahlen ist (zB:) [204, 1].

a=>(o=m=s="",l=a.map(n=>(s+="|",l=(n+"").length)>m?m=l:l),h=[],a=a.map((n,i)=>[..."0".repeat(m-l[i])+n].map((d,j)=>d<h[j]?d:h[j]=d)),h.map((n,i)=>{i?o+=s+`
`:0;for(j=n;j--;o+=`
`)a.map(d=>o+="|.:8"[d[i]-j<1?0:i<m-1?1:d[i]-1?2:3])}),o)

Erläuterung

a=>(

  o=m=s="",                      // m = max number of digits in a number, s = separator string         
  l=a.map(n=>(                   // l = lengths of each number
      s+="|",                    // set the separator string
      l=(n+"").length                 // convert each number to a string
    )>m?m=l:l                    // get max length
  ),
  h=[],
  a=a.map((n,i)=>
    [..."0".repeat(m-l[i])+n]    // add leading 0s to make all same length
    .map((d,j)=>d<h[j]?d:h[j]=d) // set each digit of h to max
  ),

  h.map((n,i)=>{
    i?o+=s+`
`:0;
    for(j=n;j--;o+=`
`)
      a.map(d=>
        o+=
          "|.:8"[
            d[i]-j<1?0
            :i<m-1?1
            :d[i]-1?2:
            3
          ]
      )
  }),
  o
)

Beispiel

Eingabe: Array von Zahlen: [4,8,15,16,23,42]
Ausgabe:

|||||.
|||||.
||||..
||....
||||||
|:||||
|:||||
|:|:||
|:::||
::::||
:::::|
::::::
::::::
Aᴄʜᴇʀᴏɴғᴀɪʟ
quelle
+1 beeindruckendes Golfen. Fügen Sie ein Beispiel mit Input und Output hinzu?
DavidC
@ DavidC Danke! Und das Beispiel ist enthalten. Rufen Sie es von der Konsole aus auf und es gibt eine Zeichenfolge zurück. :)
29.
7

Python 3, 624 598 595 574 561 535 532 527 525 426 345 328 324 294 288 286 283 280 267 265 255 251 245 238 235 234 230 228 Bytes

z=input().split();v=max(map(len,z));d=''.join(i.zfill(v)for i in z);x=['']*len(z)
for k,c in enumerate(d):j=k%v;m=int(max(d[j::v]));c=int(c);x[k//v]+="|"*(m-c+0**m+(j>0))+":8."[(c<2)|-(j<v-1)]*c
for r in zip(*x):print(*r,sep='')

Nun, da diese Frage eine Antwort benötigt, habe ich hier eine angegeben, bei der die Eingabe eine durch Leerzeichen getrennte Folge von Zahlen sein sollte, wie z "204 1". Junge, ist es eine lange. Vorschläge zum Golfen (oder bessere Antworten) sind willkommen.

Bearbeiten: Durch Mischen von Tabulatoren und Leerzeichen gespeicherte Bytes.

Bearbeiten: Ich habe eine Menge Bytes gespart, indem ich geändert habe, wie ich die Ziffern einer Zahl erhalten habe (erstelle eine Liste aus der mit Nullen aufgefüllten Zeichenfolge der Zahl, dann transponiere sie in den Hauptteil des Codes, um Hunderte Ziffern, zehn Ziffern usw. Zu erhalten .)

Edit: Und ich habe noch mehr gespart, indem ich diese letzte :8Schleife in die Haupt-Quipu-Schleife aufgenommen habe. Wenn ich nur herausfinden könnte, warum b=d[j*v+i]==m(d[i::v])das nicht funktioniert. Hat es herausgefunden und die Lösung benötigt zu viele Bytes. (Auch die Byteanzahl ist gesunken, weil die Tabulatoren wieder in vier Leerzeichen umgewandelt wurden. Dies war wahrscheinlich die Codeblockformatierung auf dieser Site.)

Edit: Ich habe reorganisiert, wie der Quipus gemacht wurde. Jetzt wird jeweils ein Strang erstellt und dann zum Drucken transponiert.

Bearbeiten: Meine Antwort wurde wieder in ein Python 3-Programm umgewandelt, um weitere Bytes zu sparen.

Bearbeiten: Ich habe einen Fehler in meinem Code gefunden, der dazu führte, dass keine Nullen in der Mitte der Zahlen korrekt gedruckt wurden (siehe Testfall 204 1oben). Bei der Behebung dieses Problems habe ich es geschafft, Golf zu spielen :)

Bearbeiten: Ich habe den Druck geändert, um 10 Bytes zu sparen. Und ich habe alle alten Byte-Zählungen zurückgesetzt, nur weil.

Bearbeiten: Golfed die Zuweisung der vVerwendung mapfür vier Bytes. Dank an CarpetPython , da ich die Idee von ihrer Antwort hier habe .

Bearbeiten: Die mittlere "for-Schleife in einer for-Schleife" wurde in eine for-Schleife für sechs Bytes umgewandelt.

Bearbeiten: Jetzt mit enumerate. Nicht mehr verwenden l=len(z). Verwandelte den Ternär if-elsein einen Listenternär. Siehe unten für Details.

Bearbeiten: Sp3000 schlug eine Bearbeitung für printund eine Bearbeitung für die ternäre Bedingung vor, bei der jeweils ein Byte gespeichert wurde.

Ungolfed:

s = input()
z = s.split()
v = max(map(len, z))                # the amount of digits of the largest number
d = ''.join(i.zfill(v) for i in z)  # pad zeroes until every number is the same length
                                     # then join the numbers into one string
x = ['']*len(z)                     # a list of strings for the output, one for each number

for k,c in enumerate(d):          # for every digit in every number
    i,j = divmod(k, v)            # i is the index of the number we're on
                                   # j is the index of the digit of the number we're on
    m = int(max(d[j::v]))         # the largest of all the digits in the j-th place
    c = int(c)                    # the digit in j-th place of the i-th number
    x[i] += "|"*(m-c+0**m+(j>0))  # pad | to size m-c, until the knots are correctly spaced
                                  # add a | if m<1, all j-th place digits are 0
                                  # add a | if j>0, if it's not at the start, as delimiters
    x[i] += ":8."[(c<2)|-(j<v-1)] * c
    # this is essentially the following code
    # if j<v-1:
    #     x[i] += "."*c      # . knots if not in the units place
    # else:
    #     if c == 1:
    #         x[i] += "8"*c  # 8 knots for ones in the units place
    #     else:
    #         x[i] += ":"*c  # : knots for something else is in the units place

for r in zip(*x):       # transpose so all the rows (the quipu strings) now hang down
    print(*r, sep='')    # join the strings together at each knot
                         # and print each on a separate line
Sherlock9
quelle
Gibt es hier etwas spezielles für Python 3 ? Wenn nicht, könnte die Konvertierung in Python 2 einige Bytes
einsparen
@Cyoce Nichts zu Python 3-spezifisch. Ich habe gerade in Python 3 angefangen, weil das die Version ist, die ich habe. Ich werde eine Python 2-Version auf Ideone oder so testen.
Sherlock9
@Maltysen Das funktioniert nicht mit Eingaben, die mit beginnen 0, wie z 0 12 4.
Sherlock9
Sie können einige Bytes speichern, indem Sie Tabulatoren und Leerzeichen für den Einzug in Python 2 abwechseln. Ich glaube, 1 Tabulatorzeichen == 8 Leerzeichen laut Pythons
Einzugsparser
for r in zip(*x):print(''.join(r))->print(''.join(r)for r in zip(*x))
Undichte Nonne
4

C, 238 235 Bytes

Verlassen Sie sich stark auf den C-Präprozessor, um den Code so kurz wie möglich zu halten. Als Nebeneffekt macht es auch ziemlich unlesbar.

#define l strlen(a[i])
#define d l<k||a[i][l-k]-48
#define m(e) for(i=1;a[i];e<=r?i++:r++);
#define p(e) {m(!putchar(e?'|':k>1?46:d<2?56:58))puts("");}
k,r;main(int i,char**a){m(l)for(k=r,r=1;k;r=k>1){m(d)for(;r;r--)p(d<r)if(--k)p(1)}}

Unter Ubuntu 14.04 können Sie den Code einfach kompilieren gcc quipu.c (bitte ignorieren Sie die Warnungen). Ein Beispiel für die Ausführung der ausführbaren Datei:

$ ./a.out 1 2 3 2 1
||:||
|:::|
8:::8

Getestet gegen alle OP's Testfälle.

Ungolfed-Quellcode:

// Standard library; leaving out the includes still gives executable code despite the warnings.
#include <stdio.h>
#include <string.h>

// 4 preprocessor macros.
// Note: some of these actually make use of the fact that parentheses have been left out

// l: length of argument i
#define l     strlen(a[i])

// d: shorthand for a digit
#define d     l<k || a[i][l-k]-'0'

// m: loop across all arguments; calculates r as the maximum of expression e
#define m(e)  for (i=1; a[i]; e<=r ? i++ : r++);

// p: prints one line of output
// note: intentionally does not use the r++ code branch of m;
//       putchar always returns a non-zero number here, so !putchar is zero,
//       which is always <=r (because r is never negative)
// note: the semicolon after m(...) is redundant;
//       the definition of m already contains a semicolon
// note: puts("") outputs a newline
#define p(e)  { m(!putchar(e ? '|' : k > 1 ? '.' : d < 2 ? '8' : ':')); puts(""); }

// k: knot position; 1 for units, 2 for tens, 3 for hundreds...
int k;

// r: input and output value for m
// note: the first time we call m, we need r to be zero;
//       by defining it outside main, it is automatically initialized as such
int r;

// function main
// note: parameter i (normally named argc by convention) is not needed
//       (the last element of argv is known; it is followed by a NULL pointer)
//       but we cannot leave it out (otherwise we cannot access argv)
//       so it serves as a local variable (to loop through arguments; see m)
// note: parameter a (normally named argv by convention)
//       is the array of arguments (starting from index 1)
int main(int i, char **a)
{
    // Determine the longest argument; store its length in r.
    // This is the number of knot positions to consider.
    m(l)

    // Iterate k through the knot positions from top to bottom.
    // Note: k > 0 has been abbreviated to k.
    // Note: for each iteration, we also initialize r with either 0 or 1.
    //       0 = suppress printing when all knots are zero
    //       1 = always print, even when all knots are zero
    for (k = r, r = 1; k > 0; r = k > 1)
    {
        // Determine the highest digit at this knot position.
        // Note: due to the absence of parentheses, d mixes up with <=r into:
        // (l < k) || (a[i][l-k]-'0' <= r)
        m(d)

        // Count the digits down.
        for (; r; r--)
        {
            // Print a single line of output.
            // When d (the digit in the current strand) is less than the counter,
            // then print a '|', otherwise print a knot.
            p(d < r)
        }

        // Decrement k (go to next knot position).
        // If this was not the last iteration...
        if (--k > 0)
        {
            // Print separator line.
            p(1)
        }
    }

    // Return exit code zero; redundant.
    return 0;
}
Ruud Helderman
quelle
Herzliche Glückwünsche! Als kürzeste Antwort innerhalb des Prämienzeitraums haben Sie meine Prämie von +50 Wiederholungen erhalten. Gute Antwort! :)
Alex A.
4

Mathematica 436 453 357 352 347 Bytes

t=Transpose;y=ConstantArray;a=Table;
g@j_:=(s=t[PadLeft[#,Max[Length/@i]]&/@(i=IntegerDigits@#)]&;p_~u~o_:=(m=Max@p;c=If[o==-2,":","."];w=If[o==-2,"8","."];p//.{0->a["|",Max@{1,m}],1->Join[a["|",{m-1}],{w}],n_/;MemberQ[2~Range~9,n]:>Join[y["|",m-n ],c~y~n]});t[Join@@@t@Join[u[#,0]&/@Most@#,u[#,-2]&/@{#[[-1]]}]]&[Riffle[(s@j),{a[0,Length@j]}]]//Grid)

Obenstehendes

  • Bricht jede Ganzzahl mit in eine Liste von Ziffern auf IntegerDigits ; . füllt jede Zahl links mit Nullen auf (um den gleichen Abstand zu gewährleisten); Jede eingegebene Nummer, die jetzt in Ziffern zerlegt ist, entspricht einer Zeile eines Arrays. Jede Spalte repräsentiert einen Platzwert. Array wird transponiert.
  • Ersetzt Ziffern durch eine Liste von Knoten mit Polsterung. Für die Einheiten wird eine etwas andere Musteranpassungsroutine verwendet.

Beispiel

g[Range[0, 50]]

fünfzig

DavidC
quelle
Transpose@Join? Das sollte doch sein, oder?
CalculatorFeline
Ja. Danke, dass du das verstanden hast.
DavidC
Platz davor.
CalculatorFeline
1

R - 446 444

Ich sehe, dass es noch keine R-Lösung gibt, also hier eine. Die Funktion nimmt einen Vektor mit ganzen Zahlen.

function(x){r=nchar(max(x));c=length(x);m=matrix(0,r,c);for(i in 1:c){t=as.numeric(strsplit(as.character(x[i]),"")[[1]]);m[(r+1-length(t)):r,i]=t};Q=c();for(i in 1:r){d=m[i,];z=ifelse(max(d)>0,max(d),1);q=matrix("|",z,c);for(j in 1:c){v=m[i,j];if(i==r){if(v==1)q[z,j]=8;if(v>1)q[(z-v+1):z,j]=rep(":",v)};if(i<r){if(v>0)q[(z-v+1):z,j]=rep(".",v)}};if(i!=1&sum(d)>0)q=rbind(rep("|",c),q);Q=rbind(Q,q)};for(i in 1:nrow(Q))cat(Q[i,],sep="",fill=T)}

Ungolfed

# Some test data
test <- c(201, 0, 100, 222, 53)

# Define function
quipu <- function (x) {

    # Create matrix with a row for each digit and a column for each number
    r=nchar(max(x));c=length(x);m <- matrix(0,r,c)
    for(i in 1:c) {
        t=as.numeric(strsplit(as.character(x[i]),"")[[1]])
        m[(r+1-length(t)):r,i]=t
    }

    # Loop through each row (digit) starting at the top of the quipu
    Q=c() # Empty matrix to store quipu 
    for(i in 1:r){

        d=m[i,]
        z=ifelse(max(d)>0,max(d),1)
        q=matrix("|",z,c)

        # Loop through each column (number in the vector) starting at the leftmost quipu
        for(j in 1:c){

            # The digit
            v=m[i,j]

            # If it is the last segment of the quipu
            if(i==r){
                if(v==1){q[z,j]=8} # If unit digit =1
                if(v>1){q[(z-v+1):z,j]=rep(":",v)} # If unit digit >1               
            }

            # If it is not the last segment of the quipu
            if(i<r){
                if(v>0){q[(z-v+1):z,j]=rep(".",v)} # If non-unit digit >0   
            }
        }

        # Add segment to Q
        if(i!=1 & sum(d)>0){q=rbind(rep("|",c),q)}
        Q=rbind(Q,q)    
    }

    # Print quipu
    for(i in 1:nrow(Q)) {cat(Q[i,], sep="", fill=T)}
}

# Test
quipu(test)
Langsame Loris
quelle
Benötigen Sie if(v>0)in Ihrer if(i<r)Klausel? Akzeptiert R einen Bereich wie z+1:zwann v==0? Wenn das q[z+1:z,j]überhaupt nicht betroffen wäre, würde ich denken. Hat R auch eineelse Schlüsselwort und eine Art else ifSchlüsselwort? In diesem Fall könnten Sie einige dieser Bedingungen erfüllen.
Sherlock9
if(v>0)wird benötigt, weil wenn v=0der Index außerhalb der Grenzen liegt (dh versucht, Zeile nrow + 1 zu erhalten). R hat else, und ich habe Ihren Vorschlag tatsächlich ausprobiert und elsewo möglich verwendet, aber es stellte sich heraus, dass es die gleiche Anzahl von Bytes ist.
Slow Loris