かなりローマ三位一体ではない


23

整数n≥0を指定する139ABCDE…と、数字と1文字の区切り文字を使用して、非位置ベース3表記で出力します。すべての数字は3の連続した累乗であり、セパレーターの左側の数字は無効になります(例: A931 | B →81-(1 + 3 + 9 + 27)→ 41)。数字は1回しか表示されません。

厳密に、数字の値は次のとおりです。

  • 数字が1、3、または9の場合の値
  • 数字が27の場合 A
  • B..の直前の数字の3倍の値Z

出力はsum(の右側|の桁の値|)-sum(の左側の桁の値)== inputを満たす必要があります

input     output
----------------
0         |
1         |1
7         3|91
730       |D1
9999      FEDC|GA9

別の非スペース文字をセパレータとして使用できます。また、セパレータを持たないこともできます。この場合、最大桁が正のシーケンスを開始します。2 32 -1(PMIGDCBA9|RQNLH3)を超えるものを処理する必要はありません。

完全なプログラムまたは機能を記述でき、通常のチャネルのいずれかで入出力を提供できます。

これはなので、答えが短いほど良いです!


2
(関連することは、重複を意味するのではなく、落ち着く)
リーキー修道女

8
ここで何が尋ねられているのかわからないのは私だけですか?
シャギー

3
@Shaggyは、3のべき乗とその負の和として入力を表します。aの左側にマイナス|、右側にプラスを置きます。
マーティンエンダー

2
@KevinCruijssen「いいえ、注文は無料です。」-OP
user202729

3
@ user202729ああ、そのコメントを逃しました。ありがとう。ルールはコメントではなく、挑戦に編集しているときに何が起こるかの..(それFrownyFrog:?いずれかの区切り文字のいずれかの側の順序は結構です、あなたは挑戦にそのルールを追加することができます)
ケビンCruijssen

回答:


5

Java 10、120 113 112 109 107 102バイト

n->{var r="|";for(char c=49;n++>0;c=(char)(c+=c>64?1:c*4%22%9),n/=3)r=n%3<1?c+r:n%3>1?r+c:r;return r;}

@ArnauldのJavaScript(ES6)回答のトリックの一部を使用して-3バイトに
変更しi=0、およびi++<1?49:i<3?51:i<4?57:i+61に変更i=4++i>9?i+55:i>8?57:++i+43ます。
取り除くことで、@ Arnauldに直接感謝しますi

出力の順序:最高から最低、|区切り文字、最低から最高。

説明:

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

n->{              // Method with integer parameter and String return-type
  var r="|";      //  Result-String, starting at the delimiter "|"
  for(char c=49;  //  Character, starting at '1'
      n++>0       //  Loop as long as `n` is larger than 0
                  //  Increasing it by 1 with `n++` at the start of every iteration
      ;           //    After every iteration:
       c=(char)(  //     Change character `c` to:
          c+=c>64?//      If the current `c` is an uppercase letter:
              1   //       Simpy go to the next letter using `c+1`
             :    //      Else:
              c*4%22%9),
                  //       Change '1' to '3', '3' to '9', or '9' to 'A' 
       n/=3)      //     Integer-divide `n` by 3
     r=           //     Change the result to:
       n%3<1?     //      If `n` modulo-3 is 0:
        c+r       //       Prepend the character to the result
       :n%3>1?    //      Else-if `n` modulo-3 is 2:
        r+c       //       Append the character to the result
       :          //      Else:
        r;        //       Leave `r` unchanged
   return r;}     //  Return the result-String

1
私はこの作品を考える:103バイト
アルノー

@Arnauldいいね!そしてr、ループ本体に入れることでさらに-1バイト。ありがとう!
ケビンCruijssen

@Arnauld好奇心から、ブルートフォーサーは、これらの最後の2つのマジックナンバーに使用したように見えます(まだ使用iしていたときと、再使用したときc)。
ケビンクルーッセン

1
私はすでにそれを捨てました...:-/しかしここに最後のものがあります。(非常に非効率的ですが、このような小さな値でも問題ありません。)
アーナルド

(また、コードにp=1含ま*1れているかどうかを実際にテストする必要があります-その場合、より良い式につながるわけではありませんが。)
Arnauld


5

JavaScript(ES6)、82 80 79バイト

小文字で出力しますが、うまくいけばうまくいきます。

f=(n,s=(k=4,'|'),c=++k>8?k.toString(36):++k-5)=>n?f(++n/3|0,[c+s,s,s+c][n%3]):s

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

Leaky "Ninja Master" Nunの答えに似ており、xnorの答えにも基づいています

数字変換

k = 4から始めます。一方で、kは以下である9、我々は、各繰り返しで二回、それをインクリメントし、減算5。その後、1回だけインクリメントしてbase-36に変換します。

  k  | ++k > 8       | k.toString(36) | ++k - 5  | result
-----+---------------+----------------+----------+--------
  4  | k=5  -> false |                | k=6 -> 1 | 1
  6  | k=7  -> false |                | k=8 -> 3 | 3
  8  | k=9  -> true  | '9'            |          | '9'
  9  | k=10 -> true  | 'a'            |          | 'a'
  10 | k=11 -> true  | 'b'            |          | 'b'
 ... | ...           | ...            | ...      | ...



2

スタックス30 29 バイト

£└≤☻╘pÿ╖╡A[ô%æτ⌐}►ºôßHl4⌡π%^ 

実行してデバッグする

Balanced Ternary Converterの Stax回答のポート。

説明

解凍されたバージョンを使用して説明します。

139$VA+cz{;3%+,^3/~;wY1|I@'|ay2|I@L
139$VA+c                               "139AB...Z", make a copy
        z                              Empty array to store the digits
          {         w                  Do the following until 0.
           ;3%+                           Append `b%3` to the digits
                                          Originally, `b` is the input
              ,^3/                        `b=(b+1)/3`
                  ~;                       Make a copy of `b` which is used as the condition for the loop

                     Y                 Save array of digits in `y` for later use
                      1|I              Find index of 1's
                         @             Find the characters in "139AB...Z" corresponding to those indices
                          '|           A bar
                            ay2|I@     Do the same for 2's
                                  L    Join the two strings and the bar and implicit output

1

C#.NET、103バイト

n=>{var r="|";for(var c='1';n++>0;c=(char)(c>64?c+1:c+c*4%22%9),n/=3)r=n%3<1?c+r:n%3>1?r+c:r;return r;}

私のJava 10回答の移植版。直接ポート(n->to を除くn=>)が可能だった場合、この多言語でJavaの回答を編集していたでしょう。ただし、残念ながら、C#ではc+=文字や文字を使用することc=49はできないため、この移植性の低い回答です。

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




1

J、129バイト

f=:3 :0
a=.'139',u:65+i.26
s=.'|'while.y>0 do.if.1=c=.3|y do.s=.s,{.a end.y=.<.y%3
if.c=2 do.s=.s,~{.a 
y=.1+y end.a=.}.a end.s
)

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

特にJプログラムの場合は長すぎます...

説明:

f =: 3 : 0
   a =. '139',u:65+i.26   NB. a list '139ABC...Z'
   s =. '|'               NB. initialize the list for the result  
   while. y>0 do.         NB. while the number is greater than 0
      c =. 3|y            NB. find the remainder (the number modulo 3)
      y =. <.y%3          NB. divide the number by 3 
      if. c = 1 do.       NB. if the remainder equals 1
         s =. s,{.a       NB. Append the current power of 3 to the result
      end.
      if. c = 2 do.       NB. if the remainder equals 2 
         s =. s,~{.a      NB. prepends the result with the current power of 3
         y =. 1+y         NB. and increase the number with 1
      end.
      a =. }.a            NB. next power of 3 
   end.
   s                      NB. return the result  
)

1

C 、int: 138 123バイト、long152 131バイト

作業最大入力の課題の限界が0x100000000少し奇妙に思えたので、私はこれの2つのバージョンを作成しました。1つのバージョンは32ビットの整数で動作し(明らかな理由で制限に失敗します)、もう1つのバージョンは64ビットで動作します(これは指定された制限を超え、14 8バイト余分にかかります)。

32ビットバージョン:

char b[22],*r=b;f(v,l)char*l;{v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}

64ビットバージョン:

char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}

これは、整数変数を宣言することを除いて同一ですlong(Linuxでは64ビットです)。

改変されていないlongバージョン:

char buffer[22],*result=buffer;
f(long value,char*letter){
    if(value%3>1){
        *result++=*letter,value++;
    }
    if(value){
        f(value/3,letter+1);
    }
    if(value%3){
        *result++=*letter;
    }
}
g(long value){
    f(value,"139ABCDEFGHIJKLMNOPQR");
    *result=0;
    result=buffer;
}

ご覧のとおり、これは再帰的なまともな方法で機能します。剰余が1の場合、それぞれの文字が再帰呼び出しの後に出力文字列に追加されます。余りが2の場合、出力は再帰の前に実行されます。この場合、負の数字を正しく処理するために値を1ずつ増やします。これには、剰余をゼロに変更するという追加の利点があり、value%3再帰後ifの条件として使用できます。

変換の結果はグローバルバッファに配置されます。g()ラッパーはゼロのジョブが正しく得られた文字列を終了し、リセットする必要があるresult(また、どのようにしているその開始位置へのポインタをg()「戻り」結果)。

longこのコードでバージョンをテストします。

#include <stdio.h>

char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}

void printConversion(long value) {
    g(value);
    printf("%ld: %s\n", value, r);
}

int main() {
    for(long i = 0; i <= 40; i++) {
        printConversion(i);
    }
    printConversion(0x7fffffff);
    printConversion(0xffffffffu);
    printConversion(0x100000000);
}

さらに可能ですが、破壊的なゴルフ:

  • -4バイト:でリセットされたポインターを削除して、関数をワンショットにしg()ます。

  • -5バイト:呼び出し元に文字列の終了を実行させ、で終了せずに文字列を返し、で文字列の終わりを返しbufferますresult


1

、36バイト

NθF³⊞υ⟦⟧F⁺139α«⊞§υθι≔÷⊕θ³θ»F²«×|ι↑⊟υ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

Nθ

値を入力します。

F³⊞υ⟦⟧

3つの空のリストを事前定義された空のリストにプッシュします。

F⁺139α«

文字139と大文字のアルファベットをループします。

⊞§υθι

リストのリストに値を周期的にインデックス付けし、現在の文字をプッシュします。

≔÷⊕θ³θ»

値を3で除算しますが、最初に1を加算して丸めます。

F²«×|ι

2回ループします。2回目はを印刷し|ます。

↑⊟υ

各ループでは、リストから最後のエントリをポップします。1回目は2(のバランスの取れた3進数に対応する)の残りを持つエントリを提供-1し、2回目はのバランスのとれた3進数に対応するエントリを提供します1。結果の配列は通常垂直に印刷されますが、印刷方向を上に回転させるとキャンセルされます。



0

Perl 5の92の 89バイト

javaおよびpythonの回答に触発されました。

sub n{($n,$r,$c,@a)=(@_,'|',1,3,9,'A'..'Z');$n?n(int++$n/3,($c.$r,$r,$r.$c)[$n%3],@a):$r}

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

いくつかの空白がある場合:

sub n {
  ($n, $r, $c, @_) = (@_, "|", 1, 3, 9, 'A' .. 'Z');
  $n ? n( int++$n/3, ($c.$r, $r, $r.$c)[$n%3], @_)
     : $r
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.