Litery znaku markizy

41

Każdego dnia umieszczasz nowe słowo na znaku namiotu z ruchomymi literami , kupując tylko te litery, które musisz napisać. W miarę możliwości ponownie korzystasz z zakupionych liter do wcześniejszych słów. Biorąc pod uwagę słowa, które chcesz pisać każdego dnia w kolejności, wypisz litery, które kupujesz każdego dnia.

Przykład

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

Dzień 1: Aby rozpocząć bez liter, więc pisać ONE, można kupić wszystkie swoje litery E, N, O.
Dzień 2: Następnego dnia chcesz odłożyć TWO (zdjąć ONE). Masz już Ood ONE, więc kupujesz dodatkowy TW.
Dzień 3: W tym momencie masz ENOWT. Do pisania THREEpotrzebujesz EHR. Pamiętaj, że musisz kupić sekundę Eoprócz tej, którą posiadasz.
Dzień 4: Aby napisać SEVENTEEN, potrzebujesz 4 E, z których masz już dwa (nie trzy!), Więc kupujesz dwa kolejne. Mieć również Ti jedną z N„s, więc kupić pozostałe litery: EENSV.

W tym przykładzie wyprowadziliśmy litery posortowane alfabetycznie, ale możesz je wypisać w dowolnej kolejności.

Dane wejściowe: niepusta lista niepustych ciągów liter A-Z. Jeśli wolisz, możesz użyć małych liter. Listy znaków są odpowiednie dla napisów.

Wyjście: wydrukuj lub wydrukuj dodatkowe litery, które musisz kupić każdego dnia. Listy z jednego dnia mogą być wyprowadzane w dowolnej kolejności, ale dni muszą nadejść we właściwej kolejności.

Litery z każdego dnia powinny być oddzielone od innych dni, abyś wiedział, gdzie kończy się dzień. Separator końcowy i / lub wiodący jest w porządku, zarówno w ciągu dnia, jak i między dniami. Pamiętaj, że w dniu może nie być kupionych żadnych liter, co powinno znaleźć odzwierciedlenie w wynikach (spacja lub pusta linia jest w porządku, nawet ostatniego dnia).

Przypadki testowe

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

Oto wszystkie dane wejściowe i wyjściowe jako osobne listy:

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

A jako ciągi rozdzielone spacjami (końcowe spacje w wyjściach mają znaczenie):

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  

Liderów

xnor
źródło
5
W wieku skryptów użytkowników pojawił się dziki skrypt liderów: o
Quintec
Czy możemy wyprowadzać dane jako tablicę znaków, które należy kupić, a nie ciąg wszystkich znaków? np .:[['E', 'N', 'O'], ...]
Downgoat
Czy dane wyjściowe są SHORTLONGOOOOOważne dla ostatniego wyniku? AKA nie używa ograniczników?
Magic Octopus Urn
@Downgoat Tak, listy są w postaci znaków, których wyjście jest w porządku.
xnor
@MagicOctopusUrn Nie, potrzebujesz ograniczników, w przeciwnym razie nie możesz powiedzieć, jakie litery są na dany dzień.
xnor

Odpowiedzi:

10

Haskell, 54 49 bajtów

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

Wypróbuj online!

Budujemy listę wyników, obliczając parami różnicę listy ( \\) listy danych wejściowych i skumulowane dołączenie listy wyników (zaczynając od "").

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

Zarówno w zakresie, jak Data.Listi Data.Functionzakresie (np. Za pomocą środowiska lambdabot), można to skrócić do 30 bajtów:

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

Edycja: -5 bajtów dzięki @Sriotchilism O'Zaic.

nimi
źródło
Dlaczego nie to
Kreator pszenicy
10

Python 2 , 72 68 bajtów

-4 bajty dzięki Jonathanowi Allanowi.

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

Wypróbuj online!

Skomentował

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
źródło
3
for r in input():oszczędza 4 bajty.
Jonathan Allan
7

Perl 6 , 44 bajtów

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

Wypróbuj online!

Dane wyjściowe jako lista list znaków.

Wyjaśnienie

{                                      } # 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
źródło
2
Powód byłby mile widziany
Jo King
Nie downvoter, ale powiem, że ten format wyjściowy jest zbyt daleko idący. Coś takiego Bag(E(2), N, S, V)musiałoby faktycznie pokazywać, że dwa E są OK.
xnor
3
Co naprawdę? To tylko domyślne formatowanie wydruku. Zwracany wynik to nieuporządkowana lista zawierająca te znaki (i może zawierać wielokrotność tego samego znaku). Zaktualizuję formatowanie wyjściowe, aby lepiej to odzwierciedlić, ale głosowanie wydaje się śmieszne.
Jo King
Downvoter, czy mógłbyś wyjaśnić, czy chodzi o I / O, czy coś innego? Jeśli chodzi o format torby, nie znam Perla, czy jest to powszechne we / wy w golfach Perl? Patrząc na dokumenty (zapisane w pamięci podręcznej, ponieważ witryna nie działa), wydaje mi się, że są bardziej jak dykta z licznikami, podobnie jak w Pythonie, collections.Counterktórych nie zamierzałem zezwalać jako wynik. Czy można z łatwością iterować po eltach torby z wielorakością, rzutować na listę / tablicę, wyświetlać z krotnością itp.?
xnor
3
Downvote było błędem, miało być na górze.
Jonathan Allan
7

Haskell , 44 bajty

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

Wypróbuj online!

Dane wyjściowe to ciąg znaków podobny ONE,TW,HRE,SVEENdo przecinków między dniami.

Lynn
źródło
1
Cóż za miłe użycie formatu wyjściowego, aby uniknąć konieczności składania \`. And an unexpected podstawowej skrzynki foldl1.
xnor
7

JavaScript (Node.js) , 59 bajtów

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

Wypróbuj online!

Całkiem proste rozwiązanie. Dla każdego słowa husuń litery, które już mamy.

Oto wyjaśniona wersja tego kodu:

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
źródło
Możesz zaoszczędzić 1 bajt , pożyczając jedyną sensowną sztuczkę z mojego skądinąd skomplikowanego rozwiązania.
Arnauld
5

J , 29 bajtów

-29 bajtów dzięki FrownyFrog!

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

Wypróbuj online!

Oryginalny post

J , 58 bajtów

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

Wypróbuj online!

Dzięki ngn za pomoc w ulepszaniu „odejmowania liter przy jednoczesnym przestrzeganiu części powtarzania”.

Nie jest to idealne dopasowanie do J, ale rozświetlające ćwiczenie.

Zacznijmy od skonstruowania czasownika pomocniczego wo(„bez”), który usuwa wszystkie znaki w jednym ciągu z drugiego, przy jednoczesnym przestrzeganiu powtórzeń.

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

Jest tutaj zabawny pomysł: sprawiamy, że każde powtarzające się wystąpienie postaci jest niepowtarzalne, powtarzając ją wymaganą liczbę razy. Zatem jeśli naszym oryginalnym ciągiem jest ABBA:

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

Trzeci Astałby się AAAi tak dalej. Dokonuje tego fraza ((e. <@# [) {:)\, która bierze każdy prefiks \, patrzy na jego ostatni element {:i konstruuje maskę wszystkich elementów w tym prefiksie, które pasują do e.tego ostatniego elementu, a następnie filtruje i zaznacza tylko te elementy <@#.

Dzięki naszym wejściom zarówno „unikatowymi”, możemy teraz bezpiecznie używać normalnego zestawu minus -. przy jednoczesnym zachowaniu powtarzalności.

Następnie otwieramy każdy wynik i bierzemy tylko pierwszy element, aby „cofnąć” nasze powtórzenia: {.@>

Po podłączeniu tego czasownika pomocniczego nasze ogólne rozwiązanie (które po prostu podkreśla):

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

Zasadniczo wszystko, co tutaj robimy, to ustawić nasz problem jako pojedynczą redukcję. Zaczynamy odwracać dane wejściowe |.i dodawać do nich ,~asa a:lub puste pole, które będzie początkową wartością naszego końcowego wyniku, tak jak:

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

Trzymamy następujący czasownik między każdym elementem, aby uzyskać redukcję:

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

Ten mówi: podjąć właściwą wejście ](czyli nasz wynik) i dołączyć do niego , lewą wejście (to jest ONEna pierwszej iteracji, TWOna 2, etc) bez wotej raze z ;prawego wejścia (czyli bez żadnych wcześniejszych listach do tej pory używane), ale przed dołączeniem posortuj go /:~i zaznacz ponownie <@.

Na końcu tego wszystkiego uzyskamy pożądany wynik, listę pudeł, ale wszystko w jednym dużym dodatkowym pudełku, nadal z pustym pudełkiem z przodu. W ten sposób możemy otworzyć okno, aby usunąć zewnętrzną i zabić pierwszego elementu: }.@>.

Jonasz
źródło
[:}.@>|.(],a.<@#~0>.-&(1#.a.=/;))&.>/@,<@a:
FrownyFrog
Prosty (],a.<@#~0>.-&(1#.a.=/;))/@|.działa również, chyba że brakuje mi skrzynki krawędzi.
FrownyFrog
O ile wiem, sortowanie nie jest wymagane.
FrownyFrog
2
Zaktualizowałem i teraz, kiedy miałem czas na jego przyswojenie, chciałem tylko powiedzieć: To cholernie fajne J!
Jonasz
4

JavaScript (ES6),  66  65 bajtów

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

Wypróbuj online!

Skomentował

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()
Arnauld
źródło
4

C ++ (gcc) , 177 170 bajtów

-5 bajtów dzięki końcówce @ anatolyg, -2 bajty na małe rzeczy, które zauważyłem.

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

Wyjaśnienie

#import<random>dodaje oba <string>i <vector>dla połowy bajtów.

Najpierw tworzy 91-elementowy wektor 0 (tylko indeksy 65-90 są używane do przechowywania wystąpień liter), a inny wektor tego samego typu, ale nie ustawiony na wartość. Iteruje przez każdy element danych wejściowych (dni): pobiera aktualnie posiadane litery, pobiera litery, które są potrzebne na dany dzień, zastępuje dane wejściowe w indeksie wymaganą kwotą i aktualizuje posiadane litery. Zwraca zastąpione wejście.

Wypróbuj online!

Neil A.
źródło
Możesz zrobić #define v std::vector<std::stringi usunąć, using namespace stdaby zmniejszyć liczbę bajtów o 6 bajtów.
anatolyg
2

C # (interaktywny kompilator Visual C #) , 123 bajty

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

Wypróbuj online!

Anonimowa funkcja wysyłająca dane poprzez modyfikację tablicy wejściowej.

// 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
źródło
2

R, 119 112 106 103 bajtów

-7 bajtów od aliasingu dwóch dłuższych nazw funkcji, a teraz pobieranie danych wejściowych od scan()
-6 bajtów, aby wywoływać tylko strsplit()raz na początku
-3 bajtów, aby pozbyć się aliasingu ponownie i przypisać dwie zmienne w jednym wywołaniu

(Edytowano również liczbę bajtów, która wcześniej była błędnie niska)

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

To moje pierwsze zgłoszenie PPCG dowolnego rodzaju! Więc nie mam pojęcia, co robię zarówno pod względem golfa, jak i etykiety. Dane wyjściowe to lista wektorów, które mogą, ale nie muszą spełniać warunki wyzwania. :-P

Jeśli chodzi o sam kod, pobiera dane wejściowe od użytkownika scan()i porównuje litery każdego dnia z literami posiadanymi łącznie, jak w innych rozwiązaniach. Jeśli istnieją krótsze alternatywy unlisti strsplitkonwersje ciągów znaków na wektory poszczególnych znaków, byłoby fajnie wiedzieć. Użyłem również vsetdifffunkcji w pakiecie Carla Withofta, vecsetsaby uzyskać różnicę między literami potrzebnymi na następny dzień a posiadanymi literami.

qdread
źródło
1
nie, jest całkowicie w porządku. Sam niechętnie używam zewnętrznych pakietów, ale to tylko ja ... Wolę podchodzić do wyzwań w podstawowym kodzie R;)
digEmAll
1
103 w bazie R
digEmAll
2

Python 2 , 102 100 bajtów

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

Wypróbuj online!

-2 bajty, dzięki Embodiment of Ignorance

TFeld
źródło
100 bajtów
wcielenie nieznajomości
@EmbodimentofIgnorance Thanks :)
TFeld
2

Japt , 15 14 bajtów

£Q®X=rZPPÃQ±XX

Spróbuj

£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
Kudłaty
źródło
1
@Downvoter, proszę przyzwoitość dodać komentarz.
Kudłaty
1

Czerwony , 75 bajtów

func[b][a: copy""foreach w b[foreach c a[replace w c""]print w append a w]]

Wypróbuj online!

Galen Iwanow
źródło
1

PowerShell , 71 bajtów

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

Wypróbuj online!

Pobiera słowa wejściowe $argsi iteruje je. Każdej iteracji ustawiamy bieżące słowo $w, a następnie zapętlamy nasz $pzbiór już zakupionych liter. W każdej wewnętrznej pętli wykonujemy wyrażenie regularne -replacena naszym bieżącym $wzleceniu, aby zastąpić tylko pierwszą instancję litery z naszego $pool. Po przejrzeniu wszystkich liter w puli, wypisujemy to, co pozostało $w(tj. To, co musimy kupić), a następnie przypinamy te litery do naszej puli, $p+=$waby uzyskać następne słowo.

AdmBorkBork
źródło
1

Excel VBA, 127 bajtów

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

Pobiera dane wejściowe w postaci zakresu programu Excel.

William Porter
źródło
1

C (gcc) , 118 bajtów

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

Wypróbuj online!

Jako mały bonus przyjmuje rna początek zapasy jako zestaw. Zwraca wejściową listę zakończonych znakiem zerowym zakończonych znakiem zerowym, aa wszystkie używane litery są zastąpione spacjami.

LambdaBeta
źródło
106 bajtów
pułap pułapu
1

05AB1E , 11 bajtów

-6 dzięki Kevin Cruijssen

ćsvDysSõ.;»

Wypróbuj online!

Urna Magicznej Ośmiornicy
źródło
1
Twoje prace 15-byter, ale zastąpi końcowego znaku Jz ». Możesz także zapisać 4 bajty, zastępując vyð.;}ðKje Sõ.; 11 bajtami .
Kevin Cruijssen
Ahhhh ... Potrzebowałem S, żeby wektoryzować.
Magic Octopus Urn
1

Swift 4.2 / Xcode 10.2 , 244 242 239 238 bajtów

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

Wypróbuj online!

Litery nie są ułożone w kolejności alfabetycznej, nie jest to zabronione przez reguły.

Roman Podymov
źródło
1

Scala, 68 bajtów

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

Wypróbuj online!

/: jest skrótem od operatora foldLeft, a jest agregacją, ostatecznie zwraca pożądany wynik, n jest kolejnym elementem

Nie grał w golfa

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
źródło
0

Węgiel drzewny , 18 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

 θ                  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
źródło
0

Obsługa PHP, UTF-8 (253 bajtów)

<?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
źródło
0

C # (interaktywny kompilator Visual C #) , 112 bajtów

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

Wypróbuj online!

Wcielenie ignorancji
źródło
Hmm ... Zgłasza to wyjątek?
dana
@dana Jestem pewien, że funkcje, które niczego nie zwracają, mogą wyjść z wyjątkami
Embodiment of Ignorance
Ciekawe ... Przypuszczam, że to nie jest najdziwniejsza zasada.
dana