Quipuのカウント:新世界のベース10


41

Quipusは、プレコロンビア時代にインカがコード上の結び目のベース10位置システムに数字を記録するために使用する古代のデバイスで、次のように機能します。

ノットの各クラスターは数字であり、ノットには主に3つのタイプがあります。単純なオーバーハンドノットです。「長い結び目」、1つ以上の追加のターンを持つオーバーハンドノットで構成されます。と8の字結び目。

  • 10の累乗は、文字列に沿った位置によって示され、この位置は連続するストランド間で整列します。
  • 10以上の累乗の位置の数字は、単純なノットのクラスターで表されます(たとえば、40は「10」の位置にある4つの単純なノットです)。
  • 「1」の位置の数字は、長い結び目で表されます(たとえば、4は4ターンの結び目です)。ノットの結び方により、数字1はこのように表示することはできず、この位置では8の字のノットで表されます。
  • ゼロは、適切な位置に結び目がないことで表されます。

詳細

この課題については、QUIPUの各鎖は表し、単一の番号(Wikipediaの記事の状態として、あなたは、しかしをすることができ、我々はてはならない、この挑戦に、一方の鎖に多くの数を表します)。

結び目

各ノットは、単一のASCII文字で表されます。

  • . 単純な結び目を表します
  • : 長い結び目の1回転を表します
  • 8 8の字結び目を表します
  • | ノットがないことと、数字の間の区切り文字を表します。

Quipusの構築

Quipuはこれらのルールに従って構築されます。

  1. ストランドは、位置の降順で上から下に走ります(たとえば、ユニットの数字はストランドの下端になります)。ストランドに沿った数字は、文字(|)で区切られます。
  2. 数字が表す10の累乗は、数字システムの数字のインデックスを使用して数字の10の累乗が計算されるのと同じ方法で、ストランドに沿った位置によって決まります。すなわち、242十の位および4ユニット場所では、2つのノット、デリミタ(によって表される|当時)は、4つのノット。
  3. 同じ位置の数字は、ストランドの下部に向かって整列します。ある位置の1つの数字が同じ位置にある他の数字の他の数字よりも結び目が少ない場合、それらの結び目がないことは(|)で表されます。
  4. 連続するシンプルなノット(.)は、その位置の値を表します。
  5. すべての数字は、少なくとも1文字で表されます。quipu内のすべての数値で数字の値が0の場合、ノット(|)がないことで表されます。
  6. ユニットの場所は特別に扱われます。単位の場所にあるものは、8の字結び目(8)で表されます。単位の場所の2つ以上の値は、連続する長いノット(:)で表されます。
  7. quipuのすべての数値の単位桁が0の場合、ノットがないことは出力されませんが、10桁の末尾の区切り文字は保持されます。
  8. 単位の数字の後に区切り文字はありません。

ルール

  • 入力は、デフォルトの入力メソッドのいずれかを介して受信される可能性のある非負整数の空でないリストで構成されます。あなたはこれらの整数がすべて未満であるかに等しいと仮定してよいです21474836472^31-1。テストケースはスペースで区切られていますが、入力形式では、カンマ区切り、改行区切り、配列など、言語に適した方法で入力を分離できます。
  • 出力は、上記のルールに従って構築された単一のQuipuで構成されます。出力は、デフォルトの出力方法のいずれかを介して指定できます
  • コードはプログラムまたは関数である必要がありますが、名前付き関数である必要はありません。
  • 結び目は結び付けるのに時間がかかるので、時間を節約するために、コードはできるだけ短くします。

いつものように、問題が不明な場合はお知らせください。幸運と良いゴルフ!

入力:

5 3 1 0

出力:

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

入力:

50 30 10 0

出力:

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

入力:

330

出力:

.
.
.
|
.
.
.
|

入力:

204 1

出力:

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

入力:

201 0 100 222

出力:

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

入力:

1073741823 2147483647

出力:

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

入力:

0

出力:

|

より長いテストケース

参考文献


回答:


3

Pyth、64バイト

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

オンラインでお試しください!

使い方

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

これは、1つの問題を除いて優れた答えです。最終的な結び目は、必ずしも8字結び目ではありません8。実際、8最後の桁が1である場合にのみノットになります(ルール6を参照)。あなたはすべての最終的な結び目を変換していますが、それは仕様と一致しません。また、Try It Online!リンクは明らかに、ここに掲載されているものとは別のコードを持っている
Sherlock9

22

読み取り不可3183 3001バイト

これは、クリスマスのお祝いの合間に、オン、オフの作業をするための楽しい挑戦でした。投稿していただきありがとうございます!仕様には多くのif条件を必要とする例外と特別なケースがいっぱいであるため、これをゴルフで楽しむことは興味深いものでした。また、今回は10進数に変換したり、10進数から変換したりする必要はありませんでしたが、各数値の最大桁数と各桁の最大値を決定するための「最大」ソート関数必要でした。

これの最初のバージョンは4844バイトでした。これは、私がどれだけゴルフをしたかを知るためのものです。

プログラムは、入力を整数のコンマ区切りリストとして予期します。スペースや改行なし。これらを使用すると、未定義の動作が発生します。

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

説明

特定の入力を処理する方法を示すことで、プログラムがどのように機能するかを説明します202,100,1

最初に、後で必要になるいくつかの値を作成します。ほとんどの場合、出力する文字のASCIIコードです。

ここに画像の説明を入力してください

あなたが見る、わかるように'8'して'.'、すでに利用可能です。'|'ただし、実際は14ではなく124です。whileループを使用して、スロット#1の一時値を2倍して124を取得します(whileループは56-1 = 55で実行されるため、14 + 55×2です)。繰り返し)。124のような大きな整数リテラルは本当に長いため、これによりバイト数が節約されます。次の図では、プログラムが使用するすべての変数の場所を示しています。

ここに画像の説明を入力してください

次に、すべての文字を入力し、セル#12からテープに保存します(pはこのための実行ポインターです)。同時に、最も長い数字の長さ(桁数)を知りたいです。これを達成するために、セル#-1から左に向かって単項で実行中の合計を保持します(実行ポインターとしてqを使用します)。最初の入力番号(202)の後、テープは次のようになります。

ここに画像の説明を入力してください

数字が4ずれていることに気付くでしょう。最初に入力したとき、それらはASCII値であるため、48で「オフ」になり、カンマは44です。各文字に対して、46をコピーします。R、次にwhileループでそれを引く(45を減算する)、その後、私たちはそれを認識するために、条件を使用できるように、我々は、カンマ(、私たちのセパレータ)が0であるので、それを行う1を追加します。'.'

また、セル#11を0のままにしていることにお気づきでしょう。最初の数字の境界を認識するために必要です。

次の文字はコンマになるため、#15に0を格納しますが、もちろん今回はqを進めません。代わりに、qを0に戻し、既に配置した1を「上書き」し始めます。

残りのすべての文字が処理された後、次のようになります。

ここに画像の説明を入力してください

ご覧のように、qで書かれた1 は、最も長い数値の長さを(単項で)示しています。

ここで、whileループを使用してqを一番左に移動し、そこに別のポインターを配置してr2を呼び出します。r2の目的は後で明らかになります。

ここに画像の説明を入力してください

この時点で、これから使用する用語を明確にします。

  • 、私はカンマで区切られた入力番号のいずれかを意味します。この例では、202、100、1です。
  • 、私は数字の特定の1で一桁を意味します。最初の数字は3桁です。
  • 場所によって、私は1の場所、10の場所、100の場所などを意味します。したがって、「現在の場所の数字」と言い、現在の場所が1の場所である場合、それらの数字は2、0、および1です注文。

さて、通常のプログラミングに戻りましょう。プログラムの残り全体は、セル#0に到達するまでqを前方に移動する大きなループです。途中の各セルは1つの場所を表し、1つの場所は右端にあり、qは最上位から始まります。この例では、数百の場所です。

我々は、細胞増加することによって進めるのq(、である点をQ *)。

ここに画像の説明を入力してください

私たちは現在、数百の場所で「ステージ2」にいます。この段階では、数百の桁の中で最大の桁が何であるかを調べます。これには同じ単項カウンティングトリックを使用しますが、今回はポインターがrと呼ばれ、ポインターr2が次の番号に進むたびにリセットする必要がある開始位置をマークします。

最初の数字から始めましょう。まず、pを11(すべての数字のハードコーディングされた開始位置)に設定します。次に、whileループを使用して数値の末尾を見つけ、そこにp2を設定して位置をマークします。同時に、q2を0に設定します。

ここに画像の説明を入力してください

q2が変数を指しているという事実に気を取られないでください。セル番号0であるという理由だけでセル#0を検出できるため、空白セルのパディングはありません。

次に、* pがゼロになるまでpq2を一緒にデクリメントして、現在の数を調べます。それぞれの場所で、* q2の値は何をする必要があるかを示しています。1は「何もしない」という意味なので、続けます。最終的に、セル#-3の2に遭遇します。* q2が1に等しくないたびに、q2は常にqに等しくなります。

ここに画像の説明を入力してください

すでに述べたように、ステージ2は「この場所で最大の桁を決定する」ことです。したがって、rr2に設定し、whileループを使用して* pをデクリメントし、rを左に移動してテープを1で埋め、次に別のwhileループを使用してrを右に戻し、* pを再度インクリメントして値を復元します。whileループは、使用する値よりも1回少ない反復で実行されることに注意してください。このため、書き込まれる1の数は数字の値よりも4つ多くではなく3つ多くなり、* pに戻される最終値はさらに2つ多くなります。したがって、これにより* pが実質的に2 減少します。

その後、pp2の値に設定し、それをすべて繰り返します。再度q2を0 に設定し、pを右に移動して数値の末尾を見つけ、pq2を一緒にデクリメントしてこの数値の桁を調べます。もう一度、セル#-3の2に遭遇し、* rの残りの1を書き込みます。

3番目の数値の場合、100の位がないために何もしません(したがってq2qに到達しません)が、最大桁の値の計算に影響を与えないため、それは問題ありません。

ここに画像の説明を入力してください

また、ここではラベルなしの矢印でマークしたセル*(r − 4)を1に設定します(すでに1になっている場合でも)。まだ理由をお話しするつもりはありませんが、おそらくあなたはすでに推測していますか?

次の* qの増分により、ステージ3に進みます。これは、「現在の場所のすべての桁から最大桁を減算する」ことです。前と同様に、pを11に、q2を0 にリセットしてから、前の段階で行ったようにすべての数値を調べます。この時間を除いて、* Q 3の代わりに、2度に= q2は満たしているのqpは百の位であるが、我々が使用中デクリメントへのループ* Pの左側のブロック内の1があるとして、多くの倍* R2(5この例では)rを使用して実行中のポインターとして。実際にそれをもう一度デクリメントして、最大桁が-2になるようにします。理由は後で明らかになります。

ここに画像の説明を入力してください

すべての数値を処理した後、ステージ3の終わりになりました。ここでは、2つの特異なことを実行します。

  • 最初に、* qからrブロック(プラス1)のサイズ減算しますが、r2ポインターを使用して、左側に残します。* qはこの方法で負になります。この場合、rブロックには5つの1があるため、* qは-3になります。
  • 次に、変数をゼロ以外の値に設定て、現在出力ステージに入っていることを示します。(技術的には、* qが負であるという事実はすでに出力段階を示していますが、これは確認するのが難しすぎるため、余分な変数です。)

あなたは今、我々は数字を経由しておくことを理解する(非1の値で示される現在の場所を見つける* Qがそれぞれ数以内)、およびの値に応じて何かをする* Q。私たちは、ことがわかり* qは最初の3、その後、(=計算最大桁値)2にインクリメント(この場所で、すべての桁から最大桁の値を減算)し、我々はそれを否定するために、それから減算されます。そこから、1に達するまで上昇し続け、「何もしない」ことを意味する値を復元します。その時点で、次の場所に進みます。

現在、* qが負の場合、出力しています。* qは正確に正しい値であるため、1に達する前に正しい数の文字の行を出力します。最大桁が2の場合、3行を出力する必要があります。* qの各値で何が起こるか見てみましょう:

  • * q = −2:
    • 最初の数値では、* pは-2であり、これは'.'(ドット)または':'(コロン)を出力する必要があることを示します。qを見ることでどちらを決定します:-1の場合は1の場所にあるので、a ':''8'+2 として計算)を出力し、そうでない場合はa を出力し'.'ます。
    • 2番目の数値の場合、* pは-3です。−2以外'|'の値は、(パイプ)を出力してから値をインクリメントすることを意味します。このようにして、正しい場所で-2に到達し、その数字の残りについて'.'s / ':'s を出力します。
    • いずれの場合も、数値を処理する前に変数pdを0 設定し、pd(=“ printed”)をゼロ以外の値に設定して、文字を印刷したことを示します。
    • 3番目の番号には、数百の桁がないため、処理は行われません。この場合、数値を処理した後もpdは0のままであり、aを出力する必要があることを示しています'|'(ただし、outがゼロ以外の場合は、ステージ2または3にいるためです)。
    • すべての数値を処理した後、outがゼロ以外の場合、改行を出力します。ステージ2または3で改行を出力しないように、out変数が必要なことに注意してください。
  • * q = -1:前と同じですが、最初の2つの数値の両方で * pが-2であるため、両方がaを出力します'.'(3番目の出力は'|'以前のようにaを出力します)。
  • * Q = 0:とき * qは 0で、この手段は、「私たちはものの場所にいる場合の行そうでない場合は、出力を何もしない'|'のにかかわらず、 * P」。このようにして、数字間のパディングを取得します。

次にqをインクリメントして次の場所である10の場所に移動し、そこで* qをインクリメントします。ステージ2の開始時には、テープは次のようになります。

ここに画像の説明を入力してください

次に、前と同じようにステージ2を実行します。これは、この場所のすべての数字から2を事実上減算し、最大桁を示す* r2の単項数を残します。前の単項数はそのままにして、テープを左に拡張し続けます。「クリーンアップ」するために余分なコードが必要になるだけです。完了して* qをインクリメントすると、ステージ3の開始時にテープは次のようになります。

ここに画像の説明を入力してください

実際、これは嘘です。以前、*(r − 4)を1 に設定したと言ったのを思い出してください。では、その理由を説明します。このような場合は、最大桁が実際に0であるため、この場所のすべての桁は0です。上記のラベルのない矢印で示される*(r − 4)を1に設定すると、単項数が1だけ拡張されます。ただし、この特別な場合のみ。このように、最大​​桁が1であるかのようにふりをします。これは、1行余分に出力することを意味します。

ステージ3(現在の場所のすべての桁から最大桁を引く)の後、* qを負にする追加のステップを含めて、テープは次のようになります。前回、* pブロックで最大桁が-2で表されていましたが、今回は実際はすべてゼロであるため、すべてが-3ですが、最大桁が1であるかのように見せかけています。

ここに画像の説明を入力してください

ここで、* qが1に向かって進むにつれて何が起こるかを見てみましょう。

  • とき* Q = -1、* Pの値が全てです-3、我々は出力を意味している'|'のと増分それらを。
  • とき* Q = 0、我々出力'|'なぜなら、我々は常に何をすべきかというのとき* Q = 0、にかかわらず* P

したがって、パイプの2つの行を取得します。

最後に、* qを自分の場所に移動します。これ':'は、実際の数字が1以外の場合はs を出力する必要があるが、1の場合はs を出力する必要があるため、興味深いものになり'8'ます。プログラムがどのように進行するかを見てみましょう。まず、ステージ2を開始するために* qをインクリメントします。

ここに画像の説明を入力してください

ステージ2(「最大桁値の計算」)の後、次のようにします。

ここに画像の説明を入力してください

ステージ3(「現在の場所のすべての桁から最大桁値を引く」)の後、テープは次のようになります。

ここに画像の説明を入力してください

では、* qの各反復を順番に見ていきましょう。

  • * q = −2:
    • 最初の数:すでに-2なので、aを出力します':'q = -1 '.'なのでaではなく)。
    • 2番目の数値:-4で、a '|'を出力し、増分します。
    • 3番目の数値:-3で、aを出力し'|'ます。ただし、今回は、インクリメントする代わりに、特別なケースがトリガーされます。唯一我々は最後の場所を(出力ている場合、Q = -1)、我々は(そのために二最後の行にいる* Q = -2)、及び数字は、実際には1である(* P = -3) 、その後、代わり-2にそれをインクリメントで、我々はそれを設定-1。つまり、特別な値として-1を使用して、次の反復での'8'代わりに出力する必要があることを示します':'
  • * q = −1:
    • 最初の数:すでに-2であるため、aを出力し':'ます。
    • 2番目の数値:-3で、aを出力し'|'ます。* qが-2でなくなったため、特別な条件はトリガーされません。したがって、インクリメント。
    • 3番目の数値:-1で、出力'8'
  • * q = 0:通常、'|'ここにsのパディング行を出力しますが、1の場所( q = -1)にいる特別な場合には、それをスキップします。

この後、qは0にインクリメントされ、大きなwhileループが終了します。

これで、入力のような202,100,1仕組みがわかりました。ただし、まだカバーしていない特別なケースがもう1つあります。最後の場所を処理しているときに、* pが-3の場合1、次の反復がを出力するように(-2にインクリメントする代わりに)-1に設定したことを覚えているかもしれません'8'。これが機能するのは、* pが-3 である反復があり、それをインクリメントするか、-1に設定するかを決定するためです。1 桁の数字がすべて 0または1の場合、このような反復ありません。そのような場合、1のすべての* p値は-2 から始まります。-1に設定することを決定する機会はありません-3からインクリメントするのではなく。このため、ステージ3には別の特別なケーシング条件があります(「現在の場所のすべての数字から最大の数字を引く」)。すべての桁から最大桁値を引いた後(最大桁が-1になった時点)、もう一度デクリメントしますが、実際には次のような条件があります。

私たちが見ている数字は、この場所での最大桁に等しい場合(* P = -1)、そしてこの場所は、一の位(あるQ = -1)、および最大桁が1(ある*(R + 5)非常に長い左のみ5細胞)である時、すなわち単項ブロック、0 =は、だけにして我々は去る* Pを示すために-1のみの繰り返し出力を出力しなければならないのそれ'8'。他のすべての場合では、もう一度デクリメントします。

できた 明けましておめでとうございます!

  • 編集1(3183→3001):新年あけましておめでとうございます!変数p2r2を完全に取り除きました!pは、数字の始まりと終わりを見つけ続けるために、今度は前後に競争しますが、コードの方が短いようです。私もq2を削除しようとしましたが、そのようにコードを短くすることはできませんでした。

    また、whileループの最後の値を再利用するなど、読み取り不可能な一般的なゴルフトリックを適用できる場所をいくつか見つけました。例を挙げると、

    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
    

    のような方法でそれを書くことで'""""'"""(最初に、次に2番目に)、(定数1)を保存できます

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

    もちろん、これは、whileループが少なくとも1回実行されることがわかっている場合にのみ機能しますが、実行される場合、戻り値はpdなので、ifの条件として使用できます。


「読めない」...確かにaptの名前である
アレックスA.

9
-1不十分な説明
ハットを持つ男

7

ジャバスクリプト(ES6)750 744 690 604 498 346の 245 234バイト

私はPPCGが初めてなので、これをかなり簡単だと思って試してみようと思いました。少年は私が間違っていた!私はしばらくの間、それに取り組んできました、そして、私はするべきたくさんのゴルフをしています...
提案は奨励されます!-これを理解するのは簡単なことではありませんが。

入力が数値の配列(例:)の場合にロープを出力し[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)

説明

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
)

入力:数字の配列:[4,8,15,16,23,42]
出力:

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

印象的なゴルフを+1。入力と出力の例を含めますか?
DavidC

@DavidCありがとう!そして、例が含まれています。コンソールから呼び出して、文字列を返します。:)
Aᴄʜᴇʀᴏɴғᴀɪʟ

7

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

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='')

さて、この質問には答えが必要だったので、ここで1つを提供しました。入力は、スペースで区切られた数字の文字列である必要があります"204 1"。少年、それは長いものです。ゴルフの提案(またはより良い答え)は大歓迎です。

編集:タブとスペースを混ぜて保存したバイト。

編集:数字の桁を取得する方法を変更することで多くのバイトを保存しました(数字のゼロで埋められた文字列からリストを作成し、コードの本文で数百桁、10桁などに変換します) )

編集:そして、最後の:8ループをメインのキプループに組み込むことで、さらに節約しました。なぜb=d[j*v+i]==m(d[i::v])うまくいかないのかを理解できたなら。それを考え出したところ、ソリューションのバイト数が多すぎます。(タブが4つのスペースに戻ったため、バイトカウントも低下しました。おそらく、このサイトのコードブロックの書式設定でした)

編集:私はどのようにキプスを作り直した。一度に1つのストランドを作成し、印刷用に転置します。

編集:回答をPython 3プログラムに戻し、さらにバイトを節約しました。

編集:コードのバグを発見し、数字の真ん中にゼロが正しく出力されないようにしました(204 1上記のテストケースを参照)。これを修正して、私はそれをゴルフすることに成功しました:)

編集: 10バイトを節約するために印刷を変更しました。それに、古いバイトカウントをすべて元に戻しました。

編集: 4バイトv使用の割り当てをゴルフしましたmap。功績CarpetPython私は彼らの答えからアイデアを得たとして、ここでは

編集:中間の「forループ内のforループ」を、6バイトの1つのforループに変更しました。

編集:を使用していenumerateます。使用しなくなりましたl=len(z)。三元if-elseをリスト三元に変えました。詳細は以下をご覧ください。

編集: Sp3000は、print1バイトずつ保存する3項条件の編集と編集を提案しました。

ゴルフをしていない:

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

ここにPython 3に固有のものはありますか?ない場合は、Pythonの2に変換することはかなりの数のバイトを救うことができる
Cyoce

@Cyoce Python 3固有のものはありません。Python 3を始めたのは、それが私が持っているバージョンだからです。ideoneなどでPython 2バージョンをテストします。
Sherlock9

@Maltysenこれは0、などで始まる入力では機能しません0 12 4
Sherlock9

あなたは、私がPythonのインデントパーサに応じて1つのタブ文字== 8つのスペースを信じているのPython 2のインデントにタブとスペースを交互に行うことによって、いくつかのバイトを保存することができます
Cyoce

for r in zip(*x):print(''.join(r))->print(''.join(r)for r in zip(*x))
リーキー修道女

4

C、238235バイト

コードをできるだけ短くするために、Cプリプロセッサに大きく依存しています。副作用として、それはほとんど読めなくします。

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

Ubuntu 14.04では、簡単にコードをコンパイルできますgcc quipu.c(警告は無視してください)。実行可能ファイルの実行例:

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

すべてのOPのテストケースに対してテスト済み。

未ゴルフソースコード:

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

おめでとうございます!バウンティ期間内に投稿された最短の回答として、あなたは私のバウンティ+50 repを受け取りました。素敵な答え!:)
アレックスA.

4

Mathematica 436453357352352347バイト

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)

上記

  • IntegerDigits; を使用して、各整数を数字のリストに分割します。(等しい間隔を確保するために)各番号に左にゼロを埋め込みます。現在、数字に分解されている各入力番号は、配列の行に対応しています。各列は場所の値を表します。配列が転置されます。
  • 数字をパディング付きのノットのリストに置き換えます。ユニットには、わずかに異なるパターンマッチングルーチンが使用されます。

g[Range[0, 50]]

50


Transpose@Join?であるはずですよね?
CalculatorFeline

はい。これをキャッチしてくれてありがとう。
DavidC

その直前のスペース。
CalculatorFeline

1

R- 446 444

Rソリューションはまだないので、ここに1つあります。この関数は、整数を持つベクトルを取ります。

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

非ゴルフ

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

if(v>0)あなたのif(i<r)条項に必要ですか?Rはz+1:zwhenのような範囲を受け入れv==0ますか?それq[z+1:z,j]がまったく影響を受けないなら、私は思うだろう。また、Rにはelseキーワードと何らかのelse ifキーワードがありますか?もしそうなら、これらの条件のいくつかをゴルフすることができるでしょう。
Sherlock9

if(v>0)が必要なのv=0は、インデックスが範囲外になる(つまり、行nrow + 1を取得しようとする)ためです。Rにはがありelse、実際にあなたの提案を試し、else可能な限り使用しましたが、同じバイト数であることがわかりました。
スローロリス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.