Болгарский пасьянс

9

«Болгарский пасьянс» - это однопользовательская игра, популярная у Мартина Гарднера в его математической колонке « Scientific American» .

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

Например, скажем, у вас есть 8карты, разбитые на стопку 5и стопку 3. Пишем размеры кучи в порядке убывания: 5 3. Вот стенограмма игры:

5 3
4 2 2
3 3 1 1 
4 2 2

Сначала вы удаляете карту из каждой из двух стопок, оставляя стопки 4и 2, и вновь созданную стопку 2раздачи 4 2 2. На следующем шаге они уменьшаются до 3 1 1новой стопки 3. Наконец, последний шаг очищает груды размера 1и производит 4 2 2уже появившиеся, поэтому мы остановимся.

Обратите внимание, что сумма размеров стопки остается неизменной.

Ваша цель - напечатать такую ​​стенограмму игры из заданной стартовой конфигурации. Это код гольф, поэтому побеждает меньше байтов.

вход

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

Вы не получаете общее количество карт Nв качестве входных данных.

Вывод

Распечатайте последовательность размеров кучи, через которую проходит игра «Болгарский пасьянс». Обратите внимание, что печать требуется, а не возврат. У каждого шага должна быть своя линия.

Каждая строка должна иметь последовательность положительных чисел в убывающем порядке без цифр 0. У вас могут быть разделители, а также начальный и конечный токены (например, [3, 3, 1, 1]). Числа могут иметь несколько цифр, поэтому их нужно как-то разделить.

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

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

>> [1]
1
1

>> [2]
2
1 1
2

>> [1, 1, 1, 1, 1, 1, 1]
1 1 1 1 1 1 1
7
6 1
5 2
4 2 1
3 3 1
3 2 2
3 2 1 1
4 2 1

>> [5, 3]
5 3
4 2 2
3 3 1 1
4 2 2

>> [3, 2, 1]
3 2 1
3 2 1

>> [4, 4, 3, 2, 1]
4 4 3 2 1
5 3 3 2 1
5 4 2 2 1
5 4 3 1 1
5 4 3 2
4 4 3 2 1
XNOR
источник

Ответы:

4

Пиф, 40 25

QW!}QY~Y]Q=Q_S+fTmtdQ]lQQ

Это довольно близко к переводу моего ответа на Python 2.

Образец прогона:

Входные данные:

[4,4,3,2,1]

Вывод:

[4, 4, 3, 2, 1]
[5, 3, 3, 2, 1]
[5, 4, 2, 2, 1]
[5, 4, 3, 1, 1]
[5, 4, 3, 2]
[4, 4, 3, 2, 1]

Как это работает:

Q                          Q = eval(input()) # automatic
 W!}QY                     while not Q in Y:
      ~Y]Q                     Y += [Q]
               fTmtdQ                     filter(lambda T: T, map(lambda d: d - 1, Q))
            _S+      ]lQ           sorted(                                             + [len(Q)])[::-1]
          =Q_S+fTmtdQ]lQ       Q = sorted(filter(lambda T: T, map(lambda d: d - 1, Q)) + [len(Q)])[::-1]
                        Q      print(Q)
QW!}QY~Y]Q=Q_S+fTmtdQ]lQQ
Джастин
источник
1. Вы можете заменить v$input()$на Q. 2. Если вы храните список в порядке убывания, вам не нужно Nвообще:W!}QYQ~Y]Q=Q_S+fTmtdQ]lQ;Q
Деннис
@ Деннис Спасибо, я не мог понять, как это сделать; Я знал, что есть способ сделать это.
Джастин
1
Вот что я сделал, совершенно независимо друг от друга: QW!}QY~Y]Q=Q_S+]lQfTmtdQQ. Точно так же, символ за персонажем, вплоть до коммутативности.
Исаак
3

CJam, 26 байт

q{~_:(_,+0-$W%]___&=}g{p}/

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

Пример запуска

$ cjam <(echo 'q{~_:(_,+0-$W%]___&=}g{p}/') <<< '[5 3]'
[5 3]
[4 2 2]
[3 3 1 1]
[4 2 2]
Деннис
источник
Это какой-то CJam!
Оптимизатор
Давай !, я знаю, ты можешь сделать его короче, чем Пиф!
Оптимизатор
Если бы :pработал, я мог бы ...
Деннис
4
Перестань ныть! :p
Оптимизатор
3

Руби, 98

f=->c{g={c=>1}
p *loop{c=(c.map(&:pred)<<c.size).sort.reverse-[0]
g[c]?(break g.keys<<c): g[c]=1}}

объяснение

  • Входные данные принимаются в качестве аргументов лямбды. Это ожидает Array.
  • Предыдущие игровые состояния хранятся в Hash g.
  • Чтобы создать новое игровое состояние, используйте Array#mapдля уменьшения каждого элемента на 1, добавьте длину элемента в Arrayкачестве элемента, отсортируйте его по убыванию и удалите элемент 0.
  • Чтобы проверить, просматривалось ли ранее gигровое состояние, достаточно проверить наличие ключа для нового игрового состояния.
britishtea
источник
+1 Действительно аккуратный рубиновый гольф здесь! Тем не менее, хотя эта sort_byвещь, безусловно, умна, sort.reverseна самом деле она на один символ короче ^^
daniero
Ой, это очень плохо. Спасибо.
британцы
2

CJam, 35 34 33 байта

(Черт, это отключение электричества, которое я не первым опубликовал в CJam)

l~{_p:(_,+{},$W%_`_S\#0<\S+:S;}g`

Входные данные:

[1 1 1 1 1 1 1]

Вывод:

[1 1 1 1 1 1 1]
[7]
[6 1]
[5 2]
[4 2 1]
[3 3 1]
[3 2 2]
[3 2 1 1]
[4 2 1]

Попробуйте онлайн здесь

оптимизатор
источник
1

Питон 2 - 103

p=input()
m=[]
print p
while p not in m:m+=[p];p=sorted([x-1 for x in p if x>1]+[len(p)])[::-1];print p

Аналогичен ответу Quincunx, но заменяет добавление дополнением и удаляет последние две строки.

Пример вывода:

[4, 4, 3, 2, 1]
[5, 3, 3, 2, 1]
[5, 4, 2, 2, 1]
[5, 4, 3, 1, 1]
[5, 4, 3, 2]
[4, 4, 3, 2, 1]
Натан Меррилл
источник
Хм, похоже? Это идентично; Вы просто сделали шаги в гольф, которые были совершенно очевидны. Когда я вернулся к своему, я поиграл в гольф и обнаружил, что теперь это дубликат моего ответа (или наоборот, как бы вы ни хотели его просмотреть)
Джастин
Я обнаружил твой ответ только после публикации моего. Я в порядке, рассматривая их как дубликаты друг друга.
Натан Меррилл
1

Хаскелл, 99

import Data.List
g l=until(nub>>=(/=))(\l->l++[reverse$sort$length(last l):[x-1|x<-last l,x>1]])[l]
гордый хаскеллер
источник
1

CJam, 40 36 34 байта

]l~{a+_W=_p:(_,+$W%{},1$1$a#0<}gp;

Проверьте это здесь. Введите ввод в виде массива в стиле CJam, например [5 3], в поле STDIN. Формат вывода похож, поэтому квадратные скобки и пробелы в качестве разделителей.

Даже если я продолжу играть в гольф (что, безусловно, возможно), нет никакого способа победить Пита с этим. Может быть, пришло время изучить J. Объяснение будет позже.

Мартин Эндер
источник
Не уверен, что J поможет, я не могу получить APL ниже 38
TwiNight
1

JavaScript (E6) 113

Худшая запись до сих пор :(

F=l=>{
  for(k=[];console.log(l),!k[l];)
    k[l]=l=[...l.map(n=>(p+=n>1,n-1),p=1),l.length].sort((a,b)=>b-a).slice(0,p)
}

Тест в консоли FireFox / FireBug

F([4,4,3,2,1])

Вывод

[4, 4, 3, 2, 1]
[5, 3, 3, 2, 1]
[5, 4, 2, 2, 1]
[5, 4, 3, 1, 1]
[5, 4, 3, 2]
[4, 4, 3, 2, 1]
edc65
источник
1

Python 2, 148 130 101

l=input()
s=[]
print l
while l not in s:s+=l,;l=sorted([i-1for i in l if 1<i]+[len(l)])[::-1];print l

Это просто запоминает все предыдущие итерации и проверяет, есть ли новая в этом списке. Затем он распечатывает это.

Образец прогона:

Входные данные:

[4,4,3,2,1]

Вывод:

[4, 4, 3, 2, 1]
[5, 3, 3, 2, 1]
[5, 4, 2, 2, 1]
[5, 4, 3, 1, 1]
[5, 4, 3, 2]
[4, 4, 3, 2, 1]

Изменить: я перечитал спецификации для гольфа, а также много играл в гольф.

Джастин
источник
Вы можете просто распечатать списки в виде списков.
xnor
@xnor Ооо, спасибо, что пропустил это.
Джастин
Это не сработает с [5,3]
Натан Меррилл
Это дает неправильный вывод для [4,2,2]. Там легко исправить, хотя.
xnor
0

Python 3: 89 символов

g=lambda l,s=[]:print(l)!=l in s or g(sorted([x-1for x in l if~-x]+[len(l)])[::-1],s+[l])

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

Функцию print()(это Python 3) просто нужно как-то вызывать в каждом цикле. Хитрость в том, что lambdaдопускается только одно выражение, поэтому мы не можем этого сделать print(l);.... Кроме того, это выводит None, с которым трудно работать. Я ставлю print(l)одну сторону неравенства; ==не работает по какой-то причине, которую я не понимаю.

Альтернативный подход для размещения его в списке использует одинаковое количество символов.

g=lambda l,s=[]:l in s+[print(l)]or g(sorted([x-1for x in l if~-x]+[len(l)])[::-1],s+[l])

Использование print(*l)будет форматировать выходные данные как, 4 2 2а не [4,2,2].

XNOR
источник