指数をASCIIアートに変換する


28

仕事

あなたの仕事は、このような文字列を変換することです:

abc^d+ef^g + hijk^l - M^NO^P (Ag^+)

このような文字列へ:

   d   g       l    N P    +
abc +ef  + hijk  - M O  (Ag )

これはabc d + ef g + hijk l -M N O P(Ag +)の近似値です

つまり、キャレットのすぐ隣の文字を上の行に移動します。キャレット1つにつき1文字です。

スペック

  • 出力で余分な末尾の空白を使用できます。
  • チェーンされたキャレットm^n^oは入力として提供されません。
  • キャレットの直後にスペースまたは別のキャレットが続くことはありません。
  • キャレットの直前にはスペースが付きません。
  • すべてのキャレットの前には少なくとも1つの文字があり、その後に少なくとも1つの文字があります。
  • 入力文字列には、印刷可能なASCII文字のみが含まれます(U + 0020-U + 007E)
  • 2行の出力の代わりに、2つの文字列の配列を出力できます。

正規表現を話す人へ:入力文字列はこの正規表現と一致します:

/^(?!.*(\^.\^|\^\^|\^ | \^))(?!\^)[ -~]*(?<!\^)$/

リーダーボード


2
@TimmyD「入力文字列には印刷可能なASCII文字のみが含まれます(U + 0020-U + 007E)」
Nun

3
指数で停止するのはなぜですか?H_2Oを処理するものが欲しい!
ニール

1
@Neilその後、独自の課題を作成し、その課題の複製としてこの課題を終了することがあります。:)
リーキー修道女

1
あなたの例に基づいて、それらは必ずしも指数ではなく、指数であると言います
ルイス・メンド

4
正規表現を話す人は、表現が厳しく制限されている非常に規則的な国から来ています。死の主な原因は壊滅的な後戻りです。
デビッドコンラッド

回答:


19

V15 14バイト

ÄÒ +òf^xxé kPj

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

かなり簡単なソリューション。の完璧な Vのための挑戦!

説明:

Ä                "Duplicate this current line
 Ò               "Replace this line with spaces
   +             "Move to the beginning of the next line
    ò         ò  "Recursively (The second ò is implicit):
     f^          "  Find a caret
       xx        "  Delete two characters. The second will be saved into the main register
         é       "  Insert a space
           k     "  Move up
            P    "  Paste from the main register
             j   "  Move down

便利なことに、再帰の仕組みに基づいて、これはキャレットごとに1回実行されます。


2
vimはこの課題に最適な言語です。+1
ダウンゴート

18

チェダー、77 72 67バイト

l->l.chars.vfuse.replace("^\n"," ").lines.map(j->"%-2s"%j).turn(3)

正規表現なし!

この答えはチェダーの能力の素晴らしいデモンストレーションであるため、大好きです。主にConorによって追加された置換機能に感謝します。devへのPRは行われなかったため、replace関数はこのブランチにのみ存在します(更新:PRを作成し、現在インストールできる最新のベータブランチにありますnpm install -g cheddar-lang

私はゴルフをする方法を見つけましたが、残念ながら見落としの結果、アイテムの長さが同じでない場合にこれが起こります:

["   denifednud   denifednug       denifednul    denifednuN denifednuP    denifednu+ ", "abcdenifednu +efdenifednu  + hijkdenifednu  - Mdenifednu Odenifednu  (Agdenifednu )"]

正規表現を使用して多くのバイトを保存できましたが、実際に唯一の問題は何も正規表現関数が存在しないということです...チェダーのための正規表現をしました:/

説明

l->                    // Function take input as `l`
   l.chars             // Get array of chars in input
   .vfuse              // Join with newlines
   .replace("^\n"," ") // Replace `^\n` with a space globally
   .lines              // Get the lines (see below for more details on what this returns)
   .map(j->            // Loop through each "line" `j` is arg
       "%-2s"          // C-like printf format.
                       // think of as: padRight(j, " ", 2)
                       // see below for more details
        % j            // Pass j as the string to insert
   ).turn(3)           // Turn the string 270 degrees (see below)
   .vfuse              // Vertically fuse to get result (this is not needed as we can output an array of the lines)

理解を深めるため。これは何の.linesために戻ります1^2

["1", " 2"]

でこれ.turnを回転させます:

1
 2

に:

 2
1

より明確にする別の例:

1
 2
2
 2

になる:

 2 2
1 2

なぜフォーマットするのですか?

%-2sやっていることは非常に簡単です。%「フォーマット」を開始すること、またはこの時点でこの文字列に変数を挿入することを指定します。-文字列を右詰めすることを意味し2、最大長です。デフォルトでは、スペースが埋め込まれます。s文字列であると指定するだけです。それが何をするかを見るには:

"%-2s" % "a"  == "a "
"%-2s" % " a" == " a"

2
:DIは常にチェダーを支持します。
DJMcMayhem

@DrGreenEg​​gsandIronMan:Dありがとう
-Downgoat

1
チェダーにはturn文字列のメソッドがありますか?
TuxCrafting

6
-1この言語の名前は常に私を空腹にします。
反時計回りに

@TùxCräftîñgは2D配列専用です。そのため、行を取得するために.linesを使用しました。
ダウンゴート

10

Perl、21 + 1 = 22バイト

say'';s/\^(.)/♥[A\1↓/

-pフラグを指定して実行します。生のESCバイト(0x1b)と垂直タブ(0x0b)に置き換えます。

垂直タブはMartin Enderのアイデアです。2バイト節約しました!ありがとう。


指数が最後のコンソールプロンプトと重ならないように、カーソルを最初の行に移動する必要はありませんか?
マーティンエンダー

確かではありませんでした。私は必要なだけのスペースがあると仮定しましたが、それは少し面倒です。(一般的に、この種の問題を解決するためにカーソル移動を使用することをあまり誇りに思っていませんが、それが最初に思い浮かんだことです...)
リン

2
私はそれは素晴らしい解決策だと思いますが、結果は意図したとおりに文字列を印刷することと視覚的に見分けがつかないはずです。
マーティンエンダー

1
なんて素敵な解決策
トーマスウェラー

7

JavaScript(ES6)、56 55バイト

s=>[/.(\^(.))?/g,/\^.(())/g].map(r=>s.replace(r,' $2'))

もちろん救助に正規表現。最初の文字は、キャレットが見つからない限り、すべての文字をスペースに置き換えます。キャレットが見つからない場合は、キャレットを削除し、その後の文字を保持します。(これらの文字は存在することが保証されています。)2番目は、各キャレットとそれに続く文字をスペースで置き換える明らかな文字です。

編集:2番目の置換のために置換文字列を再利用する方法を考案した@Lynnのおかげで1バイト保存され、置換を正規表現の配列にマッピングできます。


2
s=>[/.(\^(.))?/g,/\^.(())/g].map(r=>s.replace(r,' $2'))短いように見えます。
リン

@Lynnそれは本当にunningなスタントです!
ニール

7

Python 3、157 101 98 85 83 74バイト

このソリューションは、前のキャラクターが ^、それに基づいて1行目または2行目に出力するかどうかを決定します。

の配列として出力し['firstline', 'secondline']ます。

a=['']*2
l=0
for c in input():x=c=='^';a[l]+=c*x;a[~l]+=' '*x;l=x
print(a)

@LeakyNunのおかげで13 15バイト節約されました!

@Joffanのおかげで7バイト節約されました!


1
ニース有限状態オートマトン。
リーキー修道女

それが持っている方が良いだろうa=['','']とCONCATENATE ' 'c直接にa[l]a[~l]
ジョファン

6

Python 2、73バイト

l=['']*2;p=1
for c in input():b=c!='^';l[p]+=c*b;l[~p]+=' '*b;p=b
print l

正規表現なし。前の文字がであったかどうかを記憶し、それに^基づいて現在の文字を上部または下部の行に配置し、もう一方の行にスペースを配置します。


4

Pyth、17バイト

CcsmX~Z1j;d;cQ\^2

             Q      input string
            c \^    split on '^'
   m                map for sections d:
    X      ;          insert a space at index:
     ~Z1                the old value of Z (initially 0), before setting Z to 1
                      into:
        j;d             the section joined on spaces
  s                 concatenate
 c              2   chop into groups of 2
C                   transpose

2つの文字列の配列を返します。(j改行で参加することをお勧めします。)

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


1
あなたの姓がどのように発音されるのか疑問に思うことを止めることはできません。:D
リン

4

MATL、18バイト

94=t1YSt~&vG*cw~Z)

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

94=    % Take input implicitly. Create logical array of the same size that contains
       % true for carets, false otherwise
t      % Push a copy of this array
1YS    % Circularly shift 1 unit to the right. This gives an array that contains true
       % for the elements right after a caret (superindices), and false for the rest 
t~     % Push a copy and negate
&v     % Concatenate vertically. This gives a 2D, 2-row array
G*     % Push the input again, multiply with broadcast. This gives a 2D array in
       % which the first row contains the superindices (characters after a caret)
       % and 0 for the rest; and the second row contains the non-superindices and
       % 0 for the superindices
c      % Convert to char
w      % Swap. Brings to top the array containing true for carets and false otherwise
~      % Negate
Z)     % Use as logical index to remove rows that contain carets. Display implicitly

4

Ruby、47 + 1(-nフラグ)= 48バイト

puts$_.gsub(/\^(.)|./){$1||" "},gsub(/\^./," ")

次のように実行します。 ruby -ne 'puts$_.gsub(/\^(.)|./){$1||" "},gsub(/\^./," ")'


の代わりに$_=$_.gsub(/\^(.)|./){$1||" "}+gsub(/\^./," ")とを使用して1バイト節約できると思います。-p-n
ドムヘイスティングス

1
@DomHastingsは、それが機能するかどうかに関係なく、コードに改行がないようで、追加+$/することはバイトを節約しないことを意味します。引数の間putsに改行があると、自動的に改行,が挿入されます。
値のインク

ああ...私は使用してテストしましたruby -p ... <<< 'input'が、同意します、それが改行を欠いているなら、それは良くありません!実際には、以前のテストで改行が追加されていたかもしれません...それは働いていたので確認できません!
ドムヘイスティングス

@DomHastingsもう一度見てみると、getsほとんどの場合、末尾の改行が含まれているためだと思いますが、末尾の改行を含まないファイルをパイプすると、表示されず、出力が間違っています。ruby -p ... inputfileRuby getsはコマンドライン引数の場合、ファイルにリダイレクトするため、コードをテストします。
バリューインク

わかった、完璧に理にかなっている。ファイル内の末尾の改行も問題を解決すると思います。私は決して熟練したRubyistではないので、今日それについてもう少し学んだように感じます。ありがとう!
ドムヘイスティングス

3

Python(2)、76 68 67バイト

@LeakyNunのおかげで-5バイト

@ KevinLau-notKennyのおかげで-3バイト

-1バイト、@ ValueInkのおかげ

@DrGreenEg​​gsandIronManのおかげで-0バイト

import re
lambda i,s=re.sub:[s("(?<!\^).\^?"," ",i),s("\^."," ",i)]

この匿名のLambda関数は、入力文字列を唯一の引数として受け取り、改行で区切られた2つの出力行を返します。呼び出すには、名前の前に「f =」と書いて名前を付けます。

かなり簡単な正規表現:最初の部分は、次の文字をスペースに置き換えます。任意の文字とニンジンキャレットまたは文字のみ。ただし、キャレットがない場合のみ。2番目の部分は、文字列内のキャレットとその後の文字をスペースで置き換えます。


@LeakyNun:何らかの理由で、ライブラリをインポートする場合も1.が成り立つかどうか疑問に思いました。あなたのコメントを見たとき、今この質問に2.をコピーしていました。あなたとケビンに感謝します!
カールカストール

from re import*
DJMcMayhem

@DrGreenEg​​gsandIronManこれは、まったく同じバイト数を使用しているようです。(上記参照)
カールカストール

古いインポート文を保持しlambda i,s=re.sub:[s("(?<!\^).\^?"," ",i),s("\^."," ",i)]、-1バイトで処理します
値インク


2

網膜、16バイト

S`^
\^(.)
♥[A$1↓

Martin Enderが指摘したPerlの回答の移植版。生のESCバイトに置き換えます(0x1b)と垂直タブ(0x0b)にます。


2

shell + TeX + catdvi、 51 43バイト

tex '\empty$'$1'$\end'>n;catdvi *i|head -n2

を使用texしていくつかの美しい数学を組版しcatdvi、テキスト表現を作成します。headコマンドは、存在しないジャンク(ページ番号、末尾の改行)を削除します。

編集:なぜ/dev/null副作用を無視して単一の文字ファイルに書き込むことができるときに、長くて適切なものをリダイレクトするのですか?


入力: abc^d+ef^g + hijk^l - M^NO^P (Ag^+)

TeX出力(方程式にトリミング): "Beautiful" mathematics! 最終出力:

   d   g     l  N P   +
abc +ef +hijk -M O (Ag )

前提条件:空のディレクトリ(または「i」で終わる名前のないディレクトリ)で開始します。入力は、シェルスクリプトへの単一の引数です。入力は空の文字列ではありません。

これが特にルールの乱用かどうか教えてくださいcatdvi


2

Haskell、74 56 55バイト

g('^':c:r)=(c,' '):g r
g(c:r)=(' ',c):g r
g x=x
unzip.g

文字列のペアを返します。使用例:unzip.g $ "abc^d+e:qf^g + hijk^l - M^NO^P: (Ag^+)"->(" d g l N P + ","abc +e:qf + hijk - M O : (Ag )")

gペアのリストを作成します。最初の要素は上の行のcharで、2番目の要素は下の行のcharです。unzipリストのペアに変換します。

編集:@xnor提案 unzip 18バイトを節約するた。@Laikoniは、保存するバイトをもう1つ見つけました。ありがとう!


できますかj=unzip.g
xnor

@xnor:ああ、それを自分で見ないなんて馬鹿だ!どうもありがとう!
nimi

で置き換えg[]=[]g x=x1バイト節約できます。
ライコニ

@ライコニ:よくわかりました!ありがとう!
-nimi

1

Perl、35バイト

34バイトのコード+ 1 -p

$_=s/\^(.)|./$1||$"/ger.s/\^./ /gr

使用法

perl -pe '$_=s/\^(.)|./$1||$"/ger.s/\^./ /gr' <<< 'abc^d+ef^g + hijk^l - M^NO^P (Ag^+)'
   d   g       l    N P    + 
abc +ef  + hijk  - M O  (Ag )

注:これは、後で調査したValue Inkの答えとまったく同じです。Rubyソリューションに実際には追加されないため、必要に応じて削除します。


1

Java 8ラムダ、132 128 112文字

i->{String[]r={"",""};for(char j=0,c;j<i.length();j++){c=i[j];r[0]+=c==94?i[++j]:32;r[1]+=c==94?32:c;}return r;}

改変されていないバージョンは次のようになります。

public class Q86647 {

    static String[] printExponents(char[] input) {
        String[] result = {"",""};
        for (char j = 0, c; j < input.length(); j++) {
            c = input[j];
            result[0] += c == 94 ? input[++j] : 32;
            result[1] += c == 94 ? 32 : c;
        }
        return result;
    }
}

配列として出力します。キャレットがあるかどうかを確認し、キャレットがある場合は次の文字が上の行に配置され、そうでない場合はスペースが挿入されます。


更新

4文字を節約するために、文字をASCII値に置き換えました。

入力としてchar配列を使用することを指摘してくれた@LeakyLunに感謝します。

に切り替えてさらに文字を保存intcharてくれた@KevinCruijssenにも感謝します。


入力char[]して使用for(char c:i)して、バイト数を減らすことができるかどうかを確認できます。
リーキー修道女

入力として:i->{String[]r={"",""};for(char j=0,c;j<i.length;j++){c=i[j];r[0]+=c==94?i[++j]:32;r[1]+=c==94?32:c;}return r;}with "abc^d+ef^g + hijk^l - M^NO^P (Ag^+)".toCharArray()を使用すると、110バイトまで少しゴルフすることができます。(これらの変更の
イデオン

1

ココナッツ122 114 96バイト

編集:リーキー修道女の助けを借りて8 26バイトダウン。

def e(s,l)=''==l and s or"^"==l[0]and l[1]+e(s+' ',l[2:])or' '+e(s+l[0],l[1:])
f=print..e$('\n')

だから私は今日のpythonを学んだとして三項条件演算子を持っている、あるいは実際にそれらの2に:<true_expr> if <condition> else <false_expr><condition> and <true_expr> or <false_expr>して最後のものは1つの文字少ないときます。
python準拠バージョンをイデオン化できます。


最初の試み:

def e(s,l):
 case l:
  match['^',c]+r:return c+e(s+' ',r)
  match[c]+r:return' '+e(s+c,r)
 else:return s
f=print..e$('\n')

f("abc^d+ef^g + hijk^l - M^NO^P (Ag^+)")プリントで呼び出す

   d   g       l    N P    +
abc +ef  + hijk  - M O  (Ag )

まだココナッツでゴルフを試した人はいますか?..上記で使用したパターンマッチングや関数連結(with )など、より機能的なプログラミングの概念でpythonを強化します。これがココナッツでの私の最初の試みなので、どんなヒントでも大歓迎です。

有効なpythonコードも有効なココナッツであり、短いPython回答が投稿されているため、これは間違いなく短縮できますが、純粋に機能的なソリューションを見つけようとしました。


三項演算子(x and y or z)を使用してcase
リーキー修道女

あなたも使用することができますs[0]=="^"代わりにmatch['^',c]+r in l
漏れ修道女

私は交換しないで@LeakyNun match['^',c]+rs[0]=="^"、その後、cそしてrもはや拘束されています。これはどのように役立ちますか?
ライコニ

を使用s[1]してcs[2:]を置換および置換できますr
リーキー修道女

その後、3進法を使用できます。
リーキー修道女

0

Dyalog APL、34バイト

{(0 1=⊂b/¯1⌽b){⍺\⍺/⍵}¨⊂⍵/⍨b←⍵≠'∧'}

2行の2要素ベクトルを返します

サンプルの実行(前にある上向き矢印は、人間が使用できるように2要素ベクトルをフォーマットすることです):

      ↑{(0 1=⊂b/¯1⌽b){⍺\⍺/⍵}¨⊂⍵/⍨b←⍵≠'∧'}'abc∧d+ef∧g + hijk∧l - M∧NO∧P (Ag∧+)'
   d   g       l    N P    + 
abc +ef  + hijk  - M O  (Ag )

コードが何もしないという私の質問についてのあなたのコメントに:はい、あなたが置いたコードは重要です。
-haykam

0

PowerShell v2 +、88 83バイト

-join([char[]]$args[0]|%{if($c){$_;$b+=' '}elseif($_-94){$b+=$_;' '}$c=$_-eq94});$b

他のものより少し長いですが、PowerShellの魔法と少し異なるロジックを紹介しています。

基本的にPythonの答えと同じ概念です。入力文字を文字ごとに繰り返し、前の文字がキャレット($c)であったかどうかを記憶し、現在の文字を適切な場所に配置します。ただし、出力先を決定するためのロジックと方法は少し異なり、タプルまたは個別の変数なしで処理されます-前の文字がキャレットであるかどうかをテストし、そうであれば文字をパイプラインに出力し、スペースを連結します$b。そうでない場合は、現在の文字がキャレットであるかどうかをチェックし、キャレットelseif($_-94)でない限り、現在の文字を$bパイプラインに連結して、スペースをパイプラインに出力します。最後に、現在のキャラクターが次のラウンドのキャレットかどうかを設定します。

これらの文字をパイプラインから括弧にまとめ、カプセル化-joinして文字列に変換し、それをそのまま残します$bてからパイプラインにます。最後の出力は、間に改行が含まれて暗黙的に行われます。

比較のために、ここでは、@ XNORの直接ポートのPythonの答えはで、85バイト

$a=,''*2;[char[]]$args[($l=0)]|%{$a[!$l]+="$_"*($c=$_-ne94);$a[$l]+=' '*$c;$l=!$c};$a

0

Gema、42 41文字

\^?=?@set{s;$s }
?=\ @append{s;?}
\Z=\n$s

Gemaは入力をストリームとして処理するため、1回のパスで解決する必要があります。最初の行は処理済みとしてすぐに書き込まれ、2番目の行は変数$ sに収集され、最後に出力されます。

サンプル実行:

bash-4.3$ gema '\^?=?@set{s;$s };?=\ @append{s;?};\Z=\n$s' <<< 'abc^d+ef^g + hijk^l - M^NO^P (Ag^+)'
   d   g       l    N P    +  
abc +ef  + hijk  - M O  (Ag )

0

シナモンガム、21バイト

0000000: 5306 6533 bd92 d1db 8899 8381 a2f8 8f8c  S.e3............
0000010: 1230 249e a1                             .0$..

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

説明

私は正規表現のゴルファーではないので、おそらくこれを行うためのより良い方法があります。

文字列は次のように解凍されます。

S(?<!\^)[^^]& &\^&`S\^.& 

(末尾のスペースに注意してください)

最初のSステージは入力を受け取り、ネガティブな後読みを使用して、キャレットが先行するキャレット以外のすべての文字をスペースで置き換え、すべてのキャレットを削除します。次に、変更された入力文字列を直ちに改行で出力し、そのSステージを削除します。STDINは使い果たされており、前のステージでは入力が提供されていなかったため、次のSステージは再びSTDINの最後の行を受け取り、すべてのキャレットとそれに続くスペースのある文字列を置き換えて出力します。

Perl擬似コードの場合:

$first_stage_sub_1 = ($input =~ s/(?<!\^)[^^]/ /gr);
$first_stage_sub_2 = ($first_stage_sub_1 =~ s/\^//gr);
print $first_stage_sub_2, "\n";

$second_stage_sub = ($input =~ s/\^./ /gr);
print $second_stage_sub, "\n";

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