选框标志字母


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天:要写作SEVENTEEN,您需要E共有4 个,而您已经有2个(而不是3个!),因此您又买了2个。您也有T和之一N,因此您可以购买剩余的字母: EENSV

在此示例中,我们输出了按字母顺序排序的字母,但是您可以按任何顺序输出它们。

输入:非空字母字符串的非空列表A-Z。如果愿意,可以使用小写字母。字符列表适用于字符串。

输出:输出或打印您每天需要购买的其他字母。一天中的字母可以以任何顺序输出,但是日期必须以正确的顺序排列。

每天的来信应与其他日期分开,以便您知道一天的结束时间。在一天之内或几天之间,尾随和/或前导分隔符都可以。请注意,一天可能没有购买任何字母,这应该反映在输出中(空格或空行也可以,即使是最后一天也可以)。

测试用例

['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
用户脚本时代出现了一个疯狂的排行榜脚本:o
Quintec

我们可以输出需要购买的字符数组而不是所有字符的字符串吗?例如:[['E', 'N', 'O'], ...]
Downgoat

输出SHORTLONGOOOOO对最后一个输出有效吗?也没有使用分隔符?
魔术章鱼缸

@Downgoat是的,列表可以输出chars。
xnor

@MagicOctopusUrn不,您需要定界符,否则您将无法分辨星期几是什么字母。
xnor

Answers:


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(\\)

编辑:-5字节,感谢@Sriotchilism O'Zaic。



10

Python 2中72 68个字节

-4个字节感谢Jonathan Allan。

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
不赞成投票的原因将不胜感激
Jo King

不是下降投票者,但我要说的是这种输出格式偏离得太远了。喜欢的东西Bag(E(2), N, S, V)需要实际显示二号E的是OK。
xnor

3
真的吗 这只是默认的打印格式。返回结果是一个包含这些字符的无序列表(并且可以包含多个相同字符)。我将更新输出格式以更好地反映这一点,但是下降表决似乎很荒谬。
Jo King

Downvoter,请您解释一下,这是关于I / O还是其他?关于包装袋的格式,我不知道Perl,这在Perl高尔夫中对I / O通用吗?查看文档(由于站点关闭而被缓存),在我看来,它们更像是带有计数的字典,类似于Python collections.Counter,但我不想将其作为输出。一个人可以轻松地遍历遍历多个包包,转换为列表/数组,进行多重展示等吗?
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个字节
Arnauld

5

J,29个字节

-29字节感谢FrownyFrog!

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

在线尝试!

原始帖子

J,58字节

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

在线尝试!

感谢ngn帮助改善“在尊重重复部分的同时减去字母”。

对于J而言,这不是一个很好的选择,但它是一个有启发性的练习。

让我们从构造一个辅助动词wo(“ without”)开始,该动词将一个字符串中的所有字符从另一个字符串中删除,同时注意重复。

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

这里有一个有趣的主意:通过重复所需次数,使每个重复的字符实例唯一。因此,如果我们的原始字符串为ABBA

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

三分之一A将成为AAA依此类推。这是通过短语实现的,该短语 ((e. <@# [) {:)\采用每个前缀\,查看其最后一个元素 {:,并为该前缀中与e.该最终元素匹配的所有元素构造一个掩码 ,然后仅过滤和包装这些元素<@#

使用我们的输入都是“唯一的”,我们现在可以安全地使用正常的设定负值,-. 同时仍然要遵守重复。

然后,我们打开每个结果并仅采用第一个元素“撤消”我们的重复: {.@>

插入该辅助动词后,我们的整体解决方案(只需对其进行内联)将变为:

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

本质上,我们在这里所做的只是将我们的问题设置为一次归约。我们开始反转输入,|.并在其后面附加,~一个ace a:或空框,这将是我们最终结果的初始值,如下所示:

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

我们在每个元素之间插入以下动词以实现简化:

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

这就是说:取正确的输入](即我们的结果)并将其追加到, 左边的输入(ONE在第一次迭代中,TWO在第二个迭代中,依此类推),而不会wo混淆;正确的输入(即到目前为止没有任何先前的字母) ),但在追加排序之前/:~,请再次将其装箱<@

在所有这些操作的最后,我们将得到想要的结果,一个盒子列表,但全部都在一个大的附加盒子内,并且前面还有一个空盒子。因此,我们打开以移除外框并杀死第一个元素:}.@>


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

(],a.<@#~0>.-&(1#.a.=/;))/@|.除非我缺少边缘情况,否则简单的方法也适用。
FrownyFrog

据我所知,排序是没有要求的。
FrownyFrog

2
更新,现在我有时间去吸收它,只想再说一遍:那该死的好J!
约拿

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)177170字节

@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>一半的字节。

首先创建一个91元素的矢量0(仅使用索引65-90来存储字母出现),然后创建另一个相同类型但未设置为值的矢量。遍历输入的每个元素(天):获取当前拥有的字母,获取当天所需的字母,用所需的数量覆盖索引上的输入并更新拥有的字母。返回覆盖的输入。

在线尝试!


您可以#define v std::vector<std::string删除using namespace std以减少6个字节的字节数。
anatolyg

2

C#(Visual C#交互式编译器),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,119112106103字节

从两个较长的函数名别名中减去-7个字节,现在从scan()
-6个字节中获取用户输入,只strsplit()在开头的
-3个字节中调用一次,以再次消除别名并在一个调用中分配两个变量

(还编辑了先前错误地降低了字节数)

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()与其他解决方案一样,它需要用户输入,并将每个新的一天的字母与累积拥有的字母进行比较。如果有更短的替代方法unlist以及strsplit将字符串转换为单个字符的矢量的替代方法,那将很容易理解。我还使用了vsetdiffCarl 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并遍历它们。每次迭代时,我们都设置当前单词$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

C(gcc),118个字节

m(a,r,q,u)char**a,*r,*q,*u;{for(;*a;a++,memcpy(r,q,255))for(memcpy(q,r,255),u=*a;*u;u++)*u=r[*u]-->0?32:(q[*u]++,*u);}

在线尝试!

作为一点红利,它r从一开始就以阵列形式接受库存。输出输入的以空值终止的以空值终止的字符串列表,a其中所有二手字母均用空格替换。




1

迅速4.2 / 10.2的Xcode244 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;}





By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.