Чередование в OCaml

Я пытаюсь создать функцию, которая чередует пару троек, таких как ((6, 3, 2), ( 4, 5,1)) и создать 6-кортеж из этого чередования. Я провел некоторое исследование, но смог понять, как чередование должно работать, поэтому я попытался что-то на собственном опыте и закончил с кодом, который создает 6-кортеж, но не с правильным чередованием. Это мой код

let interleave ((a, b, c), (a', b', c')) =
let sort2 (a, b) = if a > b then (a, b) else (b, a) in
let sort3 (a, b, c) = 
let (a, b) = sort2 (a, b) in
let (b, c) = sort2 (b, c) in
let (a, b) = sort2 (a, b) in
(a, b, c) in
let touch ((x), (y)) = 
let (x) = sort3 (x) in
let (y) = sort3 (y) in
((x),(y)) in
let ((a, b, c), (a', b', c')) = touch ((a, b, c), (a', b', c')) in
(a, b', a', b, c, c');;

Может кто-нибудь, пожалуйста, объясните мне, как с помощью функций я могу добиться правильной формы чередования. Я не узнал о рекурсиях и списках на тот случай, если вы спросите, почему я пытаюсь сделать это таким образом. Спасибо уже

2 ответа

Решение

В постановке задачи используется слово "max" без определения его. Если вы используете встроенный compare Функция OCaml, как ваше определение, использует лексикографический порядок. Таким образом, вы хотите наибольшее значение (из 6 значений) в первой позиции в 6-кортеже, второе по величине значение в следующем и так далее.

Это должно быть довольно легко, учитывая ваши ранее установленные навыки сортировки кортежей.

Для чего бы это ни стоило, кажется, нет особой ценности в сохранении идентичности двух трёх кортежей. Оказавшись внутри самой внешней функции, вы можете просто работать с 6 значениями как с 6-ю кортежами. Или мне так кажется.

Обновить

Из вашего примера (вероятно, следовало дать его в начале:-), довольно ясно, что вас просят сделать. Вы хотите получить последовательность, в которой элементы исходных кортежей находятся в их первоначальном порядке, но их можно чередовать произвольно. Это часто называют "перемешиванием" (или слиянием). Вы должны найти тасование, которое имеет максимальное значение лексикографически.

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

Это гораздо проще сделать со списками.

Теперь, когда я понимаю, какова ваша конечная цель.,,

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

Один из подходов, который в основном имитирует рекурсивную функцию над списками (но требует много дополнительных функций из-за того, что кортежи имеют разные типы), состоит в том, чтобы иметь два набора вспомогательных функций:

  • функции, которые добавляют значение к существующему кортежу: prepend_to_2через prepend_to_5, Например,

    let prepend_to_3 (a, (b, c, d)) = (a, b, c, d)
    
  • функции, которые чередуют два кортежа каждого возможного размера до 3: interleave_1_1, interleave_1_2, interleave_1_3, interleave_2_2, interleave_2_3, а также interleave_3_3, (Обратите внимание, что нам не нужно, например, interleave_2_1потому что мы можем просто позвонить interleave_1_2 с аргументами в обратном порядке.) Например,

    let interleave_2_2 ((a, b), (a', b')) =
        if a > a'
        then prepend_to_3 (a, interleave_1_2 (b, (a', b')))
        else prepend_to_3 (a', interleave_1_2 (b', (a, b)))
    

    (Вы видите, как это работает?)

затем interleave просто interleave_3_3,

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

Другие вопросы по тегам