Маркировочные буквы


41

Каждый день вы помещаете новое слово на маркировочный знак с подвижными буквами , покупая только те буквы, которые вам нужны, чтобы написать его. Вы повторно используете буквы, которые вы купили для более ранних слов, когда это возможно. Учитывая слова, которые вы хотите писать каждый день по порядку, выводите буквы, которые вы покупаете каждый день.

пример

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

День 1: Вы начинаете без каких - либо букв, так писать ONE, вы покупаете все свои письма E, N, O.
День 2: На следующий день вы хотите смириться TWO (сняв ONE). У вас уже есть Oот ONE, поэтому вы покупаете дополнительный TW.
День 3: На данный момент, у вас есть ENOWT. Чтобы написать THREE, вам нужно EHR. Обратите внимание, что вам нужно купить секунду Eв дополнение к той, что у вас есть.
День 4: Чтобы написать SEVENTEEN, вам нужно всего 4 E, из которых у вас уже есть два (а не три!), Поэтому вы покупаете еще два. Кроме того, есть 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  

Leaderboards


5
Дикий сценарий таблицы лидеров появился в возрасте пользователей: o
Quintec

Можем ли мы вывести в виде массива символов, которые нужно купить, а не строку из всех символов? Например:[['E', 'N', 'O'], ...]
Downgoat

Является ли вывод SHORTLONGOOOOOдействительным для последнего вывода? АКА, не используя разделители?
Волшебная Урна Осьминога

@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.Listи Data.Functionв области видимости (например, с помощью среды lambdabot) это можно сократить до 30 байт:

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

Изменить: -5 байт благодаря @Sriotchilism O'Zaic.



10

Python 2 , 72 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
Причина понижения будет оценена
Джо Кинг

Не downvoter, но я должен сказать, что этот формат вывода отклоняется слишком далеко. Что-то вроде того, Bag(E(2), N, S, V)что на самом деле нужно показать две буквы Э, чтобы быть в порядке.
xnor

3
Что на самом деле? Это просто форматирование печати по умолчанию. Возвращаемый результат - неупорядоченный список, содержащий эти символы (и может содержать несколько одинаковых символов). Я обновлю форматирование вывода, чтобы лучше отразить это, но понижение кажется смешным.
Джо Кинг

Downvoter, не могли бы вы объяснить, это о I / O или что-то еще? Что касается формата сумки, я не знаю Perl, это часто встречается в I / O в Perl Golf? Глядя на документы (кэшированные из-за того, что сайт не работает), мне кажется, что они больше похожи на документы с подсчетами, похожие на документы Python, collections.Counterкоторые я не собирался допускать в качестве вывода. Можно ли легко перебирать сумку elts с множественностью, приводить к списку / массиву, отображать с множественностью и т. Д.?
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 байт

-29 байт благодаря FrownyFrog!

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

Попробуйте онлайн!

Оригинальный пост

J , 58 байт

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

Попробуйте онлайн!

Спасибо ngn за помощь в улучшении «вычитания букв при соблюдении повторяющейся части».

Не очень подходит для J, но осветительное упражнение.

Давайте начнем с создания вспомогательного глагола wo(«без»), который удаляет все разделы в одной строке из другой, соблюдая при этом повторения.

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

Здесь есть забавная идея: мы делаем каждый повторяющийся экземпляр персонажа уникальным, повторяя его необходимое количество раз. Таким образом, если наша оригинальная строка ABBAэто становится:

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

Третье Aстанет AAAи так далее. Это достигается с помощью фразы ((e. <@# [) {:)\, которая берет каждый префикс \, просматривает его последний элемент {:и создает маску всех элементов в этом префиксе, которые соответствуют e.этому конечному элементу, а затем фильтрует и блокирует только эти элементы <@#.

С нашими входами как «уникально-ified» мы теперь можем безопасно использовать нормальный набор минус, -. сохраняя при этом повторение.

Затем мы открываем каждый результат и выбираем только первый элемент для «отмены» наших повторений: {.@>

Включив этот вспомогательный глагол, наше общее решение (которое просто указывает на него) становится:

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

По сути, все, что мы здесь делаем, это настраиваем нашу проблему как единое сокращение. Мы начинаем реверсировать ввод |.и добавляем к нему ,~туз a:или пустое поле, которое будет начальным значением нашего конечного результата, например так:

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

Мы вставляем следующий глагол между каждым элементом, чтобы произвести сокращение:

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

Это говорит: взять правильный вход ](то есть, наш результат) и добавить к нему , левый вход (это ONEна первой итерации, TWOна 2 - й и т.д.) без 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))

Попробуйте онлайн!

комментарии

ббИкссИксб . Только купленные письма возвращаются.

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 байт

-5 байт благодаря подсказке @ anatolyg, -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 байтов.
анатолиг

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

Р, 119 112 106 103 байта

-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 любого вида! Поэтому я понятия не имею, что я делаю, как с точки зрения игры в гольф, так и с точки зрения публикации этикета. Вывод представляет собой список векторов, которые могут соответствовать или не соответствовать условиям задачи. :-П

Что касается самого кода, он принимает пользовательский ввод через scan()и сравнивает буквы каждого нового дня с совокупно принадлежащими буквами, как и в других решениях. Если есть более короткие альтернативы unlistи strsplitдля преобразования строк в векторы отдельных символов, это было бы здорово узнать. Я также использовал vsetdiffфункцию в пакете Carl Withoft, vecsetsчтобы получить заданную разницу букв, необходимых на следующий день, и текущих принадлежащих букв.


1
нет, все отлично Я немного неохотно пользуюсь внешними пакетами, но это только я ... Я предпочитаю подходить к вызовам в базовом коде R;)
digEmAll






2

PowerShell , 71 байт

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

Попробуйте онлайн!

Принимает входные слова $argsи перебирает их. Каждую итерацию мы устанавливаем текущее слово $w, а затем перебираем наши $pуши уже купленных букв. В каждом внутреннем цикле мы выполняем регулярное выражение -replaceдля нашего текущего $word, поэтому мы заменяем только первый экземпляр письма из нашего $pool. После того, как мы проверили все буквы в пуле, мы выводим то, что осталось $w(то есть, что нам нужно купить), а затем прикрепляем эти буквы в наш пул $p+=$wдля следующего слова.


2

Japt , 15 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

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

05AB1E , 11 байт

-6 спасибо Кевину Круйссену

ćsvDysSõ.;»

Попробуйте онлайн!


1
Ваш 15-байтовый работает, но я бы заменил трейлинг Jна ». Также вы можете сохранить 4 байта, заменив их vyð.;}ðKна Sõ.; 11 байтов .
Кевин Круйссен

Аааа ... Мне нужен был S, чтобы сделать это векторизацией.
Волшебная Урна Осьминога

1

Swift 4.2 / Xcode 10.2 , 244 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

Скала, 68 байт

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

Попробуйте онлайн!

/: сокращение от оператора foldLeft, a агрегация, в конечном итоге возвращает желаемый результат, n следующий элемент

Un-golfed

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 #) , 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 Я уверен, что функциям, которые ничего не возвращают, разрешено выходить с исключениями
Embodiment of Ignorance

Интересно ... Полагаю, это не самое странное правило.
Дана




Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.