マーキーサイン文字


41

毎日、移動可能な文字マーキーサインに新しい単語を追加し、必要な文字だけを購入します。可能な限り、以前の単語用に購入した文字を再利用します。毎日書きたい単語を順番に指定して、毎日購入する文字を出力します。

Input:  ['ONE', 'TWO', 'THREE', 'SEVENTEEN']
Output: ['ENO', 'TW', 'EHR', 'EENSV']

1日目:あなたはなし文字で始まるが、その書き込みにONE、あなたはそのすべての文字を買いますENO
2日目:翌日、あなたは我慢したいTWO (降ろすONE)。あなたはすでにOfromを持っているONEので、追加を購入しますTW
3日目:この時点で、あなたは持っていENOWTます。書くには THREE、あなたが必要EHRです。Eあなたが持っているものに加えて秒を購入する必要があることに注意してください。
4日目:を書くにはSEVENTEENEすでに2つ(3つではない!)ある4 の合計が必要な ので、さらに2つ購入します。にもとのT1つがあるNので、残りの文字を購入します EENSV

この例ではアルファベット順に文字を出力しましたが、任意の順序で出力できます。

入力:文字の空でない文字列の空でないリストA-Z。必要に応じて小文字を使用できます。文字列には文字のリストが適しています。

出力:毎日購入する必要がある追加の手紙を出力または印刷します。1日の文字は任意の順序で出力できますが、日は正しい順序でなければなりません。

毎日の文字は他の日と区別する必要がありますので、一日の終わりを知ることができます。1日以内または数日間の両方で、末尾および/または先頭の区切り文字は問題ありません。1日には購入した文字がなく、出力に反映される必要があることに注意してください(最終日であっても、スペースまたは空の行は問題ありません)。

テストケース

['ONE', 'TWO', 'THREE', 'SEVENTEEN']
['ENO', 'TW', 'EHR', 'EENSV']

['ONE', 'TWO', 'ONE', 'THREE']
['ENO', 'TW', '', 'EHR']

['ABC', 'AABC', 'ABBC', 'ABCC', 'AABBCC']
['ABC', 'A', 'B', 'C', '']

['SHORT', 'LOONG', 'LOOOONG', 'LOOOOOOONG', 'SHORT', 'LOOONG']
['HORST', 'GLNO', 'OO', 'OOO', '', '']

すべての入力と出力は個別のリストです:

[['ONE', 'TWO', 'THREE', 'SEVENTEEN'], ['ONE', 'TWO', 'ONE', 'THREE'], ['ABC', 'AABC', 'ABBC', 'ABCC', 'AABBCC'], ['SHORT', 'LOONG', 'LOOOONG', 'LOOOOOOONG', 'SHORT', 'LOOONG']]
[['ENO', 'TW', 'EHR', 'EENSV'], ['ENO', 'TW', '', 'EHR'], ['ABC', 'A', 'B', 'C', ''], ['HORST', 'GLNO', 'OO', 'OOO', '', '']]

そして、スペースで区切られた文字列として(出力の末尾のスペースが重要です):

ONE TWO THREE SEVENTEEN
ONE TWO ONE THREE
ABC AABC ABBC ABCC AABBCC
SHORT LOONG LOOOONG LOOOOOOONG SHORT LOOONG

ENO TW EHR EENSV
ENO TW  EHR
ABC A B C 
HORST GLNO OO OOO  

リーダーボード


5
野生のリーダーボードスクリプトはuserscript時代に出演しています。o
Quintec

すべての文字の文字列ではなく、購入する必要がある文字の配列として出力できますか?例:[['E', 'N', 'O'], ...]
ダウンゴート

出力SHORTLONGOOOOOは最後の出力に対して有効ですか?区切り文字を使用しない別名?
マジックタコop

@Downgoatはい、リストは文字で出力しても問題ありません。
xnor

@MagicOctopusUrnいいえ、区切り文字が必要です。そうしないと、どの文字が何曜日のものかわかりません。
xnor

回答:


10

Haskell、54 49バイト

import Data.List
g x=zipWith(\\)x$scanl(++)""$g x

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

\\入力リストのリスト差分()と出力リストの累積追加(で始まる)をペアワイズで計算して、出力リストを作成します""

input list:                ONE       TWO       THREE        SEVENTEEN
cumulative append:         ""   +->  ONE  +->  ONETW   +->  ONETWHRE
list difference (output):  ONE -+    TW  -+    HRE    -+    SVEEN

両方Data.ListData.Functionスコープで(たとえば、lambdabot環境を使用して)、これは30バイトに短縮できます。

fix.(.scanl(++)"").zipWith(\\)

編集:@Sriotchilism O'Zaicのおかげで-5バイト。



10

パイソン272の 68バイト

ジョナサン・アランのおかげで-4バイト。

p=''
for r in input():
 for x in p:r=r.replace(x,'',1)
 print r;p+=r

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

コメント済み

l=input()       # the list of words to write
p=''            # p contains all letters we own
for r in l:     # for each word ...
  for x in p:   # for each letter we own ...
    r=r.replace(x,'',1)   # remove one occurence from the current word
  print r       # print the remaining word
  p+=r          # add the remaining chars to p

3
for r in input():4バイト節約します。
ジョナサンアラン


7

Perl 6、44バイト

{$!=@;.map:{kxxv $!=.comb.Bag∖($⊎=$!):}}

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

文字のリストのリストとして出力します。

説明

{                                      } # Anonymous codeblock
 $!=@;                                   # Initialise $! to an empty list
      .map:{                          }  # Map each item in the input to
                    .comb                # The string split to characters
                         .Bag            # In a Bag
                                        # Set minus
                              ($⊎=$!)    # The accumulated Bag of results
                 $!=                     # And save the result for the next item
            kxxv                     : # Then decompose the Bag into a list

2
downvoteの理由は高く評価されるでしょう
ジョーキング

ダウンボッターではありませんが、この出力形式はあまりにも遠すぎます。Bag(E(2), N, S, V)実際に2つのEを表示してOKにする必要があるようなものです。
xnor

3
えっ、ほんとう?それは単なるデフォルトの印刷フォーマットです。返される結果は、これらの文字を含む順序付けられていないリストです(同じ文字を複数含むことができます)。これをよりよく反映するために出力フォーマットを更新しますが、下票はばかげているようです。
ジョーキング

Downvoter、説明していただけますか、これはI / Oまたは他の何かについてですか?バッグの形式については、私はPerlを知りません。これはPerlゴルフのI / Oで一般的ですか?ドキュメント(サイトがダウンしているためキャッシュされている)を見ると、collections.Counter出力として許可するつもりはなかったPythonのように、カウントのある辞書のように思えます。バッグのエルトを多重度で簡単に反復したり、リスト/配列にキャストしたり、多重度で表示したりできますか?
xnor

3
Downvoteは間違いで、アップすることを意図していました。
ジョナサンアラン

7

Haskell、44バイト

import Data.List
foldl1(\a x->a++',':(x\\a))

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

出力は、ONE,TW,HRE,SVEEN日の間にコンマがあるような文字列です。


1
\`. And an unexpected foldl1`ベースケースも折りたたむ必要がないようにするための、出力フォーマットの素晴らしい使用法。
xnor

7

JavaScript(Node.js)、59バイト

a=>a.map(h=>([...t].map(c=>h=h.replace(c,'')),t+=h,h),t='')

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

非常に簡単なソリューション。単語ごとにh、すでにある文字を削除します。

そのコードの説明バージョンは次のとおりです。

f = list => {
  // the string that accumulates all the letters already bought
  let accu = '';
  // for every word in the list
  return list.map( word => {
    // for every letter already bought 
    [...accu]
      // remove the letter from the word
      .map(char => {
        return word = word.replace(char,'')
      });
    // add not bought letters to accumulator
    accu += word;
    // the reduced word (without already bought letters) should be added to result map
    // this represents the letters to buy today
    return word
  }, accu)
}

console.log(f(['ONE', 'TWO', 'THREE', 'SEVENTEEN']))
console.log(f(['ONE', 'TWO', 'ONE', 'THREE']))
console.log(f(['ABC', 'AABC', 'ABBC', 'ABCC', 'AABBCC']))
console.log(f(['SHORT', 'LOONG', 'LOOOONG', 'LOOOOOOONG', 'SHORT', 'LOOONG']))


私の複雑すぎるソリューションから価値のあるトリックを借りることで、1バイト節約できます
アーナルド

5

J、29バイト

FrownyFrogのおかげで-29バイト!

(],a.<@#~0>.-&(1#.a.=/;))/@|.

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

元の投稿

J、58バイト

[:}.@>[:(],<@(/:~@({.@>@-.&(((e.<@#[){:)\));))&.>/<@a:,~|.

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

「繰り返し部分を尊重しながら文字を引く」の改善にご協力いただいたngnに感謝します。

Jにはあまり適していませんが、照明の練習です。

wo繰り返しを尊重しながら、ある文字列内のすべての文字を別の文字列から削除するヘルパー動詞(「なし」)を作成することから始めましょう。

wo=.{.@>@-.&(((e. <@# [) {:)\)

ここには楽しいアイデアがあります。必要な回数だけ繰り返して、キャラクターの繰り返される各インスタンスを一意にします。したがって、元の文字列が次のABBAようになる場合:

┌─┬─┬──┬──┐
│A│B│BB│AA│
└─┴─┴──┴──┘

3番目Aが次のようになりAAAます。これは((e. <@# [) {:)\、各プレフィックスを取り\、その最終要素{:を調べ、その最終要素 に一致e.するそのプレフィックス内のすべての要素のマスクを構築し、 それらの要素のみをフィルタリングおよびボックス化するフレーズによって実現され ます<@#

両方の入力が「一意化」され-. ているため、繰り返しを尊重しながら、通常の集合マイナスを安全に使用できます。

次に、各結果を開き、繰り返しを「元に戻す」ための最初の要素のみを取得します。 {.@>

このヘルパー動詞をプラグインすると、全体的なソリューション(単純にインライン化されます)は次のようになります。

[: }.@> [: (] , <@(/:~@wo ;))&.>/ <@a: ,~ |.

基本的に、ここで行うことは、問題を単一の削減として設定することです。入力|.を反転し、それに,~ace a:または空のボックスを追加し始めます。これは、次のように最終結果の初期値になります。

┌─────────┬─────┬───┬───┬──┐
│SEVENTEEN│THREE│TWO│ONE│┌┐│
│         │     │   │   ││││
│         │     │   │   │└┘│
└─────────┴─────┴───┴───┴──┘

削減を行うために、各要素間に次の動詞を付けます。

(] , <@(/:~@wo ;))/

これは、右の入力(つまり、これまでの文字なし)なしで、右の入力(つまり、]結果)を取得し、それに, 左の入力(ONE最初の反復、TWO2回目など)を追加します。使用されますが、並べ替えて追加する前に、もう一度ボックス化します。wo;/:~<@

このすべての最後に、必要な結果、ボックスのリストがありますが、すべてが1つの大きな追加ボックス内にあり、前に空のボックスがあります。したがって、外側のボックスを削除して最初の要素を削除します:}.@>


[:}.@>|.(],a.<@#~0>.-&(1#.a.=/;))&.>/@,<@a:
FrownyFrog

(],a.<@#~0>.-&(1#.a.=/;))/@|.エッジケースを逃していない限り、シンプルでも動作します。
FrownyFrog

私が知る限り、ソートは要件のどこにもありません。
FrownyFrog

2
更新され、今ではそれを吸収する時間がありました。もう一度言いたいだけです。
ヨナ

4

JavaScript(ES6)、 66  65バイト

a=>a.map(b=s=>[...s].filter(c=>x==(x=x.replace(c))?b+=c:0,x=b+0))

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

コメント済み

bbxcxb

a =>                      // a[] = input
  a.map(b =               // initialize b to the callback function of this map()
                          // it will be coerced to a string that does not contain
                          // any letter in uppercase
    s =>                  // for each entry s in a[]:
    [...s].filter(c =>    //   for each character c in s:
      x == (              //     check whether x is changed when
        x = x.replace(c)  //     c is replaced with 'undefined'
      ) ?                 //     if so:
        b += c            //       append c to b and keep c
      :                   //     else:
        0,                //       discard c
      x = b + 0           //     coerce b to a string and save it in x
    )                     //   end of filter()
  )                       // end of map()

4

C ++(gcc)177 170バイト

@anatolygのヒントのおかげで-5バイト、私が気づいた小さなものに-2バイト。

#import<random>
#define v std::vector<std::string>
v a(v p){std::vector<int>o(91),b;int j=-1;for(auto i:p){b=o;p[++j]="";for(int c:i)--b[c]<0?p[j]+=c,++o[c]:0;}return p;}

説明

#import<random>両方<string><vector>半バイトを追加します。

最初に、0の91要素ベクトル(文字の出現を格納するためにインデックス65-90のみが使用されます)と、同じタイプの値に設定されていない別のベクトルを作成します。入力の各要素(日)を反復処理します。現在所有されている文字を取得し、その日に必要な文字を取得し、必要な量でインデックスの入力をオーバーライドし、所有されている文字を更新します。オーバーライドされた入力を返します。

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


#define v std::vector<std::string削除using namespace stdして、バイトカウントを6バイト減らすことができます。
アナトリグ

2

C#(Visual C#Interactive Compiler)、123バイト

a=>{var b="";for(dynamic i=0,e,f;i<a.Count;b+=a[i++]=f)foreach(var c in((e,f)=(b.ToList(),"")).f+a[i])f+=e.Remove(c)?"":c;}

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

入力配列を変更して出力する無名関数。

// a: input array of strings
a=>{
  // b: cumulative letters
  var b="";
  for(
    // i: loop index of string
    // e: copy of cumulative letters for manipulation
    // f: characters missing from current string
    dynamic i=0,e,f;
    // iterate over each string in a
    i<a.Count;
    // add missing letters of the day to
    // cumulative missing letters and
    // update array for output
    b+=a[i++]=f
  )
    // iterate current string with character c
    foreach(var c in
      // tuplized variable assignment
      // e=b.ToList()
      //   set e to a copy of the cumulative letters
      // f=""
      //   initially there are no letters needed for the day
      ((e,f)=
      (b.ToList(),"")).f+a[i]
    )
      // conditionally add c to missing letters for the day
      f+=e.Remove(c)?"":c;
}

2

R、119 112106103バイト

長い2つの関数名のエイリアスから-7バイト、scan()
-6バイトからユーザー入力 を取得strsplit()して最初に1回だけ呼び出す
-3バイト、エイリアスを削除し、1回の呼び出しで2つの変数を割り当てる

(以前に誤って少なくなったバイト数も編集しました)

a=scan(,'');b=a=strsplit(a,'');for(i in 2:length(a))b[[i]]=vecsets::vsetdiff(a[[i]],unlist(b[1:i-1]));b

これは、あらゆる種類の私の最初のPPCG提出です!ですから、私はゴルフとエチケットの投稿の両方の面で何をしているのか分かりません。出力は、チャレンジの条件を満たしている場合と満たしていない場合があるベクトルのリストです。:-P

コード自体に関してはscan()、他のソリューションと同様に、ユーザー入力を使用して、新しい各日の文字を累積的に所有する文字と比較します。短い選択肢がある場合unliststrsplit知ってクールになる個々の文字のベクターに文字列を変換するために。またvsetdiff、Carl Withoftのvecsetsパッケージの関数を使用して、翌日に必要な文字と所有されている現在の文字のセットの差を取得しました。


1
いいえ、まったく問題ありません。私は外部パッケージの使用に少し消極的ですが、それは私だけです...私はベースRコードの課題にアプローチすることを好みます;)
digEmAll






2

Japt15 14バイト

£Q®X=rZPPÃQ±XX

それを試してみてください

£Q®X=rZPPÃQ±XX     :Implicit input of array
£                  :Map each X
 Q®                :  Map each Z in Q (initially a quotation mark)
   X=              :    Reassign to X
     rZ            :    Replace Z with
       P           :    The empty string
        P          :    With the default global flag disabled
         Ã         :  End map
          Q±X      :  Append X to Q
             X     :  Return X

1
@Downvoter、コメントを残す良識を持ってください。
シャギー


1

PowerShell、71バイト

$args|%{$w=$_;$p|% t*y|%{$w=$w-replace"^(.*?)$_(.*)",'$1$2'};$w;$p+=$w}

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

入力語$argsを取得し、それらを繰り返します。反復ごとに現在のwordを設定し、購入済みの文字のoolを$wループします$p。各内部ループでは-replace、現在の$wordで正規表現を実行するため、$pool からの文字の最初のインスタンスのみを置き換えています。プール内のすべての文字$wを確認したら、残っているもの(つまり、購入する必要があるもの)を出力$p+=$wし、次の単語のためにそれらの文字をプールに追加します。


1

Excel VBA、127バイト

Function z(w)
z=""
For Each x In w.Cells
v=x.value
For y=1To Len(z)
v=Replace(v,Mid(z,y,1),"",1,1)
Next
z=z&v
Next
End Function

Excel範囲の形式で入力を受け取ります。




1

スウィフト4.2 / Xcodeの10.2244の 242 239 238バイト

a.reduce(([Character:Int](),[String]())){c,l in let b=l.reduce(into:[Character:Int]()){$0[$1,default:0]+=1}.map{($0,max(0,$1-(c.0[$0] ?? 0)))};return(c.0.merging(b){$0+$1},c.1+[b.map{String(Array(repeating:$0.0,count:$0.1))}.joined()])}.1

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

文字はアルファベット順に並べられておらず、規則によって禁止されていません。


1

Scala、68バイト

(c:Seq[String])=>c./:(Seq(""))((a,n)=>a:+n.diff(a./:("")(_+_))).tail

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

/:foldLeft演算子の省略形、aは集計、最終的に必要な結果を返し、nは次の要素

ゴルフをしていない

def NewLettersPerDay(c: Seq[String]): Seq[String] = {
    c.foldLeft(Seq(""))((agg, next) => {
      val existingLetters = agg.reduce(_+_)
      val newDayLetters = next.diff(existingLetters)
      agg :+ newDayLetters
    }).tail
}


0

、18バイト

EθΦι¬⊙…θκ‹№…ιμλ№νλ

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

 θ                  Input array
E                   Map over strings
   ι                Current string
  Φ                 Map over characters
       θ            Input array
      …             Truncated to length
        κ           Outer index
    ¬               Logical Not
     ⊙              Any element exists where
          №         Count of
              λ     Current letter in
            ι       Outermost word
           …        Truncated to
             μ      Current letter index
         ‹          Is less than
               №    Count of
                 λ  Current letter in
                ν   Innermost word
                    Implicitly print each day's bought letters on their own line

0

PHP、UTF-8対応(253バイト)

<?php $p=[];for($i=1;$i<$argc;$i++){$a=$p;$b=[];for($j=0;$j<mb_strlen($s=$argv[$i]);$j++){$k=1;if(isset($a[$c=mb_substr($s,$j,1)]))if($a[$c]){$k=0;$a[$c]--;}if($k){echo $c;if(isset($b[$c]))$b[$c]+=$k;else $b[$c]=$k;}}$p=array_merge($p,$b);echo PHP_EOL;}

0

C#(Visual C#Interactive Compiler)、112バイト

a=>{var b="";for(int i=0;;b+=a[i++])foreach(var z in b)if(a[i].Contains(z))a[i]=a[i].Remove(a[i].IndexOf(z),1);}

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


うーん...これは例外をスローしますか?
ダナ

@dana何も返さない関数は例外で終了できると確信しています
無知の具体化

興味深い...私はそれが最も奇妙なルールではないと思います。
ダナ




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