Скажем, у меня есть уникальный список длиной 9 значений от 1 до 9 включительно в случайном порядке (например, судоку), и я хочу извлечь подсписок элементов, которые встречаются между значениями 1 и 9 (эксклюзив). IE: between1and9([1,3,5,4,2,9,7,8,6],[3,5,4,2])
должно быть истинным.
В данный момент я пытаюсь использовать flatten/2
, но мне не везет. Вот моя текущая тактика (при условии, что я заставлю List ins 1..9, maplist(all_distinct, List), length(List, 9)
в другом месте поддерживать порядок здесь / разделение проблем):
between1and9(List,Between) :-
flatten([_,[1],Between,[9],_], List);
flatten([_,[9],Between,[1],_], List).
Эта версия не работает, хотя, когда 1 или 9 находятся в первой или последней позиции в List
, или если они смежны в пределах List
. between1and9([_,1,9,_,_,_,_,_,_],[])
верно, но between1and9([_,1,9,_,_,_,_,_,_],_)
неверно (и не удается, когда я пытаюсь использовать его в качестве ограничения для решения более крупной проблемы.)
Кажется, это та же самая проблема, связанная с обоими сбоями, flatten
, похоже, не нравится рассматривать неизвестные как пустые списки, если они где-то не указаны явно.
Я понимаю, почему это могло бы произойти, если бы flatten
мог "придумать" пустые списки в первом аргументе, это означало бы бесконечный набор решений для чего-либо в первом аргументе. Хотя моя полная программа имеет другие ограничения, чтобы предотвратить это, я могу понять, почему flatten
может не захотеть ее разместить.
Я могу учесть крайние случаи (каламбур), сопоставив каждую перестановку с дизъюнкциями (то есть: flatten([_,1,B,9,_],L);flatten([_,9,B,1,_],L);flatten([_,1,B,9]);flatten...
, и учесть Промежуточное звено как пустой список с: \*above permutations on flatten*\; ( Between = [], (\*permutations for either edge and 1/9*\) )
Но это, кажется, делает уже давно продуманное решение (всего 10 перестановок сглаживания) еще хуже (18), поэтому у меня есть два (сильно связанных) вопроса:
Если бы я мог сделать следующее:
between1and9(L,B) :-
( ( X = 1, Y = 9 ); ( X = 9, Y = 1 ) ),
( ( Z1 = _; Z1 = [] ), ( Z2 = _ ; Z2 = [] ) ),
( B = _; B = [] ),
flatten([Z1,X,B,Y,Z2],L).
Мне не пришлось бы вручную печатать каждую перестановку совпадений для flatten
. К сожалению, это и несколько его вариантов в одностороннем порядке провалились. Я пропускаю что-то очевидное здесь? (Я подозреваю приоритет оператора, но я пробовал несколько разных версий.)
Или я делаю это совершенно неправильно? Документация flatten/2
предполагает, что в большинстве случаев это анти-паттерн, есть ли более прологичный способ решения этой проблемы? Учитывая все подводные камни, которые я осознаю, проходя через это, я почти уверен, что есть.
(Извините, я до боли осознаю, что большая часть терминологии, которую я использую для описания вещей в этом, вероятно, очень неправильная, я только немного знаком с предикатной / формальной логикой и гораздо более привык к описанию программирование типа потока управления. Несмотря на то, что я достаточно хорошо понимаю логическое программирование на практике, я все еще изо всех сил пытаюсь найти язык, чтобы говорить об этом, я исправлю этот вопрос с любыми поправками, которые получу.)
Некоторые предыстории: я новичок в прологе и проверяю свое понимание, пытаясь расширить один из множества решателей судоку, чтобы решить странное разнообразие судоку, которое я нашел в некоторых головоломках, которые я распечатал много лет назад, где вам показывают сумма всех чисел, которые появляются между 1 и 9 в каждой строке или столбце в качестве дополнительной подсказки, это своего рода смесь судоку и пикросса. Решатель в его нынешнем виде находится на swish: SumSudoku (swish) . Хотя это может быть беспорядок, когда вы добираетесь до него.
* Следующее задание: есть ли прологическая версия слова «питон?»