Играя Пикомино

10

В игре Pickomino в центре стола лежат несколько фишек , каждая с разным положительным целым числом. Каждый ход игроки бросают кубики определенным образом и получают счет, который является неотрицательным целым числом.

Теперь игрок берет плитку с наибольшим числом, которое все еще меньше или равно его счету, удаляя плитку из середины и добавляя ее в свой стек. Если это невозможно, потому что все числа в середине выше, чем оценка игрока, игрок теряет самый верхний тайл из своего стека (который был добавлен последним), который возвращается в середину. Если у игрока не осталось плиток, ничего не происходит.

Соревнование

Имитация игрока, играющего в игру против себя. Вы получаете список плиток в середине и список оценок, которые получил игрок. Вернуть список тайлов игрока после того, как все ходы были оценены.

Правила вызова

  • Вы можете предположить, что список с плитками упорядочен и не содержит целых чисел дважды.
  • Вы можете взять оба списка ввода в любом порядке, который вы хотите
  • Выходные данные должны сохранять порядок листов в стеке, но вы можете решить, будет ли список отсортирован сверху вниз или снизу вверх.

Основные правила

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте найти как можно более короткий ответ для «любого» языка программирования.
  • Стандартные правила применяются к вашему ответу с правилами ввода / вывода по умолчанию , поэтому вы можете использовать STDIN / STDOUT, функции / метод с правильными параметрами и типом возврата, полные программы.
  • По умолчанию лазейки запрещены.
  • Если возможно, добавьте ссылку с тестом для вашего кода (например, TIO ).
  • Добавление объяснения для вашего ответа рекомендуется.

пример

(взято из 6-го теста)

Tiles: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Scores: [22, 22, 22, 23, 21, 24, 0, 22]

Первый результат - 22, поэтому возьмите самый высокий тайл в середине <= 22, то есть сам 22.

Middle: [21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Stack: [22]
Remaining scores: [22, 22, 23, 21, 24, 0, 22] 

Следующий результат - 22, поэтому возьмите самый высокий тайл в середине <= 22. Поскольку 22 уже взято, игрок должен взять 21.

Middle: [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Stack: [22, 21]
Remaining scores: [22, 23, 21, 24, 0, 22]

Следующая оценка - 22, но все числа <= 22 уже заняты. Поэтому игрок теряет самый верхний тайл в стеке (21), который возвращается в середину.

Middle: [21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Stack: [22]
Remaining scores: [23, 21, 24, 0, 22]

Следующие оценки 23, 21 и 24, поэтому игрок берет эти плитки с середины.

Middle: [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Stack: [22, 23, 21, 24]
Remaining scores: [0, 22]

Игрок обанкротился и набрал ноль. Поэтому тайл с номером 24 (самый верхний в стеке) возвращается в середину.

Middle: [24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Stack: [22, 23, 21]
Remaining scores: [22]

Последний результат - 22, но все плитки <= 22 уже заняты, поэтому игрок теряет самый верхний блок в стеке (21).

Middle: [21, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Final Stack and Output: [22, 23]

Контрольные примеры

(с самой верхней плиткой последней в списке вывода)

Tiles: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Scores: [26, 30, 21]
Output: [26, 30, 21]

Tiles: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Scores: [35, 35, 36, 36]
Output: [35, 34, 36, 33]

Tiles: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Scores: [22, 17, 23, 19, 23]
Output: [23]

Tiles: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Scores: []
Output: []

Tiles: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Scores: [22, 17, 23, 19, 23, 0]
Output: []

Tiles: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36]
Scores: [22, 22, 22, 23, 21, 24, 0, 22]
Output: [22, 23]

Tiles: [1, 5, 9, 13, 17, 21, 26]
Scores: [6, 10, 23, 23, 23, 1, 0, 15]
Output: [5, 9, 21, 17, 13, 1]

Tiles: []
Scores: [4, 6, 1, 6]
Output: []

песочница

Черная Сова Кай
источник
Можем ли мы предположить, что нет плиток со значением ноль в середине?
Воплощение невежества
@EmbodimentofIgnorance Это говорит "положительное целое число", так что да.
Орджан Йохансен
Поскольку плитки уникальны, было бы приемлемо принять их как битовую маску?
Арно
@TRITICIMAGVS Да, если средняя куча пуста, игрок не может взять плитку из середины, поэтому он теряет плитку (если она есть)
Черная сова Кай
@Arnauld Это приемлемо
Черная Сова Кай

Ответы:

3

Haskell , 119 111 104 103 байта

1 байт сохранен благодаря Эрджану Йохансену

(#)=span.(<)
(a%(b:c))d|(g,e:h)<-b#d=(e:a)%c$g++h|g:h<-a,(i,j)<-g#d=h%c$i++g:j|1>0=a%c$d
(a%b)c=a
([]%)

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

Предполагается, что плитки отсортированы в порядке убывания.

Не так уж много здесь происходит. Первый аргумент - куча игроков, второй - их очки, а третий - куча в середине.

Специальный охотник за гарфами
источник
1
Это не может быть правильно, потому что sortэто восходящий. Тем не менее, тестовый пример TIO никогда не попадает в эту ветку. Я настоятельно рекомендую проверять все случаи каждый раз при повторении, как это.
Орджан Йохансен
@ ØrjanJohansen Спасибо! Исправлено сейчас. По крайней мере, мне больше не нужно импортировать!
Специальный охотник за
Сохранить байт с (#)=span.(<).
Орджан Йохансен
@ ØrjanJohansen Изменение сделано. Самое смешное, что я попробовал это раньше и подумал, что он добавил байт.
Специальная Гарф Hunter
3

Japt, 24 байта

Уф! Это не сработало так, как я думал, что будет!

Принимает ввод в обратном порядке.

®=Va§Z)Ì?NpVjZ:VpNo)nÃN¤

Попробуйте или запустите все тестовые случаи на TIO

®=Va§Z)Ì?NpVjZ:VpNo)nÃN¤     :Implicit input of N=[U=scores, V=tiles]
®                            :Map each Z in U
 =                           :  Reassign to Z
  Va                         :    0-based index of last element in V (-1 if not found)
    §Z                       :      Less than or equal to Z
      )                      :  End reassignment
       Ì                     :  Sign of difference with -1 (1 if found, 0 if not)
        ?                    :  If truthy (not zero)
         Np                  :    Push to N
           VjZ               :      Remove and return the element at index Z in V
              :              :  Else
               Vp            :    Push to V
                 No          :      Pop the last element of N
                   )         :    End Push
                    n        :    Sort V
                     Ã       :End map
                      N¤     :Slice the first 2 elements (the original inputs) off N
мохнатый
источник
2

Perl 6 , 89 байт

{my@x;@^a;@^b>>.&{@x=|@x,|(keys(@a@x).grep($_>=*).sort(-*)[0]//(try ~@x.pop&&()))};@x}

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

Я думаю, что есть еще несколько байтов для игры в гольф ...

Джо Кинг
источник
2

C # (интерактивный компилятор Visual C #) , 159 158 154 байта

Называется как f(tiles)(scores)

n=>m=>{var s=new Stack<int>();m.Add(0);n.ForEach(k=>{var a=m.Except(s).Where(x=>x<=k).Max();if(a<1)m.Add(s.Count<1?0:s.Pop());else s.Push(a);});return s;}

Если только System.Voidэто на самом деле тип возврата, а не просто заполнитель для отражения. Я мог бы заменить if(a<1)m.Add(s.Count<1?0:s.Pop());else s.Push(a);с var t=a>1?m.Add(s.Count<1?0:s.Pop()):s.Push(a);, сохраняя два байта.

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

//Function taking in a list and returning
//another function that takes in another list and returns a stack
n=>m=>{
//Initialize the stack
var s=new Stack<int>();
//Add a zero to the tiles, to ensure no exceptions appear due to accessing
//non-existent elements in an empty collection later
//when we try to filter it later and getting the biggest element
m.Add(0);
//Iterate through our scores
n.ForEach(k=>{
//Create a variable called a, which we will use later
var a=
//Get all the elements in the middle that haven't appeared in our stack
m.Except(s).
//And throw away all elements that are bigger than our current score
Where(x=>x<=k).
//And get the biggest element there, and that is now the value of a
//Without the m.Add(0), we would get an exception here
Max();
//Self-explanatory, if a is less than 1 aka if a equals 0
//Checks if all elements in the middle are bigger than our score 
//Except for our self added 0, of course
if(a<1)
//Add 0 to the middle if the stack is empty
//Remember, zeros don't affect the list
m.Add(s.Count<1?0:
//Else pop the stack and add that to the middle
s.Pop());
//If a isn't 0, add a to the stack
else s.Push(a);});
//Afterwards, return the stack
return s;}
Воплощение невежества
источник
2

JavaScript (Node.js) , 80 байт

Та же логика, что и в версии ES6, но принимает плитки как битовую маску BigInt, а оценки - как массив BigInts.

m=>s=>s.map(g=x=>!x||m>>x&1n?m^=1n<<(x?r.push(x)&&x:r.pop()||~x):g(--x),r=[])&&r

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


JavaScript (ES6),  100 98 94  87 байт

Принимает вход как (tiles)(scores). Плитка может быть передана в любом порядке.

t=>s=>s.map(g=x=>m[x]?m[x?r.push(x)&&x:r.pop()]^=1:g(x-1),t.map(x=>m[x]=1,m=[r=[]]))&&r

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

комментарии

t => s =>                 // t[] = tiles; s[] = scores
  s.map(g = x =>          // for each score x in s[]:
    m[x] ?                //   if m[x] is set:
      m[                  //     update the 'middle':
        x ?               //       if x is not equal to 0:
          r.push(x) && x  //         push x in the stack r[] and yield x
        :                 //       else:
          r.pop()         //         pop the last value from the stack
                          //         (may be undefined if the stack is empty)
      ] ^= 1              //     toggle the corresponding flag in m[]
    :                     //   else:
      g(x - 1),           //     try again with x - 1
    t.map(x =>            //   initialization of the 'middle': for each value x in t[]:
      m[x] = 1,           //     set m[x]
      m = [r = []]        //     the stack r[] is stored as the first entry of m[],
                          //     which ensures that g will always stop when x = 0
    )                     //   end of initialization
  ) && r                  // end of main loop; return r[]
Arnauld
источник
1

Древесный уголь , 35 байт

Fη«≔⌈Φ講κιι¿ι«≔Φθ⁻κιθ⊞υι»¿υ⊞θ⊟υ»Iυ

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

Fη«

Цикл по баллам.

≔⌈Φ講κιι

Ищите самую высокую доступную плитку.

¿ι«

Если это существует, то ...

≔Φθ⁻κιθ

... убрать плитку с середины ...

⊞υι

... и добавить его в стек.

»¿υ

Иначе, если стек не пустой ...

⊞θ⊟υ

Удалите последнюю плитку из стека и верните ее в середину.

»Iυ

Выведите полученную стопку от самой старой до самой новой.

Нил
источник
1

05AB1E , 27 22 байта

vÐy>‹ÏDgĀià©K®së\sª])¨

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

v            # Loop `y` over the (implicit) input-list of scores:
 Ð           #  Triplicate the tiles list (takes it as implicit input in the first iteration)
  y>‹        #  Check for each if `y` <= the value in the tiles list
     Ï       #  Only leave the values at the truthy indices
 D           #  Duplicate the remaining tiles
  ¯Êi        #  If this list is not empty:
     à       #   Pop the list, and push its maximum
      ©      #   Store it in the register, without popping
       K     #   Remove it from the tiles list
        ®    #   Push the maximum again
         s   #   Swap the maximum and tiles-list on the stack
    ë        #  Else:
     \       #   Remove the duplicated empty tiles-list from the stack
      sª     #   Add the last tile to the tiles-list
]            # Close the if-else and loop
 )           # Wrap everything on the stack into a list
  ¨          # Remove the last item (the tiles-list)
             # (and output the result implicitly)
Кевин Круйссен
источник
1

Pyth, 32 байта

VE ?JeS+0f!>TNQ=-QeaYJaQ.)|Y]0;Y

Попробуйте онлайн здесь или проверьте все тестовые примеры сразу здесь .

Здесь где-то должно быть место для улучшения - любые предложения будут высоко оценены!

VE ?JeS+0f!>TNQ=-QeaYJaQ.)|Y]0;Y   Implicit: Q=input 1 (middle), E=input 2 (scores), Y=[]
VE                            ;    For each score, as N, in the second input:
         f    Q                      Filter Q, keeping elements T where:
          !>TN                         T is not greater than N 
                                       (less than or equal is the only standard inequality without a token in Pyth, grrr)
       +0                            Prepend 0 to the filtered list
     eS                              Take the largest of the above (_e_nd of _S_orted list)
    J                                Store the above in J
   ?                                 If the above is truthy:
                   aYJ                 Append J to Y
                  e                    Take last element of Y (i.e. J)
               =-Q                     Remove that element from Q and assign the result back to Q
                                     Else:
                          |Y]0         Yield Y, or [0] if Y is empty
                        .)             Pop the last element from the above (mutates Y)
                      aQ               Append the popped value to Q
                               Y   Print Y
Sok
источник
1

Perl 5 -apl -MList:Util=max, 97 байт

$_=$".<>;for$i(@F){(($m=max grep$_<=$i,/\d+/g)&&s/ $m\b//?$s:$s=~s/ \d+$//?$_:$G).=$&}$_=$s;s/ //

TIO

читает результаты и плитки на следующей строке и печатает вывод.

Как

  • -apl: -pциклически перебирать строки и печатать, -aавтоматически разбивать , разбивать -lна части из ввода и добавлять символ новой строки в вывод
  • $_=$".<> : прочитать следующую строку (тайлы) и добавить пробел в стандартную переменную $_
  • for$i(@F){... }петля $iнад @Fполями текущей строки (баллы)
  • (.. ?.. :.. ).=$&добавить предыдущее совпадение к троичному l-значению
  • ($m=max grep$_<=$i,/\d+/g)&&s/ $m\b//?$sв случае, если максимальное значение найдено и удалено из плиток ( $_), l-значение равно Scores ( $s)
  • $s=~s/ \d+$//?$_ в противном случае, если последний номер может быть удален из баллов, это плитки
  • :$G наконец, это мусор, потому что не может произойти
  • $_=$s;s/ // установить счет в стандартную переменную и удалить начальный пробел
Науэль Фуйе
источник