Letras de signo de marquesina

41

Cada día, coloca una nueva palabra en un letrero con letras móviles , comprando solo las letras que necesita para escribirla. Reutiliza las letras que ha comprado para palabras anteriores siempre que sea posible. Dadas las palabras que desea escribir cada día en orden, envíe las letras que compra cada día.

Ejemplo

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

Día 1: Se empieza con ninguna letra, por lo que a escribir ONE, usted compra todas sus letras E, N, O.
Día 2: Al día siguiente, desea aguantar TWO (quitar el ONE). Ya tienes una Ode ONE, por lo que compras una adicional TW.
Día 3: En este punto, tienes ENOWT. Para escribir THREE, necesitas EHR. Tenga en cuenta que necesita comprar un segundo Eademás del que tiene.
Día 4: Para escribir SEVENTEEN, necesita Eel total de 4 , del cual ya tiene dos (¡no tres!), Por lo que compra dos más. También tiene la Ty uno de los N's, por lo que comprar las letras restantes: EENSV.

Hemos enviado letras ordenadas alfabéticamente en este ejemplo, pero puede enviarlas en cualquier orden.

Entrada: una lista no vacía de cadenas de letras no vacías A-Z. Puede usar minúsculas si lo prefiere. Las listas de caracteres están bien para las cadenas.

Salida: Imprima o imprima las letras adicionales que necesita comprar cada día. Las letras de un día pueden aparecer en cualquier orden, pero los días deben venir en el orden correcto.

Las letras de cada día deben separarse de otros días para que pueda saber dónde termina un día. Un separador final y / o inicial está bien, tanto dentro de un día como entre días. Tenga en cuenta que un día puede no tener letras compradas, lo que debería reflejarse en la salida (un espacio o una línea vacía está bien, incluso para el último día).

Casos de prueba

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

Aquí están todas las entradas y salidas 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', '', '']]

Y como cadenas separadas por espacios (los espacios finales en las salidas importan):

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  

Tablas de clasificación

xnor
fuente
55
Un script de clasificación salvaje ha aparecido en la edad del script de usuario: o
Quintec
¿Podemos generar una serie de caracteres que deben comprarse en lugar de una cadena de todos los caracteres? por ejemplo:[['E', 'N', 'O'], ...]
Downgoat
¿La salida es SHORTLONGOOOOOválida para la última salida? ¿AKA sin usar delimitadores?
Urna de pulpo mágico
@Downgoat Sí, las listas son caracteres que están bien de salida.
xnor
@MagicOctopusUrn No, necesita delimitadores, de lo contrario no puede saber qué letras son para qué día.
xnor

Respuestas:

10

Haskell, 54 49 bytes

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

Pruébalo en línea!

Construimos la lista de salida calculando por pares la diferencia de lista ( \\) de la lista de entrada y el agregado acumulativo de la lista de salida (empezando por "").

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

Con ambos Data.Listy Data.Functiondentro del alcance (por ejemplo, mediante el uso del entorno lambdabot), esto se puede acortar a 30 bytes:

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

Editar: -5 bytes gracias a @Sriotchilism O'Zaic.

nimi
fuente
¿Por qué no esto?
Wheat Wizard
10

Python 2 , 72 68 bytes

-4 bytes gracias a Jonathan Allan.

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

Pruébalo en línea!

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
ovs
fuente
3
for r in input():ahorra 4 bytes.
Jonathan Allan
7

Perl 6 , 44 bytes

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

Pruébalo en línea!

Salidas como una lista de listas de caracteres.

Explicación

{                                      } # 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
Jo King
fuente
2
Una razón para el voto negativo sería apreciada
Jo King
No es el votante negativo, pero voy a decir que este formato de salida se desvía demasiado. Algo así Bag(E(2), N, S, V)necesitaría mostrar dos E para estar bien.
xnor
3
¿Lo que realmente? Ese es solo el formato de impresión predeterminado. El resultado devuelto es una lista desordenada que contiene esos caracteres (y puede contener múltiples del mismo carácter). Actualizaré el formato de salida para reflejar mejor esto, pero el voto negativo parece ridículo.
Jo King
Downvoter, ¿podría explicar, se trata de E / S o algo más? Sobre el formato de la bolsa, no sé Perl, ¿es esto común para E / S en los campos de golf de Perl? Al mirar los documentos (en caché porque el sitio está inactivo), me parecen más como dictos con recuentos, similares a los de Python, collections.Counterque no tenía la intención de permitir como salida. ¿Se puede iterar fácilmente sobre bolsas con multiplicidad, emitir en una lista / matriz, mostrar con multiplicidad, etc.?
xnor
3
Downvote fue un error, estaba destinado a estar arriba.
Jonathan Allan
7

Haskell , 44 bytes

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

Pruébalo en línea!

La salida es una cadena como ONE,TW,HRE,SVEENcon comas entre días.

Lynn
fuente
1
Qué buen uso del formato de salida para evitar tener que doblar el \`. And an unexpected caso base de foldl1` también.
XNOR
7

JavaScript (Node.js) , 59 bytes

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

Pruébalo en línea!

Solución bastante sencilla. Para cada palabra h, elimine las letras que ya tenemos.

Aquí hay una versión explicada de ese 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']))

tsh
fuente
Puede ahorrar 1 byte tomando prestado el único truco que vale la pena de mi solución, que de otra manera sería demasiado complicada.
Arnauld
5

J , 29 bytes

-29 bytes gracias a FrownyFrog!

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

Pruébalo en línea!

Publicación original

J , 58 bytes

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

Pruébalo en línea!

Gracias a ngn por ayudarme a mejorar las "restar letras respetando la parte de repetición".

No es un gran ajuste para J, sino un ejercicio esclarecedor.

Comencemos construyendo un verbo auxiliar wo("sin") que elimine todos los capítulos de una cadena de otra, respetando las repeticiones.

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

Aquí hay una idea divertida: hacemos que cada instancia repetida de un personaje sea única, repitiéndola la cantidad requerida de veces. Por lo tanto, si nuestra cadena original ABBAse convierte en:

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

Un tercero Ase convertiría AAAy así sucesivamente. Esto se logra mediante la frase ((e. <@# [) {:)\, que toma cada prefijo \, mira el elemento final {:del mismo y construye una máscara de todos los elementos en ese prefijo que coinciden con e.ese elemento final, y luego filtra y encajona solo esos elementos <@#.

Con nuestras entradas "únicas", ahora podemos usar de manera segura el conjunto normal menos -. respetando la repetición.

Luego abrimos cada resultado y tomamos solo el primer elemento para "deshacer" nuestras repeticiones: {.@>

Al conectar este verbo auxiliar, nuestra solución general (que simplemente lo alinea) se convierte en:

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

Esencialmente, todo lo que hacemos aquí es configurar nuestro problema como una reducción única. Comenzamos invirtiendo la entrada |.y añadiéndole ,~un as a:, o un cuadro vacío, que será el valor inicial de nuestro resultado final, así:

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

Pegamos el siguiente verbo entre cada elemento para efectuar la reducción:

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

Esto dice: tome la entrada correcta ](es decir, nuestro resultado) y agregue , la entrada izquierda (esto es ONEen la primera iteración, TWOen la segunda, etc.) sin woel rastro de ;la entrada derecha (es decir, sin ninguna letra anterior hasta ahora usado), pero antes de agregarlo, ordénelo /:~y recuérdelo nuevamente <@.

Al final de todo esto, tendremos el resultado que queremos, una lista de cuadros, pero todos dentro de un cuadro adicional grande, y aún con el cuadro vacío en la parte delantera. De este modo abrimos para quitar la caja exterior y matar al primer elemento: }.@>.

Jonás
fuente
[:}.@>|.(],a.<@#~0>.-&(1#.a.=/;))&.>/@,<@a:
FrownyFrog
Un simple (],a.<@#~0>.-&(1#.a.=/;))/@|.también funciona a menos que me falte un caso de borde.
FrownyFrog
Por lo que puedo decir, la clasificación no está en ninguna parte de los requisitos.
FrownyFrog
2
Actualizado y ahora que he tenido tiempo de absorberlo, solo quería decir de nuevo: ¡Eso es malditamente lindo J!
Jonás
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))

Pruébalo en línea!

Comentado

sisiXdoXsi . Solo se devuelven las cartas compradas.

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()
Arnauld
fuente
4

C ++ (gcc) , 177 170 bytes

-5 bytes gracias a la sugerencia de @ anatolyg, -2 bytes a pequeñas cosas que noté.

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

Explicación

#import<random>agrega ambos <string>y<vector> para la mitad de los bytes.

Primero crea un vector de 91 elementos de 0s (solo los índices 65-90 se usan para almacenar las ocurrencias de letras), y otro vector del mismo tipo pero no establecido en un valor. Itera a través de cada elemento de la entrada (los días): obtiene las letras de propiedad actual, obtiene las letras que se necesitan para el día, anula la entrada en el índice con la cantidad necesaria y actualiza las letras de propiedad. Devuelve la entrada anulada.

Pruébalo en línea!

Neil A.
fuente
Puede hacer #define v std::vector<std::stringy eliminar using namespace stdpara reducir el recuento de bytes en 6 bytes.
anatolyg
2

C # (compilador interactivo de 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;}

Pruébalo en línea!

Función anónima que se genera modificando una 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;
}
dana
fuente
2

R, 119 112 106 103 bytes

-7 bytes aliasing los dos nombres de funciones más largos y ahora tomando la entrada del usuario de scan()
-6 bytes para llamar solo strsplit()una vez al principio
-3 bytes para deshacerse del aliasing nuevamente y asignar dos variables en una llamada

(También edité el recuento de bytes que era erróneamente bajo 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

¡Esta es mi primera presentación de PPCG de cualquier tipo! Por lo tanto, no tengo idea de lo que estoy haciendo tanto en términos de golf como en términos de publicación de etiqueta. El resultado es una lista de vectores que pueden cumplir o no los términos del desafío. :-PAGS

En cuanto al código en sí, toma la entrada del usuario a través de scan()y compara las letras de cada nuevo día con las letras de propiedad acumulativa, como en otras soluciones. Si hay alternativas más cortas para unlisty strsplitpara convertir cadenas en vectores de caracteres individuales, sería genial saberlo. También usé la vsetdifffunción en el vecsetspaquete de Carl Withoft para obtener la diferencia establecida de las letras necesarias para el día siguiente y las letras actuales.

qdread
fuente
1
No, está perfectamente bien. Soy un poco reacio a usar paquetes externos, pero soy solo yo ... prefiero abordar los desafíos en el código base R;)
digEmAll
1
103 en la base R
digEmAll
2

Python 2 , 102100 bytes

from collections import*
c=Counter
l=c()
for x in map(c,input()):y=x-l;l+=y;print list(y.elements())

Pruébalo en línea!

-2 bytes, gracias a Encarnación de la ignorancia

TFeld
fuente
100 bytes
Encarnación de la ignorancia
@EmbodimentofIgnorance Gracias :)
TFeld
2

PowerShell , 71 bytes

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

Pruébalo en línea!

Toma palabras de entrada $argse itera sobre ellas. En cada iteración establecemos la palabra actual $w, luego $precorremos nuestro montón de letras ya compradas. En cada bucle interno, realizamos una expresión regular -replaceen nuestro $word actual , de modo que estamos reemplazando solo la primera instancia de la letra de nuestro $pool. Una vez que hemos revisado todas las letras en el grupo, mostramos lo que queda $w(es decir, lo que necesitamos comprar) y luego pegamos esas letras en nuestro grupo $p+=$wpara la siguiente palabra.

AdmBorkBork
fuente
2

Japt , 15 14 bytes

£Q®X=rZPPÃQ±XX

Intentalo

£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
Lanudo
fuente
1
@Downvoter, ten la decencia de dejar un comentario.
Shaggy
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

Toma entrada en forma de un rango de Excel.

william porter
fuente
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);}

Pruébalo en línea!

Como un pequeño bono, toma el stock ral principio como una matriz. Emite la lista de entrada terminada en nulo terminada en nulo acon todas las letras usadas reemplazadas por espacios.

LambdaBeta
fuente
106 bytes
techocat
1

05AB1E , 11 bytes

-6 gracias a Kevin Cruijssen

ćsvDysSõ.;»

Pruébalo en línea!

Urna de pulpo mágico
fuente
1
Sus 15 bytes funcionan, pero reemplazaría el final Jcon ». Además, puede guardar 4 bytes reemplazando vyð.;}ðKcon Sõ.; 11 bytes .
Kevin Cruijssen
Ahhhh ... necesitaba a S para hacerlo vectorizar.
Urna de pulpo mágico
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

Pruébalo en línea!

Las letras no están ordenadas en orden alfabético, no está prohibido por las reglas.

Roman Podymov
fuente
1

Scala, 68 bytes

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

Pruébalo en línea!

/: es una abreviatura para el operador foldLeft, a es una agregación, finalmente devuelve el resultado que queremos, n es el siguiente elemento

Sin golf

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

Carbón , 18 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

 θ                  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
Neil
fuente
0

PHP, compatible con UTF-8 (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;}
rexkogitans
fuente
0

C # (compilador interactivo de Visual C #) , 112 bytes

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

Pruébalo en línea!

Encarnación de la ignorancia
fuente
Hmm ... ¿Esto arroja una excepción?
dana
@dana Estoy bastante seguro de que las funciones que no devuelven nada pueden salir con excepciones
Encarnación de la ignorancia
Interesante ... supongo que no es la regla más extraña.
dana