Letreiro assinar letras


41

Cada dia, você coloca uma nova palavra em uma placa de letreiro com letras móveis , comprando apenas as letras necessárias para escrevê-la. Você reutiliza as letras que comprou para palavras anteriores sempre que possível. Dadas as palavras que você deseja escrever todos os dias em ordem, imprima as letras que compra todos os dias.

Exemplo

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

Dia 1: Você começa com nenhuma letra, de modo a escrever ONE, você compra todas as suas cartas E, N, O.
Dia 2: No dia seguinte, você deseja colocar TWO (retirar o ONE). Você já tem um Ode ONEe compra um adicional TW.
Dia 3: Neste ponto, você tem ENOWT. Para escrever THREE, você precisa EHR. Observe que você precisa comprar um segundo Ealém do que você possui.
Dia 4: Para escrever SEVENTEEN, você precisa Edo total de 4 , dos quais você já tem dois (e não três!), Para comprar mais dois. Você também tem a Te um dos N's, então você compra as letras restantes: EENSV.

Produzimos letras classificadas em ordem alfabética neste exemplo, mas você pode imprimi-las em qualquer ordem.

Entrada: Uma lista não vazia de cadeias de caracteres não vazias A-Z. Você pode usar letras minúsculas, se preferir. Listas de caracteres são boas para seqüências de caracteres.

Saída: Imprima ou imprima as letras adicionais que você precisa comprar todos os dias. As letras de um dia podem ser impressas em qualquer ordem, mas os dias devem chegar na ordem correta.

As letras de cada dia devem ser separadas de outros dias para que você possa saber onde termina o dia. Um separador à direita e / ou à esquerda é bom, dentro de um dia ou entre dias. Observe que um dia pode não ter letras compradas, o que deve ser refletido na saída (um espaço ou linha vazia está OK, mesmo no último dia).

Casos de teste

['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', '', '']

Aqui estão todas as entradas e saídas como listas separadas:

[['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', '', '']]

E como seqüências de caracteres separadas por espaço (os espaços à direita nas saídas importam):

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  

Classificação


5
Um script de cabeçalho selvagem apareceu na era do userscript: o
Quintec

Podemos produzir como uma matriz de caracteres que precisam ser comprados, em vez de uma sequência de todos os caracteres? por exemplo:[['E', 'N', 'O'], ...]
Downgoat

A saída é SHORTLONGOOOOOválida para a última saída? AKA sem delimitadores?
Magic Octopus Urn

@Downgoat Sim, as listas são caracteres que podem ser usados.
xnor 22/04

@MagicOctopusUrn Não, você precisa de delimitadores, caso contrário, você não pode dizer quais são as letras para que dia.
xnor 22/04

Respostas:


10

Haskell, 54 49 bytes

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

Experimente online!

Construímos a lista de saída calculando em pares a diferença da lista ( \\) da lista de entrada e o apêndice cumulativo da lista de saída (começando com "").

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

Com ambos Data.Liste Data.Functionno escopo (por exemplo, usando o ambiente lambdabot), isso pode ser reduzido para 30 bytes:

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

Edit: -5 bytes graças a @Sriotchilism O'Zaic.



10

Python 2 , 72 68 bytes

-4 bytes graças a Jonathan Allan.

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

Experimente online!

Comentado

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():salva 4 bytes.
Jonathan Allan


7

Perl 6 , 44 bytes

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

Experimente online!

Saída como uma lista de listas de caracteres.

Explicação

{                                      } # 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
Uma razão para o voto negativo seria apreciada
Jo King

Não é o downvoter, mas vou dizer que esse formato de saída está muito longe. Algo como Bag(E(2), N, S, V)precisaria mostrar realmente dois E's para ficar OK.
xnor 21/04

3
O que realmente? Essa é apenas a formatação de impressão padrão. O resultado do retorno é uma lista não ordenada que contém esses caracteres (e pode conter vários do mesmo caractere). Atualizarei a formatação da saída para refletir melhor isso, mas o voto negativo parece ridículo.
Jo King

Downvoter, você poderia explicar, isso é sobre E / S ou algo mais? Sobre o formato da bolsa, não sei Perl, isso é comum para E / S nos campos de golfe Perl? Olhando para os documentos (armazenados em cache porque o site está inoperante), eles parecem-me mais com dictos com contagens, semelhantes aos do Python collections.Counterque eu não pretendia permitir como saída. Pode-se iterar facilmente os elfos de saco com multiplicidade, converter em uma lista / matriz, exibir com multiplicidade, etc?
xnor 21/04

3
O voto negativo foi um erro, era para ser bom.
Jonathan Allan

7

Haskell , 44 bytes

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

Experimente online!

Saída é uma cadeia de caracteres como ONE,TW,HRE,SVEENvírgulas entre dias.


1
Que bom uso do formato de saída para evitar a necessidade de dobrar também o \`. And an unexpected case base foldl1`.
xnor 27/04

7

JavaScript (Node.js) , 59 bytes

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

Experimente online!

Solução bastante simples. Para cada palavra h, remova as letras que já temos.

Aqui está uma versão explicada desse código:

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']))


Você pode economizar 1 byte emprestando o único truque que vale a pena da minha solução complicada.
Arnauld

5

J , 29 bytes

-29 bytes graças ao FrownyFrog!

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

Experimente online!

Correio Original

J , 58 bytes

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

Experimente online!

Agradecemos a ngn por ajudar a melhorar as "subtrair letras respeitando a parte da repetição".

Não é um ótimo ajuste para J, mas um exercício esclarecedor.

Vamos começar construindo um verbo auxiliar wo("sem") que remove todos os chacters de uma string da outra, respeitando as repetições.

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

Há uma idéia divertida aqui: Tornamos cada instância repetida de um personagem única, repetindo-a o número necessário de vezes. Assim, se nossa string original é ABBA:

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

Um terço Ase tornaria AAAe assim por diante. Isso é realizado pela frase ((e. <@# [) {:)\, que pega cada prefixo \, analisa o elemento final {:e constrói uma máscara de todos os elementos desse prefixo que correspondem e.ao elemento final e, em seguida, filtra e encaixa esses elementos <@#.

Com nossas entradas "únicas", agora podemos usar com segurança o conjunto normal menos -. , respeitando a repetição.

Em seguida, abrimos cada resultado e usamos apenas o primeiro elemento para "desfazer" nossas repetições: {.@>

Ao inserir esse verbo auxiliar, nossa solução geral (que simplesmente o destaca) se torna:

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

Basicamente, tudo o que fazemos aqui é configurar nosso problema como uma única redução. Começamos revertendo a entrada |.e acrescentando a ela ,~um ás a:ou caixa vazia, que será o valor inicial do nosso resultado final, assim:

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

Colamos o verbo a seguir entre cada elemento para efetuar a redução:

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

Isto diz: pegue a entrada correta ](ou seja, nosso resultado) e acrescente a , entrada esquerda (isto é, ONEna primeira iteração, TWOno 2º, etc.) sem woo detalhamento da ;entrada correta (ou seja, sem letras anteriores até o momento) usado), mas antes de anexá-lo, classifique-o /:~e encaixe-o novamente <@.

No final de tudo isso, obteremos o resultado que queremos, uma lista de caixas, mas todas dentro de uma grande caixa adicional e ainda com a caixa vazia na frente. Assim que abrimos para remover a caixa exterior e matar o primeiro elemento: }.@>.


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

Um simples (],a.<@#~0>.-&(1#.a.=/;))/@|.também funciona, a menos que esteja faltando um caso de ponta.
FrownyFrog

Tanto quanto posso dizer, a classificação não está em nenhuma parte dos requisitos.
FrownyFrog

2
Atualizado e agora que tive tempo de absorvê-lo, só queria dizer novamente: Que bom J!
Jonah

4

JavaScript (ES6),  66  65 bytes

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

Experimente online!

Comentado

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 bytes

-5 bytes graças à dica de @ anatolyg, -2 bytes a pequenas coisas que notei.

#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;}

Explicação

#import<random>adiciona ambos <string>e <vector>pela metade dos bytes.

Primeiro, cria um vetor de 0s com 91 elementos (apenas os índices 65-90 são usados ​​para armazenar ocorrências de letras) e outro vetor do mesmo tipo, mas não definido como um valor. Repete cada elemento da entrada (os dias): obtém as letras de propriedade atualmente, obtém as letras necessárias para o dia, substitui a entrada no índice pela quantidade necessária e atualiza as letras de propriedade. Retorna a entrada substituída.

Experimente online!


Você pode fazer #define v std::vector<std::stringe remover using namespace stdpara reduzir a contagem de bytes em 6 bytes.
anatolyg 22/04

2

C # (compilador interativo do Visual C #) , 123 bytes

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;}

Experimente online!

Função anônima que gera modificando uma matriz de entrada.

// 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 112 106 103 bytes

-7 bytes usando o alias dos dois nomes de função mais longos e agora recebendo entrada do usuário de scan()
-6 bytes para chamar apenas strsplit()uma vez no início
-3 bytes para se livrar do aliasing novamente e atribuir duas variáveis ​​em uma chamada

(Também editou a contagem de bytes incorretamente baixa anteriormente)

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

Este é o meu primeiro envio de PPCG de qualquer tipo! Portanto, não faço ideia do que estou fazendo, tanto em termos de golfe quanto em termos de etiqueta. O resultado é uma lista de vetores que podem ou não atender aos termos do desafio. :-P

Quanto ao próprio código, ele recebe a entrada do usuário scan()e compara as cartas de cada novo dia com as cartas de propriedade cumulativa, como em outras soluções. Se houver alternativas mais curtas para unliste strsplitpara converter cadeias de caracteres em vetores de caracteres individuais, seria interessante saber. Também usei a vsetdifffunção no vecsetspacote de Carl Withoft para obter a diferença definida das letras necessárias para o dia seguinte e das cartas atuais.


1
não, está perfeitamente bem. Estou um pouco relutante em usar pacotes externos, mas sou apenas eu ... prefiro abordar os desafios no código base R;)
digEmAll 23/04






2

Japonês , 15 14 bytes

£Q®X=rZPPÃQ±XX

Tente

£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
@ Downown, tenha a decência de deixar um comentário.
Shaggy


1

PowerShell , 71 bytes

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

Experimente online!

Pega palavras de entrada $argse itera sobre elas. A cada iteração, definimos a palavra atual e $w, em seguida, fazemos um loop sobre o conjunto $pde letras já compradas. Cada loop interno, realizamos uma regex -replaceem nosso $word atual , de modo que estamos substituindo apenas a primeira instância da letra do nosso $pool. Depois de ler todas as letras do pool, produzimos o que resta $w(ou seja, o que precisamos comprar) e, em seguida, colocamos essas letras no pool $p+=$wpara a próxima palavra.


1

Excel VBA, 127 bytes

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

Recebe entrada na forma de um intervalo do Excel.


1

C (gcc) , 118 bytes

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);}

Experimente online!

Como um pequeno bônus, ele recebe o estoque no rinício como uma matriz. Produz a lista de seqüência de caracteres terminada em nulo terminada em nulo acom todas as letras usadas substituídas por espaços.




1

Swift 4.2 / Xcode 10.2 , 244 242 239 238 bytes

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

Experimente online!

As letras não estão dispostas em ordem alfabética, não é proibido pelas regras.


1

Scala, 68 bytes

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

Experimente online!

/: é abreviação de operador foldLeft, a é agregação, retorna o resultado que queremos, n é o próximo elemento

Sem golfe

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

Carvão , 18 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

 θ                  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 ciente (253 bytes)

<?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;}





Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.