* Overwrit * labels


23

本当に密集したプロットにラベルを追加しようとしたことがある場合、ラベルが互いに重なり合って読みにくくなることがあります。同様のことを1Dで行います。

入力は(label, x-coordinate)ペアのシーケンスになり、出力は各ポイントとラベルを所定の順序で描画した結果になります。*ポイントを表すアスタリスクは、指定されたx座標に配置され、ラベルが続く必要があります。既存の文字はすべて上書きされます。

たとえば、入力が

Hello  0
World  8
Fizz   3
Buzz   5
PPCG   16
X      9

その後、次のことが起こります。

*Hello
*Hello  *World
*He*Fizz*World
*He*F*Buzzorld
*He*F*Buzzorld  *PPCG  
*He*F*Buz*Xrld  *PPCG

最後の行が出力されます。

I / Oルール

  • 入力は、任意の数のペアで構成できます。各ラベルは大文字と小文字のみで構成され、ラベルの長さは最大で127文字です。各x座標は0から127の間です。

  • 入力は、ペアが明確であり、ラベル/ x座標が入力内で交互になるように、任意の便利なリストまたは文字列形式にすることができます。たとえば、[("Hello", 0), ("World", 8) ...]またはのような形式[0 "Hello" 8 "World" ...]は問題ありません。ただし、ラベルとx座標の2つの別個のリストを想定することはできません。

  • 機能と完全なプログラムはどちらも大丈夫です。

  • ラベルで覆われていないスポットはスペースで表す必要があります。ただし、単一のオプションの末尾の改行を除いて、余分な先頭または末尾の空白はない場合があります。

入力:

OneLabel   10

出力:

          *OneLabel

入力:

Heathrow   0
Edinburgh  2
London     4
Liverpool  6
Oxford     8

出力:

*H*E*L*L*Oxfordl

入力:

alpha     20
beta       4
gamma     57
delta      3
epsilon   22
zeta      32
eta       53
theta     27

出力:

   *delta           *a*epsi*thetazeta                *eta*gamma

入力:

abc  5
d    5
abc  10
ABCDEFGHIJKLMNOPQRSTUVWXYZ 127

出力:

     *dbc *abc                                                                                                                 *ABCDEFGHIJKLMNOPQRSTUVWXYZ

ラベルやx座標が繰り返される場合があることに注意してください。


x座標が[0,127]で、文字列が(0,127]の場合、ラベルは行の右端からはみ出すことができますか、それとも保護されますか?つまり、「foo 127」は行を「*」または「* foo」?文字列にソフトエンドまたはハードエンドがあるかどうかを確認するだけです
PotatoOmeletteSandwich

3
@PotatoOmeletteSandwich私の意図は、合計長が255以内に収まるようにすることでした。したがって、x座標127に長さ127のラベルがある場合、最大出力長が発生します。 。
Sp3000

回答:


7

CJam、24 23 19バイト

l~Sf.*'*f*:.{S^+1=}

これは、座標ラベルのペアのCJam配列として入力を読み取ります。

CJamインタープリターでこのフィドルを試すか、すべてのテストケースを一度に検証します。

4バイトの節約を支援してくれた@MartinBüttnerに感謝します!

使い方

l~                   Read a line from STDIN and evaluate it.
  Sf                 For each pair, push the pair and " "; then:
    .*                 Perform vectorized repetition.
                         [X "label"] " " .* -> [(X spaces) "label"]
      '*f*           Join each resulting pair, using '*' as separator.
          :.{     }  Reduce by the following vectorized operator:
                       Push two characters (A and B).
             S^        Compute the symmetric difference of B and " ".
                       This pushes "B " for a non-space B and "" otherwise.
                +1=    Append and select the second character (with wrap).
                       This selects B for "AB " and A for "A".

2
テストケースを追加したばかりで、コメントを残して、いいえ、それがこの提出を壊さなかったと思いました-CJamのインタープリターの出力はワードラップだけです。混乱した場合に備えて。
Sp3000

4

Pyth、20バイト

V.Tmrj" *"d9Qpe+d-Nd

オンラインで試す:デモンストレーションまたはテストスイート

説明

V.Tmrj" *"d9Qpe+d-Nd
   m        Q         map each pair d of the input to:
     j" *"d             join d by the string " *"
    r      9            range-length encode 
                        (this gives x-coordinate spaces, a star and the label)
 .T                   transpose this table 
V                     for N in ^:
                 -Nd    remove spaces from N
               +d       add a space at the beginning
              e         take the last character
             p          and print it (without newline)

1
これは私が持っていたものよりもはるかに優れています。
isaacg

4

JavaScript ES6、104バイト

c=>(a=Array(255).fill(" "))&&c.map(([u,v])=>a.splice(u,v.length+1,..."*"+v))&&a.join``.replace(/ +$/,"")

使用例

準拠コンソールへの入力:

t = [[0,"Hello"],[8,"World"],[3,"Fizz"],[5,"Buzz"],[16,"PPCG"],[9,"X"]];
(c=>(a=Array(255).fill(" "))&&c.map(([u,v])=>a.splice(u,v.length+1,..."*"+v))&&a.join``.replace(/ +$/,""))(t);

最後のステートメントからの出力:

"*He*F*Buz*Xrld  *PPCG"

説明

これにより、c論理的にANDで結合された3つの式から無名関数が作成されます。最初の2つのステートメントは常に真実であり、JSの短絡ルールでは、最初のステートメントが真実である場合は常に、ブール値に強制せずに値全体を右側に返します。したがって、これは形式的に

(function (c) {
    a = Array(255).fill(" ");                    // global variable `a` overwritten
    c.map(function (x) {                         // only side-effects are used here.
       var u = x[0], v = x[1];                   // ES6 destructuring
       a.splice(u, v.length + 1, ..."*" + v));   // main logic
    });
    return a.join("").replace(/ +$/, "");        // postprocessing and trim
})

代入演算子=は論理AND演算子よりも優先順位が低いため、最初のステートメントは上記の括弧で囲む必要があり&&ます。

「レストパラメーター」アセンブリ..."*"+vもES6の一部です。*文字列の先頭を連結し、リストのようなパラメータとして解釈し、に提供される一連の引数に分割しArray.prototype.spliceます。(m, n, ...rest)一連ます。引数は、要素mを削除する位置で配列を取得および変更し、nすべてのrest引数を挿入します。ES6より前にこれを実現するには、より面倒なものを使用します。

[].slice.apply(a, [u, v.length + 1].concat(("*" + v).split("")))

その後、配列は空の文字列と連結され、末尾の空白が削除されます。


4

Python 2、67バイト

z=''
for a,b in input():z=(z+' '*b)[:b]+'*'+a+z[len(a)-~b:]
print z

入力を受け取り[('Heathrow', 0), ('Edinburgh', 2), ('London', 4), ('Liverpool', 6), ('Oxford', 8)]、結果を出力します。

Pythonは文字列を変更することを許可しておらず、リストへの変換やリストからの変換は高価です。したがって、これにより文字列zが再作成され、新しい単語が追加されます。b単語の前の文字を取得し、必要に応じてスペースでパディングし、次にアスタリスクで新しいテキスト、次にz新しい単語後の。末尾のスペースは追加されないことに注意してください。

reduceバージョンは、長い3つの文字(70)です。

lambda I:reduce(lambda z,(a,b):(z+' '*b)[:b]+'*'+a+z[len(a)-~b:],I,"")

3

ルビー、94 81 75バイト

ゴルフ:

s=" "*128;$<.map{|l|w,p=l.split;p=p.to_i;s[p..w.size+p]="*"+w};$><<s.rstrip

以下に、コード化されていないコードを示します。

s = " "*128
$<.map{|l|                 # for each line entered via stdin, ctrl+D to stop
  w,p = l.split            # had to move the chomp down here
  p = p.to_i               # there's no 'to_i!'...
  s[p..w.size+p] = "*"+w   # in the range of *foobar, replace the string
}
$><<s.rstrip               # output suggested by w0lf

入力のマッピングに関する提案をありがとう@ w0lf!

変数を削除することについて考えてくれた@ w0lfと@Not Charlesに感謝します。


ルビーのゴルフのヒントをご覧ください。この場合、あなたが適用できる$を<マップ{| L | ...}リットル中よりも短くなっている=取得します; ...;エンドチップと、おそらく置き換えputs $><<(余分なスペースを必要としません)。
クリスチャンルパスク

また、.chomp削除できると思います。
クリスチャンルパスク

この場合、あなたがそれについて言及したので、私はそれ.to_iをキャッチするので、削除することはおそらく非常に安全だと思います。いい考えだ。ありがとう@ w0lf!
PotatoOmeletteSandwich

どういたしまして!上記のヒントを適用した短いバージョンであるideone.com/BiOvV5を次に示します。気に入ったら、回答に自由に投稿してください。
クリスチャンルパスク

3
@PotatoOmeletteSandwich Rubyをアップグレードします。1.8.7はサポート終了です!また、1文字節約s[int, int]する代わりにフォームを使用できるはずs[range]です。
チャールズではない

3

Javascript 121文字

非標準機能を使用して、Firefoxで動作します。
x=Array(255).fill(" ");eval(prompt()).map(s=>{s[0].split``.map((n,i)=>x[s[1]+i+1]=n);x[s[1]]="*"});x=x.join``.trimRight()

古いバージョン: x=Array(255).fill(" ");eval(prompt()).map(s=>{s[0].split``.map((n,i)=>x[s[1]+i+1]=n);x[s[1]]="*"});x=x.join``.replace(/ +$/,"")

x=Array(255).fill(" ");      //Creates an array with spaces
eval(prompt())               //Gets some input, has to look like [["Hello",4],["Hi",14],["Oi",0]]
.map(s=>{s[0].split``.map((n,i)=>x[s[1]+i+1]=n);x[s[1]]="*"}); //Main "logic"
x=x.join``.replace(/ +$/,"") //Gets rid of the trailing spaces

1
/ +/ \sがっかりするよりもずっと理にかなっている を使用x=' '.repeat(255);して回避するバイトを節約できます.joinか?
ドムヘイスティングス

1
@DomHastings:JS文字列は不変なので.split('')、変更可能なデータ構造にする必要がありますが、その時点でArray(255).fill(' ')は短くなります。私のバージョンでは、ほとんどの節約は(a)「関数またはプログラムのいずれかを指定できます」というルールを使用eval(prompt())して削除しc=> 、(b)組み込みArray.prototype.sliceパラメーターを使用して残りのパラメーターを使用してロジック部分を少し短くする。
CR Drost

1
@ChrisDrostああ、もちろん...ただのアクセサであることを忘れてしまいました!恥は[].map.call(s[0],...どちらか任意の保存されない
ドムヘイスティングス

2

Python、85バイト

def g(p):
 z=[' ']*256
 for a,b in p:z[b:b+len(a)+1]='*'+a
 return''.join(z).rstrip()

オンラインで試す


1
1バイトを保存する'z'[2::5]代わりに(アポストロフィの代わりにバッククォート)できるようになり、パラメーターに''.join(z)移動z=[' ']*256すると別のバイトが保存されます。また、私はあなたが変えることができると思いますreturnprint
カーデ

p=input()インデントを回避する関数ではなく(Python 2)を使用してプログラムを記述することで、文字を保存できると思います。また、b+len(a)+1可能性がありますb-~len(a)
-xnor

1
実際、プログラムはあなたにそれをさせますfor a,b in input():
xnor

2

Perl、66バイト

63バイトのスクリプト+ 3バイト -p

$}||=$"x128;/\s+/,substr$},$',1+length$`,"*$`"}{$_=$};s/\s+$/
/

文字列を分割する代わりに、変数$`を使用し、$'それぞれ「一致の前」と「一致の後に」ある特別なものはありません。私は$}元々は1バイト節約していたので、文字列変数にましたが、それ以上ではありません!

実行例:

$perl -p overwritlabels.pl <<< 'Hello  0
World  8
Fizz   3
Buzz   5
PPCG   16
X      9'
*He*F*Buz*Xrld  *PPCG

Perl、65バイト

62バイトのスクリプト+ 3バイト -p

各行を印刷する別のバージョン(1バイト少なく!)。(はい、質問をきちんと読んでいなかったのでこれを作りました...)

$}||=$"x128;/\s+/;substr$},$',1+length$`,"*$`";$_=$};s/\s+$/
/

実行例:

$perl -p overwritlabels.pl <<< 'Hello  0
World  8
Fizz   3
Buzz   5
PPCG   16
X      9'
*Hello
*Hello  *World
*He*Fizz*World
*He*F*Buzzorld
*He*F*Buzzorld  *PPCG
*He*F*Buz*Xrld  *PPCG

2

PHP-84バイト

<? foreach(array_chunk(array_slice($argv,1),2) as $p) echo "␣[".($p[1]+1)."G*$p[0]";
                                                            ^ ESC character (\x1b)

ANSIエスケープコードを使用してカーソルを配置し(\x1b[XG、エスケープ文字とXが1ベースの座標であることを特徴とする)、その後*にその行の入力文字列が続きます。次の形式のコマンドラインで入力を受け入れます。

php filename.php Heathrow 0 Edinburgh 2 London 4 Liverpool 6 Oxford 8
php filename.php abc 5 d 5 abc 10 ABCDEFGHIJKLMNOPQRSTUVWXYZ 127

コマンドライン引数であるため、引用符で囲まれている場合、複数語のエントリを受け入れます。


1

C ++ 11、95バイト

何故なの?

関数として、位置と文字列を含むmap<int, string>名前付きの入力を受け取りvます。

string t(255,' ');for(auto&m:v){int i=m.first;t[i++]='*';for(auto&c:m.second)t[i++]=c;}cout<<t;

使用法

#include <iostream>
#include <map>
using namespace std;
int main(){
    map<int,string> v{{0,"Heathrow"},{2,"Edinburgh"},{4,"London"},{6,"Liverpool"},{8,"Oxford"}};
    string t(255,' ');for(auto&m:v){int i=m.first;t[i++]='*';for(auto&c:m.second)t[i++]=c;}cout<<t;
}

ここで実行して確認してください

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